Client-side vulnerabilities execute in the context of the user's browser and exploit the trust relationship between the browser and the web application. As modern applications shift more logic to the client side through JavaScript frameworks and single-page applications, the attack surface on the client has grown significantly. This category covers 13 tests ranging from DOM-based cross-site scripting and HTML injection to clickjacking, WebSocket testing, and browser storage security. These vulnerabilities are particularly relevant for modern JavaScript-heavy applications where client-side routing, template rendering, and data processing create new attack vectors that traditional server-side testing misses. For security testers, understanding the browser security model and same-origin policy is essential for finding these client-side vulnerabilities.
OWASP Top 10 Mapping
This testing category relates to the following OWASP Top 10 2021 categories:
Quick Reference
| Test ID | Name | CWEs | Difficulty |
|---|---|---|---|
| WSTG-CLNT-01 | DOM-Based XSS | CWE-79 | Intermediate |
| WSTG-CLNT-02 | JavaScript Execution Testing | CWE-79 | Intermediate |
| WSTG-CLNT-03 | HTML Injection | CWE-79 | Intermediate |
| WSTG-CLNT-04 | Client-side URL Redirect | CWE-601 | Intermediate |
| WSTG-CLNT-05 | CSS Injection | CWE-79 | Intermediate |
| WSTG-CLNT-06 | Resource Manipulation | CWE-829 | Intermediate |
| WSTG-CLNT-07 | CORS Testing | CWE-346, CWE-942 | Intermediate |
| WSTG-CLNT-08 | Cross Site Flashing | CWE-79 | Intermediate |
| WSTG-CLNT-09 | Clickjacking Testing | CWE-1021 | Intermediate |
| WSTG-CLNT-10 | WebSocket Testing | CWE-346 | Intermediate |
| WSTG-CLNT-11 | Web Messaging Testing | CWE-346 | Intermediate |
| WSTG-CLNT-12 | Browser Storage Testing | CWE-922 | Intermediate |
| WSTG-CLNT-13 | XSSI Testing | CWE-200, CWE-346 | Intermediate |
Detailed Test Cases
WSTG-CLNT-01: DOM-Based XSS
IntermediateDOM-based XSS testing checks whether client-side JavaScript reads data from attacker-controllable sources (URL hash, document.referrer, postMessage) and writes it to dangerous sinks (innerHTML, eval, document.write) without proper sanitization. This type of XSS occurs entirely in the browser.
What to Check
- Identify JavaScript sources that read from URL fragments, query parameters, or document properties
- Map dangerous sinks in JavaScript (innerHTML, eval, document.write, jQuery.html())
- Test if data flows from sources to sinks without sanitization
- Check for DOM XSS in client-side routing and template rendering
- Test postMessage handlers for origin validation and safe data handling
WSTG-CLNT-02: JavaScript Execution Testing
IntermediateThis test checks whether an attacker can inject and execute JavaScript through the application's client-side processing. It focuses on contexts where user input is processed by JavaScript code and may be executed as code rather than treated as data.
What to Check
- Test for JavaScript injection through URL parameters processed by client-side code
- Check for use of eval(), Function(), setTimeout/setInterval with string arguments
- Test for injection through JavaScript template literals and string interpolation
- Verify that user-controlled data is not used in dynamically generated script content
- Check for unsafe JavaScript URL handling (javascript: protocol in links)
WSTG-CLNT-03: HTML Injection
IntermediateHTML injection testing checks whether user input can be used to inject arbitrary HTML content into the page. While similar to XSS, HTML injection focuses on modifying page structure and content (defacement, phishing forms) even when script execution is prevented by Content Security Policy.
What to Check
- Test input fields for HTML tag injection that modifies page structure
- Inject fake login forms to test phishing potential
- Check if HTML injection can override or hide legitimate page content
- Test for HTML injection in error messages, search results, and user profiles
- Verify that Content-Security-Policy prevents escalation to script execution
WSTG-CLNT-04: Client-side URL Redirect
IntermediateThis test checks whether the application performs client-side redirects based on user-controllable input without proper validation. Open redirects can be used in phishing attacks by making malicious URLs appear to originate from the trusted application domain.
What to Check
- Test URL parameters used for redirects (redirect, url, next, return, goto)
- Check if JavaScript-based redirects validate the destination URL
- Test for redirect bypass techniques (protocol-relative URLs, URL encoding, backslash)
- Verify that redirect destinations are validated against a whitelist
- Test for open redirect in OAuth flows and login return URLs
WSTG-CLNT-05: CSS Injection
IntermediateCSS injection testing checks whether user input can be injected into style contexts to manipulate page appearance, exfiltrate data through CSS selectors, or in older browsers, execute JavaScript through CSS expression() functions.
What to Check
- Test if user input is reflected in style attributes or CSS blocks
- Try injecting CSS that modifies page layout to overlay phishing content
- Test CSS-based data exfiltration using attribute selectors and external URL references
- Check for CSS injection in user-customizable themes or profile styling
- Verify that user input in style contexts is properly sanitized
WSTG-CLNT-06: Resource Manipulation
IntermediateThis test checks whether an attacker can manipulate the resources loaded by the client-side application, such as JavaScript files, CSS stylesheets, images, or iframes. This includes testing for subdomain takeover of CDN resources and manipulation of resource URLs through user input.
What to Check
- Identify user-controlled parameters that influence loaded resource URLs
- Test if script, stylesheet, or iframe sources can be manipulated through URL parameters
- Check for Subresource Integrity (SRI) on externally loaded scripts and stylesheets
- Verify that CDN or third-party resource domains are not vulnerable to takeover
- Test if the application validates resource origins before loading them
WSTG-CLNT-07: CORS Testing
IntermediateCross-Origin Resource Sharing (CORS) testing evaluates whether the application's CORS policy allows unauthorized cross-origin access to sensitive data. Overly permissive CORS configurations can allow any website to read authenticated responses from the application's API.
What to Check
- Test if Access-Control-Allow-Origin reflects the requesting origin without validation
- Check if Access-Control-Allow-Credentials is true with a wildcard or reflected origin
- Test for origin validation bypasses (null origin, subdomain matching, regex flaws)
- Verify that CORS is not configured on endpoints that return sensitive data
- Test pre-flight request handling for proper origin validation
WSTG-CLNT-08: Cross Site Flashing
IntermediateCross-site flashing testing checks whether Flash applications (SWF files) on the server can be exploited to execute JavaScript, perform cross-domain data theft, or redirect users. While Flash is largely deprecated, legacy SWF files may still be hosted and exploitable.
What to Check
- Search for SWF files hosted on the application server
- Decompile discovered SWF files and review for user-controlled input handling
- Test for FlashVars injection that can alter SWF behavior
- Check if SWF files use ExternalInterface for JavaScript communication
- Verify that any remaining SWF files are necessary and not exploitable
WSTG-CLNT-09: Clickjacking Testing
IntermediateClickjacking testing checks whether the application can be loaded in a frame or iframe by a malicious site. If so, an attacker can overlay the application with transparent layers to trick users into clicking on actions they did not intend, such as changing settings or making purchases.
What to Check
- Check for X-Frame-Options header (DENY or SAMEORIGIN)
- Verify Content-Security-Policy frame-ancestors directive
- Test if the application can be loaded in an iframe from a different domain
- Check for JavaScript frame-busting code and test if it can be bypassed
- Create a proof-of-concept clickjacking page to demonstrate the vulnerability
WSTG-CLNT-10: WebSocket Testing
IntermediateWebSocket testing evaluates the security of WebSocket connections used for real-time communication. This includes checking authentication, authorization, input validation, and origin validation on WebSocket endpoints, which often lack the security controls applied to HTTP endpoints.
What to Check
- Check if WebSocket connections validate the Origin header during the handshake
- Test if authentication is required and verified for WebSocket connections
- Verify that authorization is enforced on WebSocket messages, not just connection establishment
- Test WebSocket message content for injection vulnerabilities (XSS, SQL injection)
- Check if the WebSocket connection uses the secure wss:// protocol
WSTG-CLNT-11: Web Messaging Testing
IntermediateWeb messaging testing checks the security of the postMessage API used for cross-origin communication between windows and iframes. Insecure implementations may accept messages from any origin or send sensitive data without verifying the recipient's origin.
What to Check
- Identify all postMessage event listeners in the application's JavaScript
- Check if event listeners validate the origin of incoming messages
- Test if sending crafted messages from a different origin triggers application functionality
- Verify that postMessage calls specify the target origin (not '*')
- Check if postMessage data is used in dangerous sinks without sanitization
WSTG-CLNT-12: Browser Storage Testing
IntermediateBrowser storage testing examines what data the application stores in localStorage, sessionStorage, IndexedDB, and cookies. Sensitive data stored in browser storage is accessible to any JavaScript running on the same origin and may persist longer than intended.
What to Check
- Review localStorage and sessionStorage for sensitive data (tokens, PII, credentials)
- Check if session tokens are stored in browser storage instead of httpOnly cookies
- Verify that sensitive data is cleared when the user logs out
- Check IndexedDB for cached sensitive data from API responses
- Test if stored data is encrypted or if plaintext sensitive values are accessible
WSTG-CLNT-13: XSSI Testing
IntermediateCross-Site Script Inclusion (XSSI) testing checks whether sensitive data is exposed through JavaScript files or JSONP endpoints that can be included by an attacker's page. If authenticated JavaScript responses contain user-specific data, an attacker's page can read this data by including the script.
What to Check
- Identify JavaScript endpoints that return different content based on authentication
- Check for JSONP endpoints that include sensitive user data in the callback
- Test if authenticated JavaScript responses contain user-specific information
- Verify that Content-Type headers prevent script inclusion of non-JavaScript responses
- Check if the X-Content-Type-Options: nosniff header prevents MIME type sniffing
Relevant Certifications
The following certifications cover client-side testing concepts:
Frequently Asked Questions
What is the difference between reflected/stored XSS and DOM-based XSS?
Reflected and stored XSS involve the server including malicious input in the HTTP response. DOM-based XSS occurs entirely in the browser when client-side JavaScript reads data from an attacker-controllable source (like the URL fragment) and writes it to a dangerous sink (like innerHTML) without sanitization. DOM-based XSS never reaches the server, making it invisible to server-side security controls and WAFs.
What is clickjacking and how does it affect users?
Clickjacking (UI redressing) tricks users into clicking on something different from what they perceive by loading the target application in a transparent iframe overlaid on a malicious page. The user thinks they are clicking buttons on the attacker's page but are actually interacting with the hidden target application. This can lead to unintended actions like changing settings, making purchases, or granting permissions.
Why is browser storage (localStorage, sessionStorage) a security concern?
Browser storage is accessible to any JavaScript running on the same origin, which means XSS vulnerabilities can read all stored data. Storing sensitive data like session tokens or personal information in localStorage is risky because it persists even after the browser is closed and has no equivalent of cookie security flags (HttpOnly, Secure). Sensitive data should use httpOnly cookies rather than browser storage.
CyberFolio
Mastering web security testing? Showcase your skills.
Build a free, shareable cybersecurity portfolio that highlights your certifications, projects, and skills.
Build Your Portfolio →