본문 바로가기
정보 보안 해킹 공부/모의해킹

[드림핵] XSS, CSRF 등 공부

by 박나무 2022. 2. 21.
반응형
  • Cross Site Scripting (XSS)
    공격자의 입력값이 크로스 사이트의 자바스크립트 일부로 웹 브라우저에서 실행되는 취약점을 말합니다. 실행된 스크립트는 해당 사이트의 일부가 되어 SOP 제약 없이 사이트의 구조를 변경하거나 임의 HTTP 요청을 보낼 수 있습니다.
  • Cross Site Request Forgery (CSRF)
  • 비정상적으로 사용자의 의도와 무관하게 HTTP 요청을 보내는 것을 CSRF 공격이라 합니다. Simple Request나 HTML 엘리먼트라면 SOP의 제약을 받지 않는다는 점을 이용합니다.
  • Open Redirect
  • Redirect 기능을 악용해 피싱사이트로 접속을 유도하거나, 다른 취약점을 연계하여 사용자를 공격할 수 있습니다.
  • Click Hijacking
  • 공격자가 생성한 버튼, 이미지와 같은 엘리먼트를 정상적인iframe 위에 겹쳐 올려 UI를 스푸핑해 사용자 의도와는 다른 작업을 수행하게 하는 취약점입니다.
  • 악성 스크립트는 브라우저가 실행할 수 있는 웹 리소스를 말하며, 대표적으로 HTML, JS 등이 있습니다. 

 

XSS 취약점에 대한 정보를 공유할 때 alert 또는 prompt와 같은 메시지 창을 실행하는 이유는 XSS 취약점이 발생하였다는 점을 시각적으로 표현이 가능하기 때문입니다. 주로 메시지 창에는 해당 페이지의 domain을 확인하기 위해 document.domain을 인자로 전달합니다.

 

  • dreamhack.io에서 XSS 취약점으로 인해 자바스크립트의 alert(document.domain)코드가 실행된 화면 (예시)

Mitigations

XSS는 웹 서비스상에서 빈번하게 일어나는 취약점 중 하나이며 오래전부터 발생했던 취약점이기 때문에 이를 방어하기 위해 많은 방안들이 생겨났습니다.

브라우저 단에서 방어하는 기술뿐만 아니라 서버 내부에 저장하는 시점 혹은 저장된 데이터를 출력하는 시점에 입력 값을 올바르게 검증하는 방식으로 XSS를 방어해야 합니다. 아래는 방어 기술의 종류입니다.

  • Server-side Mitigations
  • HTTPOnly 플래그 사용
  • Content Security Policy 사용
  • X-XSS-Protection

