XSS(Cross Site Scripting)란?
공격자에 의해 작성된 스크립트가 다른 사용자에게 전달되는 것으로 이용자를 식별하기 위한 세션 및 쿠키 정보를 탈취하여 임의의 기능을 실행할 수 있는 해킹기법
→ Cross Site Scripting의 약자인 CSS는 이미 스타일시트 언어인 Cascading Style Sheets의 약자로 사용되기 때문에 XSS를 사용
이러한 XSS는 발생 형태에 따라서 아래와 같이 다양한 종류로 구분됩니다.
- Stored XSS : XSS에 사용되는 악성 스크립트가 서버에 저장되고 서버의 응답에 담겨오는 XSS
- Reflected XSS : XSS에 사용되는 악성 스크립트가 URL에 삽입되고 서버의 응답에 담겨오는 XSS
- DOM-based XSS : XSS에 사용되는 악성 스크립트가 URL Fragment에 삽입되는 XSS (Fragment는 서버 요청/응답에 포함되지 않음)
이 외에도 여러 XSS가 존재하지만 해당 포스팅에서는 위의 3가지 종류에 대해 설명하겠습니다.
Stored XSS
Stored XSS 공격이란 악성 스크립트가 서버 내에 존재하여 이용자가 작성된 악성 스크립트를 조회할 때 발생하며 서버에 저장되는 형태이기에 저장형 XSS라고 합니다.
주로 웹 사이트의 방명록이나 게시판 등에 사용될 수 있으며 사용자가 방명록이나 게시판에 방문하여 클릭 시 스크립트 코드가 실행되고 이를 통해 세션, 쿠키를 공격자에게 전달됩니다.
게시판에 자바스크립트 코드를 포함하여 글 작성
작성된 글 조회 시
작성된 글의 스크립트가 코드로 실행되는 것을 확인 가능 → 사용자의 쿠키값과 같은 정보를 공격자의 서버로 전송시키는 악성 스크립트 코드가 작성되어 있는 경우 XSS로 인한 피해가 발생하게 됩니다.
Stored XSS 대응방안
PHP의 경우 htmlspecialchars 함수를 사용하여 특정 문자열을 HTML 엔티티로 치환할 수 있습니다. 이를 사용하여 게시글을 저장하기 전에 메서드를 통해 치환을 하게 되면 문자열을 그대로 출력하게 되어 스크립트 코드가 실행되지 않습니다.
$title=htmlspecialchars($_POST['title']);
$content=htmlspecialchars($_POST['content']);
작성된 글을 저장하는 PHP 코드에 htmlspecialchars 함수 사용 시
스크립트 코드를 작성하여도
해당 글을 조회하였을 때 문자열을 그대로 출력하여 스크립트 코드로 실행되지 않게됩니다.
이를 사용하면 XSS를 대응할 수 있지만 tistory와 같이 HTML 에디터를 사용하는 경우 HTML 태그가 그대로 출력되면 안 됩니다.
이때 화이트 리스트 필터링과 블랙리스트 필터링을 사용할 수 있는데요. 화이트 리스트 필터링이란 특정 태그만 허용하는 방법이고, 블랙 리스트 필터링이란 특정 태그의 사용을 금지하는 방법으로 php의 str_ireplace 함수를 통해 아래와 같이 추가하게 되면 stript라는 스크립트 태그를 사용 시 공백으로 바뀌게 됩니다.
$content=$_POST['content'];
$content=str_ireplace('script',' ',$content);
필터링을 사용한 script 태그와 HTML의 h1 태그를 함께 사용하여 글 작성 시
script 태그는 공백으로 치환되고 h1 태그는 적용되는 것을 확인할 수 있습니다.
하지만 블랙리스트 필터링의 경우 우회할 수 있는 방법이 너무 다양하기 때문에 보안적으로 취약하다는 단점이 있으며, 화이트 리스트 필터링의 경우 허용해야 하는 태그와 문자를 하나하나 지정하는 것이 비효율적이라는 단점이 있는데요. 따라서 실제로 잘 사용되지 않는 방법입니다. (HTML 에디터 사용의 경우 어떤 대응이 더 있는지는 추후에 공부하여 포스팅하도록 하겠습니다.)
Reflected XSS
Reflected XSS 공격이란 악성 스크립트가 이용자의 요청 내에 존재하여 이용자가 악성 스크립트가 포함된 요청을 보낸 후 응답을 출력할 때 발생하며 입력된 스크립트가 마치 반사되는 것처럼 동작하기 때문에 반사형 XSS라고 합니다.
주로 이메일, 게시판, SNS 등 링크를 남길 수 있는 곳에서 사용되며 공격자가 걸어놓은 악성 링크를 클릭하게 되면 이용자는 공격 스크립트 코드가 삽입된 사이트로 이동되고 입력된 스크립트가 반사되어 그대로 웹 사이트에 출력되는 방식입니다.
즉, 공격자가 URL 주소 뒤에 붙는 쿼리에 악성 스크립트를 작성하여 전달하는 것이죠.
그렇게 웹 페이지를 읽은 웹 브라우저는 자동으로 스크립트를 실행하고 세션, 쿠키를 공격자에게 전달하게 됩니다.
실습을 위해 게시글을 검색할 수 있는 기능을 추가하여 게시글을 검색할 시
검색한 내용을 출력하고 해당 결과를 가져오는 것을 확인할 수 있는데요.
존재하지 않는 글을 검색한 경우에도 검색한 단어와 검색 결과가 없다는 문구가 출력되도록 하였고 해당 기능에 취약점이 존재한다면
위와 같은 스크립트 코드를 검색어로 검색할 시
스크립트 코드가 실행되어 Reflected XSS를 시도할 수 있었습니다.
Reflected XSS 대응 방안
입력 값 제한
정규표현식을 사용하여 검색할 때 영어, 한글, 숫자, 공백만 사용할 수 있도록 입력 값을 제한하여 태그에 사용되는 특수문자를 사용하지 못하도록 하는 방법입니다.
<script>
function search_check(){
var search=document.getElementByName('search')[0].value;
var regex=/[ㄱ-ㅎ가-힣a-zA-z0-9\s]+$/;
if(!regex.test(search)){
alert("특수 문자는 검색이 불가능 합니다.");
return false;
}
}
</script>
입력 값 치환
php의 경우 위에서 설명한 str_replace 함수를 사용하여 특수 문자를 엔티티로 치환해 주어 출력하는 방법입니다.
str_replace 함수뿐만 아니라 htmlspecialchars 함수를 사용하여 문자열 전체를 그대로 출력할 수도 있습니다.
$search_con=str_ireplece('>','>',$search_con);
$search_con=str_ireplece('>','<',$search_con);
$search_con=htmlspecialchars($_GET['search']);
위와 같이 엔티티로 치환되어 출력이 되는 것을 확인할 수 있습니다.
Stored XSS와 Reflected XSS의 차이점
Stored XSS와 Reflected XSS 모두 웹 브라우저에서 스크립트를 실행했다는 것은 동일하지만 웹 서버에 스크립트를 저장했다가 출력되어 실행하는 Stored XSS와 다르게 Reflected XSS는 단순 출력된다는 차이점이 존재합니다.
DOM Based XSS
DOM Based XSS 공격이란 악성 스크립트가 URL Fragment에 삽입되는 XSS 입니다.
이때 DOM이란 HTML의 문법은 태그의 집합으로 구성되어 있고 이러한 태그들은 트리 구조로 객체가 형성되는데 이 트리 구조의 집합을 부르는 것입니다. 스크립트를 사용하면 DOM 문서에 접근할 수 있는데 이를 통해 웹 페이지의 콘텐츠가 동적으로 변경되는 것입니다.
DOM Based XSS 대응 방안
DOM Based XSS의 경우도 앞서 설명한 Stored XSS, Reflected XSS와 같이 입력값을 HTML 엔티티로 출력하는 방법이 사용될 수 있습니다.
또한 CSP를 사용하여 서버 관리자가 브라우저에서 실행 가능한 스크립트의 유효한 소스로 간주해야 하는 도메인을 지정하여 XSS가 발생할 수 있는 벡터를 줄이거나 제거할 수 있습니다. 이는 HTTP 헤더에 추가하여 적용하거나, meta 태그의 속성으로 정의하여 사용할 수 있습니다.
DOM Based XSS와 Reflected XSS의 차이점
DOM Based XSS와 Reflected XSS 모두 동적 페이지를 구성하는 과정 상에서 발생되는 것은 동일합니다.
하지만 Reflected XSS는 서버 측에서 동적 페이지를 구성하는 환경에서 발생되지만 DOM Based XSS는 클라이언트 측에서 사용자 입력 값을 통해 동적 페이지를 구성하는 환경에서 발생하기 때문에 요청이 서버로 전송되지 않고 클라이언트 브라우저에서 공격이 이루어진다는 차이점이 존재합니다.
Reflected XSS은 입력값이 서버에서 파싱 되어 처리 후 응답을 해줄 때 입력값 검증이 없어서 터지게 되며,
DOM Based XSS은 파라미터를 location.hash로 파싱 하여 서버까지 가지 않고 브라우저 단에서 파싱 한 데이터를 처리해서 그대로 보여줄 때 입력값 검증이 없어서 터지게 됩니다.
'Web > Web Hacking' 카테고리의 다른 글
NoSQL Injection (0) | 2024.09.07 |
---|---|
XXE External Entities (0) | 2024.09.06 |
File Download Vulnerability (0) | 2024.09.06 |
File Upload Vulnerability (0) | 2024.09.06 |
SQL Injection (1) (0) | 2024.09.06 |