Security Vulnerability Testing (OWASP+)
Run 55 security test cases across 5 parallel agents covering injection attacks, HTTP security headers, authentication security, data exposure, and client-side vulnerabilities.
Authorization context: This skill is designed for authorized security testing — pentesting engagements, security audits, and development/staging environments. Always test only URLs you own or have explicit permission to test.
Setup
URL="${ARGUMENTS:-http://localhost:3000}"
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
OUTDIR="test-results/test-security/$TIMESTAMP"
mkdir -p "$OUTDIR/screenshots" "$OUTDIR/snapshots" "$OUTDIR/traces"
Parallel Execution — 5 Subagents
Agent 1: Injection (-s=sec-injection)
Tests injection vulnerabilities across all input vectors.
playwright-cli -s=sec-injection open "$URL"
playwright-cli -s=sec-injection tracing-start
playwright-cli -s=sec-injection snapshot --filename="$OUTDIR/snapshots/injection-initial.yaml"
Test Cases:
| TC |
Test |
How to Check |
| TC-S1 |
Reflected XSS in inputs + URL params |
Fill every input with <script>alert(1)</script>, submit, check if script appears unescaped in DOM. Also test URL params: ?q=<script>alert(1)</script> |
| TC-S2 |
Stored XSS |
Submit XSS payload, reload page, run-code to check for script execution or unescaped payload in DOM |
| TC-S3 |
DOM-based XSS |
Navigate to URL#<img src=x>, check DOM. Try javascript: in URL inputs |
| TC-S4 |
SVG XSS |
If file upload exists: attempt upload with SVG containing <svg>. Also test <svg> in text inputs |
| TC-S5 |
SQL injection |
Fill inputs with ' OR 1=1--, '; DROP TABLE users--, ' UNION SELECT null--, check for database errors or unexpected data |
| TC-S6 |
NoSQL injection |
If JSON-based forms: test {"$gt": ""}, {"$ne": null} patterns via run-code with fetch API |
| TC-S7 |
Command injection |
Fill inputs with ; ls, `whoami`, $(cat /etc/passwd), check for command output in response |
| TC-S8 |
HTML injection |
Fill inputs with <h1>injected</h1>, <iframe src=evil.com>, verify HTML is escaped in output |
| TC-S9 |
LDAP/XPath injection |
Fill inputs with *)(objectClass=*, ' or '1'='1, check for errors |
| TC-S10 |
Template injection |
Fill inputs with {{7*7}}, ${7*7}, <%= 7*7 %>, check if output shows 49 |
playwright-cli -s=sec-injection tracing-stop
playwright-cli -s=sec-injection close
Agent 2: Headers (-s=sec-headers)
Tests HTTP security headers and TLS configuration.
playwright-cli -s=sec-headers open "$URL"
playwright-cli -s=sec-headers tracing-start
Test Cases:
Use run-code with fetch(url) to inspect response headers, or playwright-cli network after page load.
| TC |
Test |
How to Check |
| TC-S11 |
Content-Security-Policy present + configured |
run-code to fetch and check CSP header exists, has script-src, style-src, default-src |
| TC-S12 |
X-Frame-Options or CSP frame-ancestors |
Check for X-Frame-Options: DENY/SAMEORIGIN or CSP frame-ancestors directive |
| TC-S13 |
X-Content-Type-Options: nosniff |
Check header present and value is nosniff |
| TC-S14 |
Strict-Transport-Security (HSTS) |
Check for HSTS header with includeSubDomains and reasonable max-age (≥31536000) |
| TC-S15 |
Referrer-Policy |
Check for no-referrer, strict-origin, or strict-origin-when-cross-origin |
| TC-S16 |
Permissions-Policy |
Check header restricts camera, microphone, geolocation |
| TC-S17 |
X-XSS-Protection |
Check header present (legacy but still checked) |
| TC-S18 |
Cache-Control on sensitive pages |
Check no-store or no-cache on pages with forms/auth |
| TC-S19 |
HTTPS enforcement |
run-code to try HTTP URL, verify redirect to HTTPS |
| TC-S20 |
Mixed content |
run-code to find any HTTP resources loaded on HTTPS page (scripts, images, stylesheets) |
| TC-S21 |
CORS headers properly scoped |
Check Access-Control-Allow-Origin is not * on authenticated endpoints |
| TC-S22 |
Server header removed/generic |
Check Server header doesn't expose version info (e.g., Apache/2.4.51) |
playwright-cli -s=sec-headers tracing-stop
playwright-cli -s=sec-headers close
Agent 3: Auth (-s=sec-auth)
Tests authentication and session security.
playwright-cli -s=sec-auth open "$URL"
playwright-cli -s=sec-auth tracing-start
Test Cases:
| TC |
Test |
How to Check |
| TC-S23 |
CSRF tokens on state-changing forms |
run-code to find forms with POST method, check for hidden CSRF token field |
| TC-S24 |
CSRF token changes per session/request |
Load page twice in different sessions, compare CSRF tokens |
| TC-S25 |
Session cookie flags |
cookie-list and check session cookies for HttpOnly, Secure, SameSite flags |
| TC-S26 |
Session ID changes after login |
Record session ID before login, login, compare session ID after |
| TC-S27 |
Logout invalidates session |
Login, save session cookie, logout, try using saved cookie, verify rejected |
| TC-S28 |
Password field uses type="password" |
run-code to find password fields, verify type="password" |
| TC-S29 |
Login form served over HTTPS |
Check login page URL starts with https:// |
| TC-S30 |
No user enumeration |
Try login with invalid user vs invalid password, compare error messages — should be identical |
| TC-S31 |
Account lockout after N failed attempts |
Attempt 5+ failed logins, check if account locks or rate limits |
| TC-S32 |
Password policy enforced |
Try weak passwords ("123", "password", "a"), verify rejection |
| TC-S33 |
No autocomplete on sensitive fields |
run-code to check autocomplete="off" or autocomplete="new-password" on password/CC fields |
| TC-S34 |
JWT not stored in localStorage |
localstorage-list and check for JWT tokens (long base64 strings with two dots) |
| TC-S35 |
OAuth redirect_uri validated |
If OAuth present: try redirect_uri=https://evil.com, verify rejected |
playwright-cli -s=sec-auth tracing-stop
playwright-cli -s=sec-auth close
Agent 4: Data (-s=sec-data)
Tests data exposure and privacy issues.
playwright-cli -s=sec-data open "$URL"
playwright-cli -s=sec-data tracing-start
Test Cases:
| TC |
Test |
How to Check |
| TC-S36 |
Sensitive data in URLs |
Check current URL and all links for tokens, passwords, SSN patterns in query strings |
| TC-S37 |
Sensitive data in localStorage/sessionStorage |
localstorage-list and sessionstorage-list, look for PII, tokens, passwords |
| TC-S38 |
API keys/secrets in page source or JS |
run-code to get page HTML and inline scripts, regex for API key patterns (sk_, api_key, secret) |
| TC-S39 |
Source maps in production |
run-code to check for .map references in loaded scripts, try fetching them |
| TC-S40 |
Stack traces/debug info in errors |
Trigger 404/500 errors, check response for stack traces, file paths, debug info |
| TC-S41 |
Directory listing enabled |
Navigate to /uploads/, /api/, /static/, check for directory listing |
| TC-S42 |
Server version in headers/errors |
Check Server, X-Powered-By headers for version numbers |
| TC-S43 |
Sensitive files accessible |
Try fetching /.env, /.git/config, /package.json, /wp-config.php, check if accessible |
| TC-S44 |
PII in HTML comments |
run-code to extract all HTML comments, check for emails, phone numbers, internal notes |
| TC-S45 |
Credit card/SSN fields autofill exclusion |
Check autocomplete="off" on CC/SSN fields |
playwright-cli -s=sec-data tracing-stop
playwright-cli -s=sec-data close
Agent 5: Client (-s=sec-client)
Tests client-side security vulnerabilities.
playwright-cli -s=sec-client open "$URL"
playwright-cli -s=sec-client tracing-start
Test Cases:
| TC |
Test |
How to Check |
| TC-S46 |
Open redirects |
Navigate to ?redirect=https://evil.com, ?next=//evil.com, verify no redirect to external domain |
| TC-S47 |
Clickjacking protection |
Verify X-Frame-Options header or CSP frame-ancestors prevents embedding in iframe |
| TC-S48 |
Window.opener vulnerability |
run-code to find external links without rel="noopener noreferrer" |
| TC-S49 |
Insecure postMessage |
run-code to find addEventListener('message') handlers, check if origin is validated |
| TC-S50 |
eval()/innerHTML with user input |
run-code to search page scripts for eval(, innerHTML =, document.write( patterns |
| TC-S51 |
Subresource integrity (SRI) on CDN scripts |
run-code to find external scripts from CDNs, check for integrity attribute |
| TC-S52 |
Outdated JS libraries |
run-code to detect library versions (jQuery, Bootstrap, Angular, React), flag known vulnerable versions |
| TC-S53 |
WebSocket security |
run-code to find WebSocket connections, verify wss:// not ws:// |
| TC-S54 |
File upload without validation |
If file upload exists: try uploading .html, .svg, .exe files |
| TC-S55 |
Content-Disposition on downloads |
Click download links, check Content-Disposition: attachment header via run-code with fetch |
playwright-cli -s=sec-client tracing-stop
playwright-cli -s=sec-client close
Report Generation
After all 5 agents complete, merge results into $OUTDIR/report.md following the standard report format.
Security findings should be grouped by severity:
- Critical: Active exploitable vulnerabilities (XSS, SQL injection, open redirect)
- Major: Missing security controls (no CSP, no CSRF tokens, weak session management)
- Minor: Best practice deviations (missing SRI, no X-XSS-Protection, verbose server header)
- Info: Recommendations (version updates, configuration improvements)
Cleanup
playwright-cli -s=sec-injection close 2>/dev/null
playwright-cli -s=sec-headers close 2>/dev/null
playwright-cli -s=sec-auth close 2>/dev/null
playwright-cli -s=sec-data close 2>/dev/null
playwright-cli -s=sec-client close 2>/dev/null
1---2name: test-security-23description: Run OWASP+ security vulnerability testing on a URL. Use when user wants to test security, find XSS, SQL injection, check headers, CSRF, authentication security, or data exposure.4---56# Security Vulnerability Testing (OWASP+)78Run 55 security test cases across 5 parallel agents covering injection attacks, HTTP security headers, authentication security, data exposure, and client-side vulnerabilities.910**Authorization context**: This skill is designed for authorized security testing — pentesting engagements, security audits, and development/staging environments. Always test only URLs you own or have explicit permission to test.1112## Setup1314```bash15URL="${ARGUMENTS:-http://localhost:3000}"16TIMESTAMP=$(date +%Y%m%d-%H%M%S)17OUTDIR="test-results/test-security/$TIMESTAMP"18mkdir -p "$OUTDIR/screenshots" "$OUTDIR/snapshots" "$OUTDIR/traces"19```2021## Parallel Execution — 5 Subagents2223### Agent 1: Injection (`-s=sec-injection`)2425Tests injection vulnerabilities across all input vectors.2627```bash28playwright-cli -s=sec-injection open "$URL"29playwright-cli -s=sec-injection tracing-start30playwright-cli -s=sec-injection snapshot --filename="$OUTDIR/snapshots/injection-initial.yaml"31```3233**Test Cases:**3435| TC | Test | How to Check |36|----|------|-------------|37| TC-S1 | Reflected XSS in inputs + URL params | Fill every input with `<script>alert(1)</script>`, submit, check if script appears unescaped in DOM. Also test URL params: `?q=<script>alert(1)</script>` |38| TC-S2 | Stored XSS | Submit XSS payload, reload page, `run-code` to check for script execution or unescaped payload in DOM |39| TC-S3 | DOM-based XSS | Navigate to `URL#<img onerror=alert(1) src=x>`, check DOM. Try `javascript:` in URL inputs |40| TC-S4 | SVG XSS | If file upload exists: attempt upload with SVG containing `<svg onload=alert(1)>`. Also test `<svg>` in text inputs |41| TC-S5 | SQL injection | Fill inputs with `' OR 1=1--`, `'; DROP TABLE users--`, `' UNION SELECT null--`, check for database errors or unexpected data |42| TC-S6 | NoSQL injection | If JSON-based forms: test `{"$gt": ""}`, `{"$ne": null}` patterns via `run-code` with fetch API |43| TC-S7 | Command injection | Fill inputs with `; ls`, `` `whoami` ``, `$(cat /etc/passwd)`, check for command output in response |44| TC-S8 | HTML injection | Fill inputs with `<h1>injected</h1>`, `<iframe src=evil.com>`, verify HTML is escaped in output |45| TC-S9 | LDAP/XPath injection | Fill inputs with `*)(objectClass=*`, `' or '1'='1`, check for errors |46| TC-S10 | Template injection | Fill inputs with `{{7*7}}`, `${7*7}`, `<%= 7*7 %>`, check if output shows `49` |4748```bash49playwright-cli -s=sec-injection tracing-stop50playwright-cli -s=sec-injection close51```5253### Agent 2: Headers (`-s=sec-headers`)5455Tests HTTP security headers and TLS configuration.5657```bash58playwright-cli -s=sec-headers open "$URL"59playwright-cli -s=sec-headers tracing-start60```6162**Test Cases:**6364Use `run-code` with `fetch(url)` to inspect response headers, or `playwright-cli network` after page load.6566| TC | Test | How to Check |67|----|------|-------------|68| TC-S11 | Content-Security-Policy present + configured | `run-code` to fetch and check CSP header exists, has script-src, style-src, default-src |69| TC-S12 | X-Frame-Options or CSP frame-ancestors | Check for `X-Frame-Options: DENY/SAMEORIGIN` or CSP `frame-ancestors` directive |70| TC-S13 | X-Content-Type-Options: nosniff | Check header present and value is `nosniff` |71| TC-S14 | Strict-Transport-Security (HSTS) | Check for HSTS header with `includeSubDomains` and reasonable `max-age` (≥31536000) |72| TC-S15 | Referrer-Policy | Check for `no-referrer`, `strict-origin`, or `strict-origin-when-cross-origin` |73| TC-S16 | Permissions-Policy | Check header restricts camera, microphone, geolocation |74| TC-S17 | X-XSS-Protection | Check header present (legacy but still checked) |75| TC-S18 | Cache-Control on sensitive pages | Check `no-store` or `no-cache` on pages with forms/auth |76| TC-S19 | HTTPS enforcement | `run-code` to try HTTP URL, verify redirect to HTTPS |77| TC-S20 | Mixed content | `run-code` to find any HTTP resources loaded on HTTPS page (scripts, images, stylesheets) |78| TC-S21 | CORS headers properly scoped | Check `Access-Control-Allow-Origin` is not `*` on authenticated endpoints |79| TC-S22 | Server header removed/generic | Check `Server` header doesn't expose version info (e.g., `Apache/2.4.51`) |8081```bash82playwright-cli -s=sec-headers tracing-stop83playwright-cli -s=sec-headers close84```8586### Agent 3: Auth (`-s=sec-auth`)8788Tests authentication and session security.8990```bash91playwright-cli -s=sec-auth open "$URL"92playwright-cli -s=sec-auth tracing-start93```9495**Test Cases:**9697| TC | Test | How to Check |98|----|------|-------------|99| TC-S23 | CSRF tokens on state-changing forms | `run-code` to find forms with POST method, check for hidden CSRF token field |100| TC-S24 | CSRF token changes per session/request | Load page twice in different sessions, compare CSRF tokens |101| TC-S25 | Session cookie flags | `cookie-list` and check session cookies for HttpOnly, Secure, SameSite flags |102| TC-S26 | Session ID changes after login | Record session ID before login, login, compare session ID after |103| TC-S27 | Logout invalidates session | Login, save session cookie, logout, try using saved cookie, verify rejected |104| TC-S28 | Password field uses `type="password"` | `run-code` to find password fields, verify `type="password"` |105| TC-S29 | Login form served over HTTPS | Check login page URL starts with `https://` |106| TC-S30 | No user enumeration | Try login with invalid user vs invalid password, compare error messages — should be identical |107| TC-S31 | Account lockout after N failed attempts | Attempt 5+ failed logins, check if account locks or rate limits |108| TC-S32 | Password policy enforced | Try weak passwords ("123", "password", "a"), verify rejection |109| TC-S33 | No autocomplete on sensitive fields | `run-code` to check `autocomplete="off"` or `autocomplete="new-password"` on password/CC fields |110| TC-S34 | JWT not stored in localStorage | `localstorage-list` and check for JWT tokens (long base64 strings with two dots) |111| TC-S35 | OAuth redirect_uri validated | If OAuth present: try `redirect_uri=https://evil.com`, verify rejected |112113```bash114playwright-cli -s=sec-auth tracing-stop115playwright-cli -s=sec-auth close116```117118### Agent 4: Data (`-s=sec-data`)119120Tests data exposure and privacy issues.121122```bash123playwright-cli -s=sec-data open "$URL"124playwright-cli -s=sec-data tracing-start125```126127**Test Cases:**128129| TC | Test | How to Check |130|----|------|-------------|131| TC-S36 | Sensitive data in URLs | Check current URL and all links for tokens, passwords, SSN patterns in query strings |132| TC-S37 | Sensitive data in localStorage/sessionStorage | `localstorage-list` and `sessionstorage-list`, look for PII, tokens, passwords |133| TC-S38 | API keys/secrets in page source or JS | `run-code` to get page HTML and inline scripts, regex for API key patterns (`sk_`, `api_key`, `secret`) |134| TC-S39 | Source maps in production | `run-code` to check for `.map` references in loaded scripts, try fetching them |135| TC-S40 | Stack traces/debug info in errors | Trigger 404/500 errors, check response for stack traces, file paths, debug info |136| TC-S41 | Directory listing enabled | Navigate to `/uploads/`, `/api/`, `/static/`, check for directory listing |137| TC-S42 | Server version in headers/errors | Check `Server`, `X-Powered-By` headers for version numbers |138| TC-S43 | Sensitive files accessible | Try fetching `/.env`, `/.git/config`, `/package.json`, `/wp-config.php`, check if accessible |139| TC-S44 | PII in HTML comments | `run-code` to extract all HTML comments, check for emails, phone numbers, internal notes |140| TC-S45 | Credit card/SSN fields autofill exclusion | Check `autocomplete="off"` on CC/SSN fields |141142```bash143playwright-cli -s=sec-data tracing-stop144playwright-cli -s=sec-data close145```146147### Agent 5: Client (`-s=sec-client`)148149Tests client-side security vulnerabilities.150151```bash152playwright-cli -s=sec-client open "$URL"153playwright-cli -s=sec-client tracing-start154```155156**Test Cases:**157158| TC | Test | How to Check |159|----|------|-------------|160| TC-S46 | Open redirects | Navigate to `?redirect=https://evil.com`, `?next=//evil.com`, verify no redirect to external domain |161| TC-S47 | Clickjacking protection | Verify X-Frame-Options header or CSP frame-ancestors prevents embedding in iframe |162| TC-S48 | Window.opener vulnerability | `run-code` to find external links without `rel="noopener noreferrer"` |163| TC-S49 | Insecure postMessage | `run-code` to find `addEventListener('message')` handlers, check if origin is validated |164| TC-S50 | eval()/innerHTML with user input | `run-code` to search page scripts for `eval(`, `innerHTML =`, `document.write(` patterns |165| TC-S51 | Subresource integrity (SRI) on CDN scripts | `run-code` to find external scripts from CDNs, check for `integrity` attribute |166| TC-S52 | Outdated JS libraries | `run-code` to detect library versions (jQuery, Bootstrap, Angular, React), flag known vulnerable versions |167| TC-S53 | WebSocket security | `run-code` to find WebSocket connections, verify `wss://` not `ws://` |168| TC-S54 | File upload without validation | If file upload exists: try uploading `.html`, `.svg`, `.exe` files |169| TC-S55 | Content-Disposition on downloads | Click download links, check `Content-Disposition: attachment` header via `run-code` with fetch |170171```bash172playwright-cli -s=sec-client tracing-stop173playwright-cli -s=sec-client close174```175176## Report Generation177178After all 5 agents complete, merge results into `$OUTDIR/report.md` following the standard report format.179180Security findings should be grouped by severity:1811. **Critical**: Active exploitable vulnerabilities (XSS, SQL injection, open redirect)1822. **Major**: Missing security controls (no CSP, no CSRF tokens, weak session management)1833. **Minor**: Best practice deviations (missing SRI, no X-XSS-Protection, verbose server header)1844. **Info**: Recommendations (version updates, configuration improvements)185186## Cleanup187188```bash189playwright-cli -s=sec-injection close 2>/dev/null190playwright-cli -s=sec-headers close 2>/dev/null191playwright-cli -s=sec-auth close 2>/dev/null192playwright-cli -s=sec-data close 2>/dev/null193playwright-cli -s=sec-client close 2>/dev/null194```