Residential Proxies Web Scraping API Turn Sites Into AI Data Automate 3000+ Apps Learn Python Automation Pay As You Go Proxies
Residential Proxies Web Scraping API
Pay As You Go Proxies 10 Free Proxies Antidetect Browser No Code Browser Bots Web Data For AI Agents Hire Scraper Builders

Security Testing with Playwright: Authentication, Authorization, and XSS

Updated August 2026
Playwright is not a security scanner, but its browser automation capabilities make it powerful for writing application-specific security tests that generic scanners cannot cover. Playwright tests can verify that authentication flows reject invalid sessions, authorization rules prevent privilege escalation, XSS payloads are sanitized, and security headers are correctly set. This guide shows how to use Playwright for each of these security testing scenarios with practical approaches you can adapt to your application.

Playwright fills a gap between generic DAST scanners and manual penetration testing. A scanner like OWASP ZAP tests every input with generic payloads but does not understand your application's specific authorization model, multi-step workflows, or business logic. A penetration tester understands these but tests manually and infrequently. Playwright tests encode your application's security requirements as automated, repeatable checks that run on every deployment.

The tests described here complement, not replace, DAST scanning. ZAP excels at broad vulnerability detection across hundreds of inputs. Playwright excels at deep, application-specific checks that require navigating real user flows. Running both provides coverage that neither achieves alone.

Set Up a Security Test Suite

Create a dedicated test file or directory for security tests, separate from functional tests. Security tests often need different configuration: longer timeouts for brute-force simulations, multiple browser contexts for testing user isolation, and request interception for inspecting headers and cookies.

Structure your security tests around the application's security requirements. Group them by category: authentication tests, authorization tests, input validation tests, and configuration tests. Each group maps to a section of the OWASP Top 10 and can be tagged for selective execution.

Create helper functions for common operations: logging in as a specific user role, extracting session tokens from cookies, and making API requests with modified headers. These helpers keep individual tests focused on what they are verifying rather than the mechanics of setting up each scenario.

Use Playwright's built-in test runner with its assertion library. Playwright's auto-retry logic is useful for functional tests but should be disabled for security tests: if an authorization check fails once, it should fail immediately rather than retrying, because a transient "pass" on a security test is not safe.

Test Authentication Boundaries

Session token validation. Log in and capture the session cookie or JWT. Close the browser context to simulate the session ending on the client side. Open a new context, manually set the captured token, and attempt to access a protected page. If the application returns the protected content, the session is still valid server-side, which is correct. Now modify the token (change one character) and repeat: the application should reject the modified token with a 401 or redirect to login. If it accepts a modified token, session validation is broken.

