크로스 사이트 스크립트(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, "<p>", "<p>") memo = replace(memo, "<P>", "<P>") memo = replace(memo, "<br>", "<br>") memo = replace(memo, "<BR>", "<BR>") Else' HTML tag를 사용하지 못하게 할 경우 memo = Server.HTMLEncode(memo)' HTML encoding 수행 memo = replace(memo, "<", "<") memo = replace(memo, ">", ">") 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("<", "<", $memo);// HTML TAG를 모두 제거 $tag = explode(",", $use_tag); for($i=0; $i<count($tag); $i++) // 허용할 TAG만 사용 가능하게 변경 $memo = eregi_replace("<".$tag[$i]." ", "<".$tag[$i]." ", $memo); $memo = eregi_replace("<".$tag[$i].">", "<".$tag[$i].">", $memo); $memo = eregi_replace("</".$tag[$i], "</".$tag[$i], $memo); else // HTML tag를 사용하지 못하게 할 경우 // $memo = htmlspecialchars($memo); // htmlspecialchars() 사용시 일부 한글이 깨어지는 현상이 발생 할 수 있음 $memo = str_replace("<", "<", $memo); $memo = str_replace(">", ">", $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("<","<");//HTML tag를 모두 제거 memo = memo.replaceAll(">",">");// 허용할 HTML tag만 변경 memo = memo.replaceAll("<p>", "<p>"); memo = memo.replaceAll("<P>", "<P>"); memo = memo.replaceAll("<br>", "<br>"); memo = memo.replaceAll("<BR>", "<BR>"); else // HTML tag를 사용하지 못하게 할 경우 memo = memo.replaceAll("<","<"); memo = memo.replaceAll(">",">"); out.print("게시물 내용-" + memo + "<BR>"); |
△ 안전한 프로그래밍의 예 JSP
바. 피해사례
가) OO대학은 게시판의 댓글기능이 공개되어 있꼬 [HTML 편집기] 기능을 이용하여 스크립트 코드의 삽입이 가능
- 삽입한 스크립트가 동작함
나) OO대학의 아이디/학번 조회 URL에 스크립트를 삽입하면 스크립트가 동작함