-
[ 번역 ] XSS 대응( 이스케이프 처리 )Technique/WEB 2016. 9. 6. 11:55반응형
원문 : http://d.hatena.ne.jp/ockeghem/20070511/1178899191
을 번역하였습니다. 의역좀 들어가있고, 오역지적 해주시면 참고 하겠습니다.
xss 대응 : javascript등의 이스케이프
스크립트가 onXXX의 이벤트 핸들러로서 기억되는 경우
이 경우는 HTML 태그의 특성값으로서 스크립트가 기억되기 때문에 ' 스크립트는 문자 참조에 의해 이스케이프가 필요' 가 된다구체적으로는 (최저) ["]와 [&] 가 되겟다.
1<input type="text" onmouseover="alert('Hello world');">cs
이렇게 적는것이 보통이지만, 적으려고 한다면1<input type="text" onmouseover="alert("Hello world");">cs
이렇게 적어도 좋다.
그러나 스크립트 안에도 문자열 리터럴과 같이 에스케이프를 필요로하는 부분가 있다. 아래와 같이1<input type="text" onmouseover="alert('Hello JavaScript\'s world');">cs
더욱이 javascript문자열 리터럴의 에스케이프와 문자 참조를 조합해야하는 경우도 나타난다.1<input type="text" onmouseover="alert("He said \"Hello world\"");">cs
점점 무슨말인지 모르게 되고 있다.
그러나 원리는 간단하다"●●●●●'▲▲▲▲'●●●●●"
위와같이 어딘가에 계속 넣는 구조로 구성되어 있는 경우엔
- ▲ 의 부분은 내부측( 별도의 )이스케이프가 발생한다.
- 이스케이프 처리된 ▲을 포함하여 ● 전제의 에스케이프를 행한다.
이걸로 괜찮겟지만, 어느 한쪽이라도 방심한다면 xss 취약성이 발생해 버린다.
예를 들어 아래와같은 스크립트 ( ▲는 입력데이터 ) 가 있다고 치자1<input type="text" onmouseover="alert('入力は ▲▲▲ です');">cs
여기서1▲▲▲ = "');alert(document.cookie);// "cs
를 입력한다면 스크립트 전체에서는 아래와 같이 된다 ( 보기 쉽도록 개행을 추가하였다 )12<input type="text" onmouseover="alert('入力は ');alert(document.domain);// です');">cs
즉 별도의 스크립트를 넣는 것이 가능하단 것이다, 거기에 위에 나오는 싱글쿼터를 문자 참조 ( Y) 에 변환하여도 XSS 대책으론 사용할 수 없다.
javascript의 문자열 리터럴 룰에 따라 에스케이프 처리를 해야만한다.
스크립트가 script 태그에 의해 기억되는 경우
이 경우에는 아래와 같은 구조가 된다 ( ●가 스크립트 )1<SCRIPT type="text/javascript">●●●●</SCRIPT>cs 따라서 javascript로서의 에스케이프를 실시한뒤에 스크립트의 종단에 대해 이스케이프를 실시할 필요가 있다.
그러나 스크립트 요소내에서는 문자참조에 대한 이스케이프는 불가능하기에 종단문자열을 별도의 문자열로 치환하는 대책이 필요하다.
W3C에 의하면 스크립트의 종단은 </[a-zA-Z] 이다. 즉 </의 뒤에 영문자가 연속하여 나타날경우 스크립트의 종료이지만,
IE/FireFox/Opera와 같은 주요 브라우저에서 테스트해본 바에 의하면 </SCRIPT>가 아니라면 종단으로 간주하지 않았다.
스크립트 대그의 요소중에는 javascript의 문법은 감지하지 않기 떄문에, 혹여나 문자열 릴터럴중에 </script> 가 있다고 하여도 그 지점에서
스크립트의 종료로 간주한다. 이 성질을 이용한 XSS 가 가능하다.
아래와 같은 스크립트가 있다고 치자 ( △ 는 입력 데이터 )1<script>alert("入力データは▲▲▲です");</script>cs
여기서1▲▲▲ = "</script><script>alert(document.cookie);//"cs
를 입력하면, 스크립트 전체는 아래와 같이된다 ( 보기 쉽게하기 위하여 개행을 추가하였다 )12<script>alert("入力データは</script> // 構文エラーで実行されない<script>alert(document.cookie);//です");</script> // 実行されるcs
이 경우 혹여 더블쿼터의 javascript로서 이스케이프를 실시한다고 하여도 XSS 는 성립된다. 통상 이것을 의식하지 않는 경우가 많기 때문에 주의할 필요가 있다.
대책으로서는 W3C의 HTML 4.0 1사양 B.3.2에 의거한대로 문자열 리터럴에 </[a-zA-Z]에 상응하는 문자열이 들어오는 경우 <\/[a-zA-Z] 에 교환해서 처리한다.
( 앞서 기술한 것과 같이 HTML의 이스케이프가 아니다 ) 여기서 현실의 브라우저는 스크립트의 종단으로서 </script>만을 인식한다고 하여도
대책은 안전하다고 판단하고, 좀더 광범위적으로 W3C의 규칙에 준수하여 두는 것이 중요하다
현실적으론 어떻게 하는것이 좋을까
질문자의 질문에 의거하여 본질적으로는 어떻게 해야할까에 대하여 설명해 왔지만, 이미 봐온것과 같이 입력값의 이스케이프를 제대로 이해하고, 버그 없이 실시하는것은 꽤나 번거롭다.
안전한 Web사이트의 작성방법 개정 제2판에는12<script>...</script> 要素の内容を動的に生成しないようにするcs (*역: <script>...</script>요소의 내용을 동적으로 생성하지않도록 한다. )
와 같은 주의사항이 있지만, 이벤트 핸들러에 관한 주의는 없다. 필자의 입장으로선 어떤 경우에든 스크립트의 내용을 동적생성하는 것을 피하는 것을 가이드 라인으로서 제안하고 싶다.
구체적으로는 파라메터 부분을 HTML 의 hidden field 로서 정의하고 ,스크립트로부터 참조하는 형식으로 한다면 좋다.
그렇게 한다면 script는 고정된 상황에서 동적인 파라메터를 넘겨주는것이 가능하다
물론 hidden field의 속성값을 이스케이프 처리하는 것은 잊지 말도록..- 결론
이 글을 쭉 읽고, 번역하면서 생각해본 결과 XSS 대응이라는거 자체가 스크립트 대응이니까 크게 어려운 부분은 없는데
글쓴이가 적어 둔대로 급하게 코딩하다보면 늘상 잊기 쉽다.
나도 몇번을 대응하는데.. 신규 페이지 만들때마다 발견된다고 연락온다.
쩝...
반응형'Technique > WEB' 카테고리의 다른 글
[ 펌 ] user-agent string 의 역사 (0) 2016.12.30 웹사이트 크롤링과 인덱싱, robots.txt (0) 2016.12.21 [ 펌 ] HTML 코딩 팁 (0) 2016.09.19 XXE ( Xml eXternal Entity ) 문제 (0) 2016.09.06 [ CSS ] 크롬에서 input 박스 테두리 지우기 (0) 2016.03.11