Session expiration. After logging in, wait for the configured session timeout period (or manipulate the session's expiry time if your test environment supports it). Then attempt to access a protected page with the expired session. The application should reject the request and require re-authentication.

Logout effectiveness. Log in, capture the session token, then click the logout button (or call the logout endpoint). After logout, attempt to use the captured session token by setting it as a cookie in a new browser context. If the application still accepts the token, logout does not invalidate the session server-side, which means a stolen token remains usable even after the user logs out.

Credential enumeration. Submit a login attempt with a valid username and wrong password, then a login attempt with a nonexistent username and any password. Compare the error messages. If they differ ("incorrect password" vs "user not found"), the application leaks which usernames exist, enabling targeted attacks. Both cases should return an identical generic message like "invalid credentials."

Session fixation. Before logging in, manually set a known session ID in the browser's cookies. Then log in through the normal flow. After successful login, check whether the session ID changed. If the application continues using the pre-set session ID after authentication, it is vulnerable to session fixation: an attacker who sets the cookie before the victim logs in gains access to the victim's authenticated session.

Test Authorization Rules

Horizontal privilege escalation. Log in as User A and navigate to a page that displays User A's data (profile, orders, documents). Note the URL and any identifiers in the URL or API requests (user ID, order ID, document ID). Log in as User B in a separate browser context. Attempt to access User A's data by navigating to the same URLs or making the same API requests with User A's identifiers. If User B can see User A's data, access control is broken at the data level.

Vertical privilege escalation. Log in as a regular user and attempt to access admin-only pages by navigating to their URLs directly. Try /admin, /dashboard, /users, /settings, and any admin paths you know exist. Also test admin API endpoints by making API requests with the regular user's session token. The application should return 403 Forbidden or redirect to an error page for every admin resource.

Object-level authorization. For every endpoint that accepts a resource ID (order, document, account), test whether changing the ID gives access to resources belonging to other users or roles. This is the most common authorization failure in APIs, often called IDOR (Insecure Direct Object Reference). Playwright can automate this by iterating through a list of IDs and checking whether the response contains data the current user should not see.

Method-level authorization. If a user can view a resource (GET), verify that they cannot modify it (PUT/PATCH) or delete it (DELETE) unless explicitly authorized. Playwright's request interception can change the HTTP method of outgoing requests, testing whether the server enforces method-level restrictions or only checks authorization on the methods the UI normally uses.

Test XSS and Input Handling

Reflected XSS. Submit a test payload through every form field and URL parameter, then check whether the payload appears in the response page's DOM. Use a recognizable but harmless marker like a unique string wrapped in angle brackets. If the marker appears in the DOM as HTML elements rather than escaped text, the field is vulnerable to XSS. Test different contexts: the payload may be placed inside an HTML element, an attribute value, a JavaScript string, or a URL, and each context requires different escaping.

Stored XSS. Submit a test payload through an input that saves data (profile name, comment, product review). Navigate to the page where the saved data is displayed and check the DOM for the unescaped payload. Stored XSS is more dangerous than reflected because every user who views the affected page is attacked, not just the user who clicked a malicious link.

DOM-based XSS. Examine pages that read from URL parameters (hash fragments, query strings) using client-side JavaScript. Modify the URL parameter with a test payload and check whether the page's JavaScript processes it in an unsafe way, such as using innerHTML, document.write, or eval with the parameter value. Playwright's page.evaluate() method lets you inspect the DOM state after JavaScript execution.

Content Security Policy enforcement. If the application sets a Content-Security-Policy header, verify that it actually blocks inline scripts. Inject an inline script tag through a vulnerable input (or add one directly if testing your own code) and check whether the browser's CSP blocks its execution. Playwright can listen for CSP violation events in the page console to confirm that the policy is enforced.

For a deeper dive into XSS testing methodology, see our XSS testing guide.

Verify Security Headers and Cookies

Playwright gives you programmatic access to every HTTP response header and cookie, making it straightforward to verify security configuration across the application.

Response headers. For each page request, check that the response includes the essential security headers. Content-Security-Policy should restrict script sources (no unsafe-inline if possible). Strict-Transport-Security should have max-age of at least 31536000 (one year) and include includeSubDomains. X-Content-Type-Options should be "nosniff." X-Frame-Options should be "DENY" or "SAMEORIGIN" unless the page is designed to be framed. Referrer-Policy should restrict referrer information to avoid leaking URLs to external sites.

Cookie flags. After login, examine the session cookie's attributes. HttpOnly should be true (JavaScript cannot read the cookie, preventing theft through XSS). Secure should be true (cookie only sent over HTTPS). SameSite should be "Lax" or "Strict" (prevents CSRF by restricting cross-site cookie sending). Playwright's context.cookies() method returns all cookie attributes for inspection.

HTTPS enforcement. Make a request to the HTTP version of each page and verify that the application redirects to HTTPS. Check that no page serves content over plain HTTP, and that no mixed content (HTTP resources on HTTPS pages) is loaded. Playwright's page.on("request") handler can monitor all outgoing requests and flag any that use HTTP.

Information leakage. Check response headers for information that helps attackers: Server headers revealing software versions, X-Powered-By revealing frameworks, and detailed error messages revealing internal paths or stack traces. These headers should be removed or set to generic values in production.

Run in CI/CD

Add Playwright security tests to your CI pipeline alongside functional tests. They use the same infrastructure, the same browser binaries, and the same test runner. The only difference is what they verify.

Run security tests after deployment to staging, not against production. Security tests may submit malicious payloads, attempt unauthorized access, and test error handling in ways that could affect real users in production. The staging environment is the right place for these tests because it mirrors production behavior without affecting live traffic.

Tag security tests separately from functional tests so they can be run on a different schedule if needed. Some teams run security tests on every deployment, others run them nightly alongside full DAST scans. The appropriate frequency depends on your deployment cadence and risk tolerance.

Set clear pass/fail criteria. Any test that demonstrates a privilege escalation, session management failure, or XSS vulnerability should fail the pipeline and block promotion to production. Configuration issues like missing headers should be tracked as warnings that generate tickets but do not block deployment.

Playwright security tests pair well with DAST scanning. Run ZAP for broad vulnerability detection (hundreds of inputs, thousands of payloads) and Playwright for deep, application-specific checks (exact authorization rules, specific workflow bypasses). Together, they cover both the breadth and depth dimensions of automated security testing.

When Playwright Is Better Than a DAST Scanner

Playwright outperforms generic DAST scanners in four situations. First, authorization testing that requires understanding the application's specific role model: which users can access which resources, what the escalation boundaries are, and where IDOR vulnerabilities hide. Second, multi-step workflow testing that requires maintaining state across multiple pages: completing checkout, going through a verification flow, or testing a multi-stage approval process. Third, business logic testing that requires understanding what the application is supposed to do: preventing self-referral, enforcing purchase limits, or verifying that discounts apply correctly. Fourth, client-side security that requires inspecting JavaScript behavior: DOM-based XSS, CSP enforcement, and localStorage data exposure.

In all four cases, the tests require application-specific knowledge that only a human can encode. Playwright is the tool that turns that knowledge into automated, repeatable checks.

When a DAST Scanner Is Better Than Playwright

DAST scanners outperform Playwright in situations requiring breadth over depth. A scanner like ZAP tests every input on every page with hundreds of payloads, finding injection vulnerabilities that a Playwright test suite would need thousands of test cases to match. Scanners also catch configuration issues (missing headers, weak TLS, directory listing) across the entire application in a single pass, while Playwright tests would need to check each page individually. Use both: ZAP for breadth, Playwright for depth.

Key Takeaway

Playwright turns your application's security requirements into automated tests that run on every deployment. Use it for authentication bypass testing, authorization boundary verification, XSS payload testing, and security header validation. Pair it with a DAST scanner like ZAP for comprehensive coverage that combines broad vulnerability detection with deep, application-specific security checks.