웹사이트에 악의적인 스크립트를 삽입하는 공격이다. 사용자가 XSS 공격을 받은 사이트에 접속할 때, 브라우저는 공격자가 삽입한 스크립트를 실행하게 되며, 해당 스크립트가 사이트에 원래 있던 스크립트인지 XSS를 통해서 삽입된 스크립트인지 구분할 수 없다.
공격자는 스크립트를 통해서 쿠키나 세션 등 사용자의 민감한 정보를 얻을 수 있으며, 삽입된 페이지의 HTML 코드까지 수정할 수 있다.
방어 기법
Stored/Reflected XSS는 서버 측에서의 Escape, Validate로 방어 가능하며, DOM Based XSS는 별도의 규칙을 적용해야 한다.
기본적으로 신뢰할 수 없는 입력(사용자로부터 받는 입력)을 사용할 때에는 Escape 과정을 거쳐야 한다.
신뢰할 수 있는 라이브러리를 사용하는 것이 좋다. JAVA의 경우, OWASP에서 제작한 OWASP Java Encoder Project이 있음.
예방 규칙 (Rule)
HTML Body
<span>UNTRUSTED DATA</span>
HTTP Entity(<, >, \&, ", ', \/) Encoding 사용
HTML Attribute
<input type="text" name="fname" value="UNTRUSTED DATA">
- Non-Alphanumeric 문자들을 \&#xHH 형식으로 Encode한다.
UnQuoted Attribute는 여러 문자들에 의해 망가질 수 있다.
GET Parameter
<a href="/site/search?value=UNTRUSTED DATA">clickme</a>
- Non-Alphanumeric 문자들을 \%HH 형식으로 Encode한다.
URL in SRC/HREF Attribute
<a href="UNTRUSTED URL">clickme</a>
<iframe src="UNTRUSTED URL" />
- Attribute Encode
- White List 사용
- URL Validation/Verification
- Canonicalize Input
CSS Value
<div style="width: UNTRUSTED DATA;">Selection</div>
- Non-Alphanumeric 문자들을 \HH 형식으로 Encode한다.
JavaScript Variable
<script>var currentValue='UNTRUSTED DATA';</script>
<script>someFunction('UNTRUSTED DATA');</script>
- JavaScript 변수가 Quote 되어 있는지 확인
- Hex/Unicode 인코딩
- Avoid Backslash Encoding
HTML Body
<div>UNTRUSTED HTML</div>
- HTML Validation
DOM XSS
<script>document.write("UNTRUSTED INPUT: " + document.location.hash);<script/>