안녕하세요? 허니입니다. XSS/CSRF 취약점에 대해서 알아보고 대응 방법에 대해 알아보도록 하겠습니다. 사이버 해킹에 대해 공부하시는 학생이나 연구원 분이 계시면 도움이 될 것이라 생각합니다.


어플리케이션이 적절하게 검증하거나 제한하지 않고 사용자가 제공한 데이터를 브라우저가 전송한 페이지에 포함시킬 때 발생합니다. 특정한 동작의 전체과정이 예측 가능한 웹 어플리케이션에서 발생한다. 브라우저는 세션 쿠키와 같은 자격 증명 정보들을 자동으로 전송하기 때문에 공격자는 정상적인 요청과 구별할 수 없는 변조된 요청을 포함한 악성 웹 페이지를 만들 수 있습니다.

 

 일반적인 대응방법
적절한 출력 인코딩을 이용해 사용자 입력은 항상 브라우저에서 실행될 수 있는 활성 콘텐츠가 아닌 텍스트로 취급하도록 합니다. 신뢰할 수 없는 데이터가 포함될 수 있는 HTML(body, attribute, 자바스크립트, CSS, URL) 기반 데이터 전체를 어플리케이션 내에서 제한 처리를 해야 합니다. 정규화 및 디코딩으로 입력에 특수 문자가 필요한 경우 입력을 허용하기 전에 가능한 인코딩 된 모든 입력을 디코딩 해 길이, 문자, 포맷, 데이터 관련 업무 역할을 검증하도록 해야 합니다. XSS/CSRF에 사용되는 script 문장에 존재한 특수 문자를 메타캐릭터로 변환 시킵니다.

 

- 메타캐릭터 변환

<  ---------  &lt
>  ---------  &gt
(  ---------  &#40
)  ---------  &#41
#  ---------  &#35
&  ---------  &#38


- Contents 구문 사용

contents = Server.HTMLEncode(Request("contents"))

 

- Replace 구문 사용

content = ConvertTohtml(content)
content = Replace(content,"'","''")
content = replace(content ,"&","&amp;")
content = replace(content ,">","&gt;")
content = replace(content ,"<","&lt;")

 

- XST 공격 대응 방법

[Apache]
 Apache의 경우 httpd.conf 에서 아래와 같이 HTTP 메소드 제한.
 <Directory />
 <LimitExcept GET POST>
  Order allow,deny
  deny from all
 </LimitExcept>
 </Directory>

[IIS]
IIS의 경우 WebDAV를 중지하거나 URL Scan과 같은 툴을 사용하여 HTTP 메소드 제한
(http://technet.microsoft.com/en-US/security/cc242650.aspx#e)

[Tomcat]
WEB-INF\web.xml 에 아래와 같이 설정
<security-constraint>
   <web-resource-collection>
   <web-resource-name>Forbidden</web-resource-name>
       <url-pattern>/*</url-pattern>
       <http-method>HEAD</http-method>
       <http-method>PUT</http-method>
       <http-method>DELETE</http-method>
       <http-method>TRACE</http-method>
   </web-resource-collection>

 

   <auth-constraint>
       <role-name></role-name>
   </auth-constraint>
</security-constraint>

 

 개발 언어별 대응방법
- 보안코딩(ASP)

If use_html Then  // HTML tag를 사용하게 할 경우 부분 허용
memo = Server.HTMLEncode(memo)  // HTML tag를 모두 제거

 

// 허용할 HTML tag만 변경
memo = replace(memo, "&lt;p&gt;", "<p>")
memo = replace(memo, "&lt;P&gt;", "<P>")
memo = replace(memo, "&lt;br&gt;", "<br>")
memo = replace(memo, "&lt;BR&gt;", "<BR>")

Else  // HTML tag를 사용하지 못하게 할 경우
memo = Server.HTMLEncode(memo)  // HTML encoding 수행
memo = replace(memo, "<", "&lt;")
memo = replace(memo, ">", "&gt;")
End If

Response.write "게시물 내용-" & memo & "<BR>"

 

- 보안코딩(PHP)

$use_tag = “img,font,p,br”;  // 허용할 HTML tag

If($use_html == 1)  // HTML tag를 사용하게 할 경우 부분 허용
$memo = str_replace(“<”, “&lt;”, $meno);  // HTML tag를 모두 제거

$tag = explode(“,”, $use_tag);
for($i=0; $i<count($tag); $i++)  // 허용할 tag만 사용 가능하게 변경
$meno = eregi_replace(“&lt;”.$tag[$i].” “, “<”.$tag[$i].” “, $memo);
$meno = eregi_replace(“&lt;”.$tag[$i].”>“, “<”.$tag[$i].”>“, $memo);
$meno = eregi_replace(“&lt;/”.$tag[$i], “</”.$tag[$i], $memo);

else  // HTML tag를 사용하지 못하게 할 경우

// $memo = htmlspecialchars($memo);
// htmlspecialchars() 사용시 일부 한글이 깨어지는 현상이 발생할 수 있음

$memo = str_replace(“<”, “&lt;”, $memo);
$memo = str_replace(“>”, “&gt;”, $memo);

echo “게시물 내용-“.$memo.”<BR>\n”;

 

- 보안코딩(JSP)

If(use_html)  // HTML tag를 사용하게 할 경우 부분 허용
memo = memo.replaceAll(“<”, “&lt;”);  // HTML tag를 모두 제거
memo = memo.replaceAll(“>”, “&gt;”);

// 허용할 HTML tag만 변경
memo = memo.replaceAll(“&lt;p&gt;”, “<p>”);
memo = memo.replaceAll(“&lt;P&gt;”, “<P>”);
memo = memo.replaceAll(“&lt;br&gt;”, “<br>”);
memo = memo.replaceAll(“&lt;BR&gt;”, “<BR>”);

else  // HTML tag를 사용하지 못하게 할 경우
memo = memo.replaceAll(“<”, “&lt;”);
memo = memo.replaceAll(“>”, “&gt;”);

out.print(“게시물 내용-“ + memo + “<BR>”);



 

+ Recent posts