본문 바로가기
개발/ETC

CSP - Content Security Policy를 통한 XSS 방어

by 설이주인 2024. 2. 20.

XSS 방어 작업을 진행하면서 특정 URL이 제대로 막히지 않고 script를 실행하는 상황이 발생하여 수많은 삽질 끝에...

CSP로 작업한 부분을 작성해둔다.

 

문제가 된 구문

http://localhost:80/[uri]?page=1&nyx99"><script>alert("이건어떠냐메롱")</script>vjmujrnir5t=1

 

 

XSS는 무엇인가?

https://www.keycdn.com/blog/x-xss-protection

 

X-XSS-Protection - Preventing Cross-Site Scripting Attacks - KeyCDN

Learn how the X-XSS-Protection HTTP response header can help better protect your website's visitors against common cross-site scripting (XSS) attacks.

www.keycdn.com

 

 

그럼 CSP는?

https://www.keycdn.com/support/content-security-policy

 

Content Security Policy - KeyCDN Support

A Content Security Policy, or CSP, is an additional layer of security delivered via an HTTP header which defines sources that are approved for the browser.

www.keycdn.com

https://developer.mozilla.org/ko/docs/Web/HTTP/CSP

 

컨텐츠 보안 정책 (CSP) - HTTP | MDN

콘텐츠 보안 정책 (CSP)는 교차 사이트 스크립팅(XSS)과 데이터 주입 공격을 비롯한 특정 유형의 공격을 탐지하고 완화하는 데 도움이 되는 추가 보안 계층입니다. 이러한 공격은 데이터 절도에서

developer.mozilla.org

 

요약 :

This policy helps prevent attacks such as Cross Site Scripting (XSS) and other code injection attacks by defining content sources which are approved thus allowing the browser to load them.

Without a CSP, the browser simply loads all files on a page without considering the source which could be harmful. This puts both the site and it's visitors at risk of malicious activity.

 

 

 

Supported directives - Setting

  • default-src :  Define loading policy for all resources type in case of a resource type dedicated directive is not defined (fallback), / src로 끝나는 모든 리소스의 기본 동작을 설정
  • script-src  :  Define which scripts the protected resource can execute, / Javascript 태그 관련 권한과 출처 설정
  • object-src  :  Define from where the protected resource can load plugins / Flash와 같은 위험한 플러그인 비활성화
  • style-src  :  Define which styles (CSS) the user applies to the protected resource, / 스타일시트 관련 권한과 출처 설정
  • img-src  :  Define from where the protected resource can load images, / 이미지를 로드할 수 있는 출처 설정
  • media-src  :  Define from where the protected resource can load video and audio,
  • frame-src  :  Define from where the protected resource can embed frames,
  • frame-ancestors  :  Specifies valid parents that may embed a page using <frame>, <iframe>, <object>, <embed>, or <applet>.
  • font-src  :  Define from where the protected resource can load fonts,
  • connect-src  :  Define which URIs the protected resource can load using script interfaces,
  • form-action  :  Define which URIs can be used as the action of HTML form elements,
  • sandbox  :  Specifies an HTML sandbox policy that the user agent applies to the protected resource,
  • script-nonce  :  Define script execution by requiring the presence of the specified nonce on script elements,
  • plugin-types  :  Define the set of plugins that can be invoked by the protected resource by limiting the types of resources that can be embedded,
  • reflected-xss  :  Instructs a user agent to activate or deactivate any heuristics used to filter or block reflected cross-site scripting attacks, equivalent to the effects of the non-standard X-XSS-Protection header,
  • report-uri  :  Specifies a URI to which the user agent sends reports about policy violation
  • child-src : 페이지 내에 삽입된 프레임 컨텐츠에 대한 출처 설정
  • base-uri : 페이지의 <base> 태그에 나타날 수 있는 URL을 설정

 

구성 값

  • none : 모든 출처를 허용하지 않음
  • self : Origin 내에서 로드하는 리소스만 허용
  • unsafe-inline : 인라인 코드의 사용을 허용
  • unsafe-eval : eval과 같은 텍스트-자바스크립트 변환 메커니즘의 사용을 허용
  • nonce-<base64-value> : nonce 속성을 설정하여 예외적으로 인라인 코드를 사용합니다. <base64-value>는 반드시 요청마다 다른 난수 값으로 설정해야 합니다. 해당 출처를 설정하면 unsafe-inline 은 무시됩니다. 안전하지 않은 인라인 지시어를 사용하지 않도록 할 수 있습니다

 

설정 검증

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

 

CSP Evaluator

 

csp-evaluator.withgoogle.com

 

그럼 구성은 어떻게? 작성할 것인가?

script단에서 meta-data 작성 또는 서버에서 response에 담아서 전달해도 된다. 작업을 진행하면서 script단에 강제로 작성하면 그외의 function들에 인증작업을 진행해야하는 상황이 발생하여.. 사용자가 XSS 공격을 진행했을때 response에 해당 옵션을 추가하여 해당 페이지의 모든 script function을 막는 방식으로 진행했다.

 

<meta http-equiv="Content-Security-Policy" content="default-src 'self'">

<meta http-equiv="Content-Security-Policy" content="default-src * self blob: data: gap:;;
  style-src * 'self' 'unsafe-inline' blob: data: gap:;
  script-src * 'self' 'https://*';
  object-src * 'self' blob: data: gap:;
  img-src * self 'unsafe-inline' blob: data: gap:;
  connect-src self * 'unsafe-inline' blob: data: gap:; frame-src * self blob: data: gap:;
  base-uri 'self'">

 

사용자가 이상한 요청(XSS)을 보냈는지 확인하고 flag를 설정 -> XSS의 요소가 존재하는것을 확인하면 response에 CSP 설정을 적용 후 사용자에게 ERROR 를 return 했다.

 

 

:89/temp/URL?page=1&nyx99%22%3E%3Cscript%3Ealert(%22%EC%B2%9C%EC%9E%AC%EA%B5%90%EA%B3%BC%EC%84%9C%22)%3C/script%3Evjmujrnir5t=1:43 
Refused to execute inline script because it violates the following Content Security Policy directive: "script-src * 'self' https://*". 
Either the 'unsafe-inline' keyword, a hash ('sha256-20Gq36ycvJLOP3+1YX5EuJxAgPsxc2H0E1u/RTTocAQ='), or a nonce ('nonce-...') 
is required to enable inline execution.

 

 


해당 작업을 진행하면서 한가지 고민이 있었다면... XSS 공격을 진행한 사용자에게 해당 script만 실행 안되고 다른 script function들은 정상적으로 작동해야하는 것인가? 에 대한 궁금증이 있었다. 하지만 해당 방식으로 script 또는 sql injection을 진행하는 사용자분들이 비정상적인 방식으로 사이트를 사용하신 부분이니 CSP를 통해서 script function들을 막는게 맞지 않을까 하는 생각이 들어서 위와 같이 진행했다.

 

+ ) 추가적으로 찾아보니 다른 분들은 spring security를 통해서 가볍게 해결하셨다... 만약에 security를 사용하는 상황이라면

위와 같은 방식으로 진행하지 않아도 괜찮을 듯하다.