Secure Coding Guide | 크로스 사이트 스크립트 (XSS)
정의
크로스 사이트 스크립트(cross-site scripting)은 검증되지 않은 외부 입력 값을 응답의 일부로 사용하는 경우 사용자 브라우저에서 악의적인 스크립트가 실행될 수 있는 보안약점이다.
영향
쿠키 정보를 탈취하거나 피싱사이트,불법 광고 사이트 등의 악성 사이트로 이동할 수 있다.
방식
Reflected XSS
URL을 이용하여 스크립트를 피해자에게 직접 노출시켜 공격
Stored XSS
스크립트를 서버의 게시판 등 DB에 저장하여 클라이언트가 열람시 발생
조치 방법
검증되지 않은 값을 웹 브라우저에 보내는 경우(XSS_ATTRIBUTE)
안전하지 않은 jsp 코드 일부
<tr>
<td colspan="2">${contents}</td>
</tr>
attribute로부터 얻어온 값에 대한 검증을 수행하지 않는다.
안전한 jsp 코드 일부
<tr>
<td colspan="2"><c:out value="${contents}"/></td>
</tr>
JSTL의 <c:out>
태그를 사용하여 필터링을 수행한다.
javascipt에서 막는 방법
var escapeHtmlMap = {
"&" : "&",
"<" : "<",
">" : ">",
'"' : '"',
"'" : ''',
"/" : '/'
};
String.prototype.escapeHTML = function() {
return String(this).replace(/[&<>"'\/]/g, function(s) {
return escapeHtmlMap[s];
});
};
var text = "안녕하세요! <b>데브쿠아</b>입니다.";
text.escapeHTML();
참고 자료
공격에 이용되는 스크립트/태그
태그 | 기능 |
---|---|
<SCRIPT> |
스크립트 코드를 실행 |
<OBJECT> |
Active-X 컨트롤을 실행 |
<APPLET> |
자바 애플릿 등을 실행 |
<EMBED> |
객체 등을 포함 (예: 동영상, 음악) |
<FORM> |
태그를 사용해 기존폼을 수정하여 사용자의 민감한 정보를 빼돌릴 수 있음 |
<IMG> |
이미지를 브라우저 상에서 로드 함 |
<IFRAME> |
웹문서내에특정페이지를로드함 |
다양한 XSS 패턴 https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
잘못된 조치 방법
String param = request.getParameter("Param");
param = param.replaceAll("<script>", "");
param = param.replaceAll("</script>", "");
- 필터링을 사용하였으나, 문장을 공백으로 변경하여 우회 공격이 가능하다.
- 공격시
<sc<script>ript>
로 공격하면<script>
로 되어 스크립트 공격 가능하다.
<c:out value="${param}" escapeXml="false"></c:out>
- JSTL 라이브러리 c:out을 사용하였으나 escapeXml 옵션을 false 로 한 경우 스크립트 공격에 취약하다.
올바른 조치 방법
String param = request.getParameter("param");
param = param.replaceAll("<", "");
param = param.replaceAll(">", "");
param = param.replaceAll("/", "");
param = param.replaceAll(";", "");
param = param.replaceAll(",", "");
param = param.replaceAll("!", "");
param = param.replaceAll("-", "");
- 단어보단 문자열을 필터링한다.
; , ! –
XSS.DOM 방지를 위해 해당 문자열도 수행한다.;alert()<!–
식으로도 공격한다.
String param = request.getParameter("param");
param = param.replaceAll("<script>", "<scr(X)ipt>");
param = param.replaceAll("</script>", "</scr(X)ipt");
- 단어등의 문장을 필터링 하는 경우 공백이 아닌 의미없는 문자로 변경한다.
<c:out value="${param}"></c:out>
- JSTL 라이브러리 c:out을 사용한다. (escapeXml 옵션 기본값 : true)
최종 수정 : 2018-05-27