2009-04-23 3 views
17

가끔은 서버 측에서 인라인 JavaScript 코드에 포함 할 문자열을 생성합니다. 예를 들어 ASP.NET에서 "UserName"을 생성해야합니다. 그러면 그것은 마치 보입니다. 사용자가 그것은 XSS 취약점입니다javascript 문자열에 "<" and ">"문자를 "이스케이프"해야합니까?

</script><script>alert('bug')</script></script>

될 그/그녀의 이름을 가질 수 있기 때문에

<script> 
    var username = "<%UserName%>"; 
</script> 

이는 안전하지 않습니다.

그래서, 기본적으로, 코드가 있어야한다 : JavascriptEncode이 무엇

<script> 
    var username = "<% JavascriptEncode(UserName)%>"; 
</script> 

가 charater을 추가하는 것입니다 "\" "/"와 " '"와 "" "그래서, 출력 HTML 전에. 처럼 var에 사용자 이름 = "</스크립트> 경고 (\ '버그 \') </script> </스크립트>";. 이

브라우저 "해석되지 않습니다/script> "을 스크립트 블록의 끝으로 사용하십시오. 따라서 XSS는 피해졌습니다.

그러나 여전히 "<"및 ">"이 있습니다. 이 두 문자를 이스케이프 처리하는 것이 좋습니다. 우선, "<"을 "& lt;"으로 변경하는 것이 좋습니다. 및 ">"~ "& gt;" 이리. 그리고 "<"을 "\ <"으로 변경하고 ">"을 "\>"으로 변경하는 것이 모든 브라우저에서 인식되는지 확신 할 수 없습니다. "<"및 ">"에 대한 추가 인코딩은 필요하지 않습니다.

이 문제에 대한 제안 사항이 있습니까?

감사합니다.

답변

16

문제는 사용하는 마크 업 언어에 따라 다른 답변이 있습니다.

HTML을 사용하는 경우 스크립트 요소가 CDATA를 포함하는 것으로 표시되므로 항목을 HTML로 나타내면 안됩니다.

XHTML을 사용하는 경우 명시 적 CDATA 마커가있는 CDATA로 나타내거나 엔티티로 표현할 수 있습니다.

XHTML을 text/html로 사용하는 경우 XHTML의 규칙을 따르지만 text/html 파서에서 계속 작동해야합니다. 이것은 일반적으로 명시적인 CDATA 마커를 사용하고 JavaScript에서 주석 처리하는 것을 의미합니다.

<script type="text/javascript"> 
// <![CDATA[ 
    … 
// ]]> 
</script> 

얼마전에 나는 the hows and whys of this에 대해 약간 썼습니다.

+1

그러나 CDATA 블록 내부의']''여전히'>'은'>'에 의해 repalce되어야합니다. 그래서'foo [bar [0]]> 1234'는'foo [bar [0]] < 1234' 또는'foo [bar [0]]> 1234'로 대체되어야합니다. 그렇지 않으면 CDATA 블록이 너무 일찍 닫힙니다. – Gumbo

+0

CDATA는 & 문자를 "&"을 의미하고 "엔터티의 시작"을 의미하지 않으므로 작동하지 않습니다. 만약 당신이 문자열을 표현할 필요가 있다면 "]]>"CDATA 안에서 나는 꽤 빠르다. CDATA 블록 밖에서 시작하기 위해 엔티티를 사용해야한다. – Quentin

+7

아니면 공백을 추가한다 :'foo [bar [0 ]]> 1234' - 또는 문자열의 일부인 'foo [bar [0]]'+ '> 1234''이거나 외부 .js 파일에 모든 스크립트를 포함하는 경우. – gnarf

13

아니요, <>을 HTML의 <script> 안에있는 HTML 엔터티를 사용하여 이스케이프해서는 안됩니다.

  • 를 사용하여 자바 스크립트 문자열 이스케이프 규칙 (\"\\\" 교체)
  • <script> 요소에서 탈출 방지하기 위해, <\/</의 모든 차례 나오는 대체합니다.

XHTML에서는 더 복잡합니다.

  • XML과, 당신은 탈출 자바 스크립트 문자열 외에도, 엔티티를 탈출 할 필요가 CDATA 블록을 사용하지 않는 (IE와 호환의 방식)으로 XHTML을 보내는 경우.
  • XHTML을 XML로 보내고 CDATA 블록을 사용하는 경우 엔티티에서 이스케이프 처리하지 말고 을 ]]]]><![CDATA[>으로 바꾸어 이스케이프 아웃을 방지하십시오 (자바 스크립트 문자열 이스케이프 외에도).
  • XHTML을 text/html (사람의 99 %가하는 것)으로 보내면 XML CDATA 블록, XML CDATA 이스케이프 및 HTML 이스케이프를 모두 사용해야합니다.
+5

+1. 사소한 단정 짓기 :' 문자열 다음에 공백 문자,'>'또는'/'만 있으면 각 시작 태그가 끝납니다.] (http://mths.be/etago) –

2

싼 쉬운 방법 : Encode의 인코딩 방식은 자바 스크립트와 호환 관련 \xABCD 표현으로 입력의 각 문자를 번역하는 것입니다

<script type="text/javascript"> 
    var username = "<%= Encode(UserName) %>"; 
</script> 

.

또 다른 저렴하고 쉬운 방법 :

<script type="text/javascript"> 
    var username = decodeBase64("<%= EncodeBase64(UserName) %>"); 
</script> 

당신은 ASCII를 처리하는 경우.

물론 pst은 엄격한 방법으로 머리에 못을 박았습니다.

+0

+1 또한이 솔루션 출력 소스 코드가 h4x0r로 보입니다! –