# DOM-based Lab6
這題是 DOM Clobbering XSS 漏洞,利用了 JavaScript 中的邏輯錯誤 + HTML DOM 行為 + 技巧來觸發 alert()。
所以一樣先進入網站。

然後到文章下面留言:
```html
<a id=defaultAvatar></a><a id=defaultAvatar name=avatar href="cid:"onerror=alert(1)//"></a>
```
- 建立兩個 `<a>` 元素,`id=defaultAvatar`
- 第二個還多了一個 `name=avatar`(這會覆寫 avatar 屬性)
- `href="cid:"onerror=alert(1)//"` 裡的 `"` 會在 DOM 中還原成 `"`,構造出完整的 payload。
完成本題 DOM Clobbering 的一部分。

:::info
### DOM Clobbering 是什麼?
DOM Clobbering 是利用 HTML 元素的 `name` 或 `id` 屬性來「覆寫」原本 window 或 JavaScript 中的變數名稱,進而造成邏輯錯誤或安全漏洞。
```htmll
<a name="user"></a>
```
這會讓你在 JS 中 window.user 變成 `<a name="user">` 元素,覆蓋掉原本 user 的變數。這題我們就是用 `name="avatar"` 來 clobber 掉 defaultAvatar.avatar 的存取邏輯。
:::
當這段 HTML 被加入後:
```
let defaultAvatar = window.defaultAvatar || {avatar: '/resources/images/avatarDefault.svg'}
```
這行不會跑 fallback 的 object 是因為 `window.defaultAvatar` 現在是兩個 `<a>` 元素組成的 HTMLCollection,JavaScript 認為它是「truthy」。
:::info
### 為何 window.defaultAvatar 是 truthy?
fallback 沒跑的原因:
```
let defaultAvatar = window.defaultAvatar || { avatar: '/default.png' }
```
當我們塞了兩個 `<a id="defaultAvatar">` 到 HTML 中,`window.defaultAvatar` 會變成 HTMLCollection,不是 undefined,也不是 null,而是一個 **object(類陣列)**。
JavaScript 中**所有 object(不論是不是空的)都會被視為 truthy**,所以不會 fallback 成 `{ avatar: '/default.png' }`。
:::
之後程式會用:
```
let img = document.createElement('img');
img.src = defaultAvatar.avatar;
```
結果 defaultAvatar.avatar 取到的值是這個:
```
<a name=avatar href='cid:"onerror=alert(1)//'>
```
這樣就構造出:
```
<img src='cid:"onerror=alert(1)//'>
```
onerror 成功觸發。
接著我們再回去隨便發的留言觸發效果:

Bang。

:::info
### 為何要回去留言?
這是為了讓頁面重新 render,並使用被污染的 defaultAvatar。這時候 alert(1) 就會被觸發了。
### 盡量在 Chrome 執行
- cid: 協議(Content-ID)允許 " 在 Chrome 被正常還原、組合出 JavaScript 事件。
- Firefox 和其他瀏覽器會比較嚴格處理 src="cid:...",不會觸發 onerror。
:::
---