CSP?
CSP는 Content-Security-Policy의 약자이며, 하나의 보안 정책이다.
웹 페이지에서 사용될 수 있는 자원의 위치, 출처 등에 제약을 줄 수 있기 때문에, 자체적인 XSS 방어 정책과 곁들인다면 XSS를 매우 효과적으로 방어 할 수 있다.
CSP는 Content-Security-Policy HTTP 헤더에 추가하여 적용 할 수 있으며, html 페이지에서 <meta> 태그를 활용할 수도 있다.
<meta http-equiv="Content-Security-Policy" content="default-src 'self'">
SOP와 다르게 룰을 직접 설정하기 때문에, 잘못된 설정은 아무 의미도 없게 되어버릴 수도 있다는 것이다.
(= 정책에 따라 bypass 방법이 다양할 수 있다.)
따라서 csp를 올바르게 설정하였는지 검사해 볼 수 있는 사이트도 있으니 참고하도록 하자.
https://csp-evaluator.withgoogle.com/
CSP는 directive - value 형식으로 구성되어 있으며
자주등장하는 directive는 다음과 같다.
default-src | -src로 끝나는 모든 리소스의 기본 동작을 설정 |
img-src | 이미지를 로드할 수 있는 출처 설정 |
script-src | Javascript 태그 관련 권한과 출처 설정 |
style-src | 스타일시트 관련 권한과 출처 설정 |
child-src | 페이지 내에 삽입된 프레임 컨텐츠에 대한 출처 설정 |
base-uri | 페이지의 <base> 태그에 나타날 수 있는 URL을 설정 |
object-src | Flash와 같은 위험한 플러그인 비활성화 |
+ script-src directive
script-src-elem | <script> 요소를 지정하지만 인라인 스크립트 이벤트 핸들러는 지정x |
script-src-attr | 인라인 스크립트 이벤트 핸들러는 지정 하지만 <script>요소에 직접 로드된 URL은 포함x |
위의 directive와 짝지을 수 있는 value 값은 아래와 같다.
none | 모든 출처를 허용하지 않음 |
self | Origin 내에서 로드하는 리소스만 허용 |
unsafe-inline | 인라인 코드의 사용을 허용 |
unsafe-eval | eval과 같은 텍스트-자바스크립트 변환 메커니즘의 사용을 허용 |
nonce-<base64-value> | nonce 속성을 설정하여 예외적으로 인라인 코드를 사용합니다. <base64-value>는 반드시 요청마다 다른 난수 값으로 설정해야 합니다. 해당 출처를 설정하면 unsafe-inline 은 무시됩니다. 안전하지 않은 인라인 지시어를 사용하지 않도록 할 수 있습니다 |
예시로 directive와 value몇개를 조합하여 알아보자면,
Content-Security-Policy: default-src 'self'
- 모든 리소스 출처를 origin으로 제한
Content-Security-Policy: base-uri 'none'
- base태그의 모든 값을 허용하지 않음
Content-Security-Policy: script-src 'unsafe-inline'
- 인라인 코드의 사용을 허가
Bypass CSP
directive와 value값은 상황에 따라 모두 다르기 때문에, XSS공격자의 입장에서는 허점을 잘 파악하고 우회하는 것이 중요하다.
신뢰도메인에 파일 업로드
Content-Security-Policy: default-src 'self' '신뢰도메인'
과 같은 CSP 정책이 있을때 신뢰 도메인 자체에 원하는 파일을 업로드 해놓을 수 있다면?
신뢰도메인에 xss.js를 업로드하여
alert(document.cookie)
test.php?param=<script src='신뢰도메인/xss.js'></script> 로 우회 할 수 있겠다.
Base-uri 미지정
이와 비슷하게 CSP로 base-uri의 값을 지정하지 않았을때,
<base src=''> 태그를 사용하여 경로의 기준점을 변경, XSS를 터트리는 방법도 존재한다.
내서버/static/js/jquery.min.js 에 <script>alert(document.cookie)</script> 를 업로드 해놓는 다면 쿠키값을 읽어올 수 있게 된다.
PHP output_buffering 옵션 이용
이는 csp 자체를 자바스크립트 혹은 여타 기법으로 우회하는것과는 조금 다르다.
이는 CSP가 보통 응답의 헤더에 담겨오는 것을 이용한다.
PHP의 output_buffering 옵션은 apache / FastCGI 등에 응답을 줄때, 보통 4KB 만큼을 버퍼링 한 후 응답한다.
다음의 코드에서, PHP는 HELLO 출력 5초후, WORLD! 를 출력할 것으로 예상할 수 있지만, 실제로 페이지에 접속해보면 접속 5초후 한번에 HELLO WORLD! 가 출력된다는 거다.
<?php echo "Hello ";
sleep(5);
echo "World!";
?>
https://haah.kr/2018/05/01/streaming-and-output-buffering-in-PHP/
그런데 4kb 가 버퍼에 다 채워젔을경우, (csp가 포함된) 헤더보다 먼저 전송되어 csp 를 무시할 수 있다는 것이다.
'Web > Website security' 카테고리의 다른 글
toLowerCase(), toUpperCase() 유니코드 우회 (1) | 2024.04.02 |
---|---|
[SSRF / LFI] Bypass WAF with url globbing (1) | 2023.11.20 |
SSRF(Server-Side-Request-Forgery) 를 위한 다양한 URI scheme 정리 (0) | 2022.11.10 |
CSTI (Client-Side Template Injection) 취약점 (0) | 2022.11.08 |
UUID v1 사용은 안전하지 않습니다 (0) | 2022.10.11 |