사용자의 입력 값이 HTML 태그가 될 일이 없다면 꺽쇠 (<, >), 따옴표(", ')와 같은 특수 문자를 HTML Entity Encoding을 이용해 태그로 인식하지 않도록 수정(Escape) 할 수 있습니다.

 

만약 사용자 입력 값에 HTML 형태를 지원해야 한다면 화이트리스트 필터링을 해야합니다.

화이트리스트 필터링이란 허용해도 안전한 일부 태그, 속성을 제외한 모든 값을 필터링 하는 것을 의미합니다.

게시글을 운영하는데 있어서 img, video, a 태그만 필요하다면 해당되는 세 개의 태그를 제외한 모든 태그는 필터링하는 방식입니다.

 

사용자의 입력 값을 필터링 할 때 유의할 점은 요청의 URI Query 값이나 POST Body 값만 필터링하는 것이 아니라 User-Agent, Referer와 같은 헤더도 모두 포함하여 사용자로부터 입력된 값에 모두 적용해야 합니다.

Mozilla 에서 제작한 Bleach (https://github.com/mozilla/bleach) 라는 HTML 필터링 라이브러리를 추천합니다.

 

HTTPOnly Flag

Set-Cookie: session=sbdh1vjwvq; HttpOnly

HTTPOnly 플래그는 서버 측에서 응답 헤더에 Set-Cookie 헤더를 전송해 자바스크립트에서 해당 쿠키에 접근 하는 것을 금지합니다. 이는 쿠키를 생성할 때 옵션으로 설정 가능하며, XSS 취약점이 발생하더라도 공격자가 알아낼 수 없는 쿠키 값이기 때문에 세션쿠키를 설정할 땐 HTTPOnly 플래그를 적용하는 것을 권장합니다

 

Content Security Policy (CSP)

CSP는 응답 헤더나 meta 태그를 통해 아래와 같이 선언해서 사용할 수 있으며, 각각의 지시어를 적용하여 사이트에서 로드하는 리소스들의 출처를 제한할 수 있습니다.

Content-Security-Policy: <지시어>; ...

그러나 신뢰할 출처를 선언하는 방식인만큼 신뢰하는 CDN 서버가 해킹당하면 무력화되는 단점이 존재합니다.

 

script-src 'nonce-noncevalue13b739d8ea12' 와 같이 script-src를 이용해 nonce (랜덤) 값을 설정하고 HTML 태그를 이용해 자바스크립트를 실행할 때는 반드시 서버에서 생성된 nonce 값을 알아야만 실행될 수 있도록 할 수 있습니다

 

 

Request 값과 Response를 비교해 판단하는 것으로 보아 Reflected XSS 공격을 막는 데에 적합한 방어 방법임을 알 수 있으며, 다른 유형의 XSS 공격을 방어할 수 없습니다.

 


Cross Site Request Forgery(CSRF)

비정상적으로 사용자의 의도와 무관하게 다른 사이트에 HTTP 요청을 보내는 것을 CSRF 공격이라 합니다.

 

Mitigation

CSRF 공격을 막기 위해서는 보통 두 가지 방법을 사용합니다.

  1. 세션 쿠키 대신 커스텀 헤더를 사용하여 사용자 인증
    • 사용자 인증만을 위한 헤더를 추가합니다. (e.g. Authorization)
  2. 공격자가 예측할 수 없는 파라미터 추가 및 검증
    • Same Origin에서만 접근 가능한 데이터를 삽입합니다.
      • CSRF Token
    • CAPTCHA
    • 정상적인 사용자만 알고있는 기존의 값을 검증합니다. (예: 현재 비밀번호)

SameSite Cookie

위 두가지 방법은 서버 사이드에서 추가적인 검증을 통해 CSRF를 방어하는 방법입니다. 서버 코드에 검증 로직이 추가되는 방식이라 어쩔 수 없는 오버헤드가 발생하게 됩니다.

CSRF 공격이 가능한 이유를 다시 한번 생각해보면 웹 브라우저가 크로스 사이트, 즉 다른 사이트로부터 온 요청에 쿠키를 함께 전송한다는 것입니다.

웹 브라우저는 다른 사이트로부터 온 요청에 쿠키를 삽입할지를 SameSite 쿠키 설정을 보고 판단합니다.

쿠키에는 key=value를 포함해 추가적인 설정 값도 함께 저장합니다. 기존에는 Domain, Expires, Path 등만 포함했지만 새롭게 SameSite 옵션이 추가되었습니다.

크로스 사이트에서 출발한 요청에 제한적으로 쿠키를 포함시키게 하는 옵션입니다. 총 세 가지(Strict, Lax, Normal) 값을 설정할 수 있습니다.

기본적으로 Strict는 모든 크로스 사이트에서 출발한 요청에 해당 쿠키를 삽입하지 않습니다. Lax는 Link, Prerender, Form GET을 제외한 요청에는 쿠키를 삽입하지 않고 Normal 옵션은 기존과 동일하게 모든 요청에 쿠키를 삽입합니다. 해당 옵션을 설정하지 않을시 Normal과 동일한 권한을 가집니다.


Open Redirect

Redirect(리다이렉트)는 사용자의 Location(위치)를 이동시키기 위해 사용하는 기능 중 하나입니다.

리다이렉트가 사용되는 코드는 아래와 같이 HTTP Response의 300번대 영역을 통해 이동하거나, 자바스크립트를 통해 이동하는 경우가 대부분이며 이때 이동하는 주소가 공격자에 의해 변조될 경우 Open Redirect(오픈 리다이렉트) 취약점이 발생하게 됩니다.


Mitigation

 


Click Jacking

Click Jacking(클릭 재킹)은 웹 브라우저 화면에 출력되는 내용에 HTML, CSS, JS 등과 같이 화면 출력에 영향을 미치는 요소들을 이용하여 사용자의 눈을 속여 사용자의 클릭을 유도하는 공격 방법입니다. 외부 페이지 리소스를 불러올 수 있는 태그 엘리먼트(<frame>, <iframe>, <object>, <embed>, <applet>)를 사용합니다.

사용자의 클릭을 유도하는 페이지를 구성한 후, 그 페이지 위에 iframe 등의 태그로 누르게 할 페이지를 로드합니다. 그리고 CSS opacity(요소의 투명도를 조정)와 같이 사용자의 눈에는 보이지 않도록 숨겨 놓는 방법 등을 이용하여 공격을 할 수 있습니다. 사용자가 보는 페이지와 실제로 누르는 곳에 차이가 있는 이유는 iframe 태그가 웹 브라우저 상에서는 더 앞에 위치해 있기 때문입니다.

오른쪽 탭은 클릭 재킹을 간단하게 구현한 예시이며, 아래 탭은 예시의 코드 일부분 입니다.

이런거 많이 본 것 같다. 끄려고 하면 뭔가 또 나타나고 또나타나고... 클릭재킹


Mitigation

와 힘들었다~

이해 안되는 거 찾아보면서 하니 시간이 좀 걸렸다;

뿌듯~

반응형

댓글