A03-2: XSS 注入漏洞(Injection)
漏洞概述
跨站腳本(XSS,Cross-Site Scripting)是一種網路攻擊,攻擊者在 Web 應用中注入惡意 JavaScript,使受害者的瀏覽器執行惡意代碼,可能導致竊取 Cookie、劫持會話、偽造請求等攻擊行為。
1. 反射型 XSS(Reflected XSS)
概念: 反射型 XSS 是一種發生在即時請求處理的攻擊,攻擊者透過 URL 參數、表單輸入等方式將惡意 JavaScript 注入,並讓受害者點擊惡意連結,當伺服器回應該請求時,惡意腳本被嵌入到 HTML 內並在瀏覽器執行。
攻擊流程:
- 攻擊者構造帶有惡意 JavaScript 的 URL,誘導使用者點擊。
- 伺服器未進行適當的過濾或轉義,直接回傳用戶輸入的內容。
- 使用者瀏覽器執行這段惡意 JavaScript,導致 XSS 攻擊。
❌ 有漏洞的程式
package main
import (
"fmt"
"html/template"
"net/http"
)
func main() {
http.HandleFunc("/", xssHandler)
http.ListenAndServe(":8080", nil)
}
func xssHandler(w http.ResponseWriter, r *http.Request) {
query := r.URL.Query().Get("input")
// 這裡沒有做適當的輸入過濾,直接輸出用戶輸入內容,可能導致 XSS
htmlContent := fmt.Sprintf(`<html><body>你的輸入: %s</body></html>`, query)
w.Write([]byte(htmlContent))
}
🔍 檢測方法
- 使用 ZAP 檢測出有 XSS 的漏洞。

- 使用 dalfox 檢測,
dalfox url "http://192.168.56.1:8080/?input=123"
輸出的結果為:
[V] Triggered XSS Payload (found DOM Object): input=<ScRipt class=dalfox>prompt.valueOf()(1)</script>
1 line: dy>你的輸入: 123<ScRipt class=dalfox>prompt.valueOf()(1)</script></body></ht
[POC][V][GET][inHTML-none(1)-URL] http://192.168.56.1:8080/?input=123%3CScRipt+class%3Ddalfox%3Eprompt.valueOf%28%29%281%29%3C%2Fscript%3E
✅ 修正方式
使用 html/template 套件來避免 XSS:
tmpl := template.Must(template.New("page").Parse(`<html><body>你的輸入: {{.}}</body></html>`))
tmpl.Execute(w, query)
2. DOM 型 XSS
概念: DOM 型 XSS 發生在用戶端,瀏覽器內的 JavaScript 直接操作 DOM 並執行惡意腳本,而不經過伺服器處理。
攻擊流程:
- 攻擊者構造惡意的 URL,如:
http://example.com/page?name=<script>alert('XSS')</script> - 瀏覽器 JavaScript 解析 URL 並修改 DOM,導致惡意腳本執行。
❌ 有漏洞的程式
package main
import (
"fmt"
"net/http"
)
func main() {
http.HandleFunc("/", domXSSHandler)
http.ListenAndServe(":8080", nil)
}
func domXSSHandler(w http.ResponseWriter, r *http.Request) {
name := r.URL.Query().Get("name") // 直接取得 name 參數,未進行任何過濾
// 將用戶輸入的內容直接插入 HTML(這樣可以成功執行 XSS)
htmlContent := fmt.Sprintf(`
<html>
<body>
<p>輸入你的名稱:</p>
<input id="nameInput" type="text">
<button onclick="showName()">提交</button>
<p id="output">%s</p> <!-- 直接插入未過濾的輸入 -->
<script>
function getQueryParam(param) {
let params = new URLSearchParams(window.location.search);
return params.get(param);
}
function showName() {
document.getElementById("output").innerHTML = getQueryParam("name");
}
</script>
</body>
</html>`, name) // 這裡直接插入 name,會導致 XSS
w.Write([]byte(htmlContent))
}
🔍 檢測方法
- 使用 ZAP 檢測出有 XSS 的漏洞。

- 使用 dalfox 檢測,並且加上
--deep-domxss可以更深入找尋 DOM-XSS 的漏洞。
dalfox url "http://192.168.56.1:8080" --deep-domxss
輸出的結果為:
[V] Triggered XSS Payload (found DOM Object): name=<iframe srcdoc="<input onauxclick=alert(1)>" class=dalfox></iframe>
7 line: <p id="output"><iframe srcdoc="<input onauxclick=alert(1)>" class=dalfox></i
[POC][V][GET][inHTML-none(1)-URL] http://192.168.56.1:8080?name=%3Ciframe+srcdoc%3D%22%3Cinput+onauxclick%3Dalert%281%29%3E%22+class%3Ddalfox%3E%3C%2Fiframe%3E
✅ 修正方式
使用 textContent 來避免 HTML 解析:
document.getElementById('output').textContent = getQueryParam('name');
3. 儲存型 XSS(Stored XSS)
概念: 儲存型 XSS 是將惡意 JavaScript 存入伺服器的資料庫,當其他使用者讀取該資料時,惡意腳本在瀏覽器執行。
攻擊流程:
- 攻擊者提交惡意腳本,例如:
這段 JavaScript 被儲存到伺服器的資料庫中。
<script>
alert('XSS!');
</script> - 當其他用戶存取該頁面時,伺服器讀取資料並返回 HTML,導致惡意腳本執行。