홈페이지 운영팁

크로스 사이트 스크립트(XSS)

2023-12-14


 

크로스 사이트 스크립트(XSS)



가. 개요

 - 웹 애플리케이션을 사용해서 다른 최종 사용자의 클라이언트에서 임의의 스크립트가 실행되는 취약점



나. 위험성

 - 웹 어플리케이션에서 사용자 입력 값에 대한 필터링이 제대로 이루어지지 않을 경우, 

공격자가 입력이 가능한 폼(웹 브라우저 주소입력 또는 게시판 등)에 악의적인 스크립트를 삽입하여 사용자 세션 도용, 악성코드를 유포할 수 있습니다.



▲ 크로스 사이트 스크립트 취약점



다. 점검방법

 - 게시판에 글쓰기와 같이 단문이상의 입력 가능한 부분에 실행 가능한 형태의 스크립트 태그

(‘> <script> alert(‘XSS’); </script>, “> <script> alert(‘XSS’); </script> 등) 입력이 가능한지 확인합니다.


 - 다음 인코딩을 적용하여 ①에서 입력한 값을 전송해서 입력이 가능한지 확인합니다.

URL인코딩-’(%27), “(%22), ((%28), )(%29), /(%2f), ;(%3b), <(%3c), >(%3e), space(%20) 


- 입력한 스크립트 태그가 브라우져 화면에 표시되어 실행 가능한지 확인합니다. 



라. 점검 결과

 - GET으로 전송되는 URL 파라미터에 스크립트 등록시 스크립트가 발생하여 취약합니다.  


 


마. 취약점 조치 방법

 - 사용자 입력값에 대한 Positive 필터링을 구현하여 XSS 공격으로부터 웹 응용시스템을 방어합니다. 

응용시스템 차원에서 HTTP 헤더, 쿠키, 쿼리 스트링, 폼 필드, 히든 필드 등의 모든 인자들에 대해 허용된 유형의 데이터만을 받아들이도록 입력값 검증을 실시하는 방법입니다.

해당 검증 방법은 현재의 콘텐츠를 파악하여 필터링을 수행하려고 해서는 안 됩니다.


 - 콘텐츠의 종류는 상당히 많으며 필터링을 우회하기 위한 인코딩 방식에도 여러 가지가 있습니다. 

일반적으로 공격자는 <script> 태그를 이용해 공격하므로 <script> 문자열이 들어오면 

<xxscript>나 다른 문자로 변환해 스크립트 태그가 실행되지 않도록 설정해야 합니다.


 - 공격자는 <script>태그 외에 다양한 기법을 이용해 공격하기 때문에 아래표와 같이 필터링을 할 것들을 정해서 막는 ‘negative defence’가 아닌 

입력 가능한 문자만 정한 뒤 다른 문자가 들어왔을 때 전부 막는 ‘positive defence’를 하는 것이 좋습니다.


 - 입력값의 필터링은 명시적으로 허용되는 것을 지정하여 받아들이는 방식(positive Filtering)의 보안 정책을 강하게 권고합니다. 

허용되지 않는 것을지정하는 방식(negative Filtering)의 보안 정책이나 공격 패턴(시그너처)에 기반한 보안 정책은 유지 보수가 힘들며 불완전합니다.


 - 사용자 입력값에 대한 표시 치환은 사용자 입력으로 사용 가능한 문자들을 정해놓고, 그 문자들을 제외한 나머지 모든 문자들을 필터링 하는 것을 말합니다. 

필터링 해야 하는 대상은 GET 질의 문자열, POST 데이터, 쿠키, URL, 그리고 일반적으로 브라우저와 웹 서버가 주고받는 모든 데이터를 포함합니다. 

아래는 특수문자에 대한 Entity 형태를 표시한 것입니다.  



 

 - 게시판에서 HTML 포맷을 사용할 수 없도록 설정합니다. 

 - 필요한 경우 모든 HTML을 사용하지 못하게 설정 후 필요한 HTML tag만 쓸 수 있도록 설정합니다.


 

<%

Set objDBConn = Server.CreateObject("ADODB.Connection")' 게시물 읽기

Set objRs = Server.CreateObject("ADODB.RecordSet")

objDBConn.Open "board", "user", "passwd"

query = "SELECT id, name, memo FROM board_tbl WHERE id=1"

objRs.Open query, objDBConn memo = objRs("memo")

Response.write "게시물 내용-" & memo & "<BR>"' DB에서 게시판의 내용 출력


 △ 취약한 프로그래밍의 예 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>"


 안전한 프로그래밍의 예 ASP 



$query = "SELECT id, name, memo FROM board_tbl WHERE id=1";// 게시물 읽기

$result = mysql_query($query, $connect);

while($row = mysql_fetch_array($result))

$name = $row[name];

$memo = $row[memo];

echo "게시물 내용-" . $memo . "<BR>\n";// DB에서 게시판의 내용을 출력


 취약한 프로그래밍의 예 PHP 



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

if($use_html == 1) // HTML tag를 사용하게 할 경우 부분 허용

$memo = str_replace("<", "&lt;", $memo);// HTML TAG를 모두 제거

$tag = explode(",", $use_tag); for($i=0; $i<count($tag); $i++) // 허용할 TAG만 사용 가능하게 변경

$memo = eregi_replace("&lt;".$tag[$i]." ", "<".$tag[$i]." ", $memo);

$memo = eregi_replace("&lt;".$tag[$i].">", "<".$tag[$i].">", $memo);

$memo = 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";


  안전한 프로그래밍의 예 PHP 


 

Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);

Statement stmt = conn.createStatement(); ResultSet rs=null;

String query = "SELECT memo FROM board_tbl WHERE id=1"; rs = stmt.executeQuery(query);

String memo = rs.getString(1); out.print("게시물 내용-" + memo + "<BR>");


 취약한 프로그래밍의 예 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>");


 안전한 프로그래밍의 예 JSP



바. 피해사례

가) OO대학은 게시판의 댓글기능이 공개되어 있꼬 [HTML 편집기] 기능을 이용하여 스크립트 코드의 삽입이 가능

 


 

- 삽입한 스크립트가 동작함

 


 

나) OO대학의 아이디/학번 조회 URL에 스크립트를 삽입하면 스크립트가 동작함


주소
인천 남동구 선수촌공원로 5, C동 912호
(구월동, 구월테크노밸리)
대표번호
1566-8667
운영시간
평일 오전 9:30 ~ 오후 6:30

사이트 하단 정보

카카오톡 카카오스토리 블로그 인스타그램 페이스북
  • 상호 : 에이디커뮤니케이션
  • 대표 : 우세진
  • 사업자등록번호 : 130-39-21061
  • 고객센터번호 : 1566-8667
  • 팩스 : 02--6924-8414

  • 소프트웨어 사업자 : B11-43345
  • 이메일 : master@ad-com.kr
  • 주소 : 인천 남동구 선수촌공원로 5, C동 912호(구월동, 구월테크노밸리)