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,導致惡意腳本執行。
❌ 有漏洞的程式
package main
import (
"fmt"
"net/http"
"sync"
)
var (
messages []string
mu sync.Mutex
)
func main() {
http.HandleFunc("/", formHandler)
http.HandleFunc("/submit", submitHandler)
http.ListenAndServe(":8080", nil)
}
func formHandler(w http.ResponseWriter, r *http.Request) {
// 直接使用 fmt.Sprintf 生成 HTML,不使用 html/template 來防止自動轉義
htmlContent := `
<html>
<body>
<form action="/submit" method="POST">
<input type="text" name="message">
<button type="submit">送出</button>
</form>
<h2>留言列表:</h2>
<ul>`
// 這裡直接插入 messages,會讓 script 被執行
mu.Lock()
for _, msg := range messages {
htmlContent += fmt.Sprintf("<li>%s</li>", msg)
}
mu.Unlock()
htmlContent += `
</ul>
</body>
</html>`
w.Write([]byte(htmlContent))
}
func submitHandler(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodPost {
r.ParseForm()
message := r.FormValue("message")
mu.Lock()
messages = append(messages, message) // 直接儲存用戶輸入(無過濾)
mu.Unlock()
http.Redirect(w, r, "/", http.StatusSeeOther)
}
}
🔍 檢測方法
- 使用 dalfox 檢測,並起提供攻擊點和傳入的 id,並指示為 POST,就能發現 XSS 問題。
dalfox url "http://192.168.56.1:8080/submit" -d "message=<script>alert('XSS')</script>" --method POST
輸出的結果為:
[V] Triggered XSS Payload (found DOM Object): show=<ScRipt class=dalfox>alert(1)</script>
[POC][V][POST][inHTML-none(1)-FORM] http://192.168.56.1:8080/submit -d message=%3Cscript%3Ealert%28%27XSS%27%29%3C%2Fscript%3E&show=%253C%2553%2563%2552%2569%2570%2574%2520%2563%256C%2561%2573%2573%253D%2564%2561%256C%2566%256F%2578%253E%2561%256C%2565%2572%2574%2528%2531%2529%253C%252F%2573%2563%2572%2569%2570%2574%253E
✅ 修正方式
在 submitHandler 使用 html.EscapeString 來過濾輸入:
message := html.EscapeString(r.FormValue("message"))
🔍 Dalfox 檢測工具
Dalfox(DalPoong XSS)是一款功能強大的 XSS(跨站腳本攻擊)漏洞掃描工具,由韓國安全研究員 hahwul 開發。它基於 Go 語言,主要用於自動化檢測和利用 DOM-based XSS、Reflected XSS、Stored XSS 等漏洞,適用於滲透測試人員和安全研究者。
特色功能
- 多種 掃描模式
- URL 掃描:提供單個 URL 探測
- 參數掃描:針對特定參數進行 XSS 測試
- 自動爬取:可以自動探索網站內部的鏈接和輸入點
- Header 注入:檢測
Referer、User-Agent等標頭是否可被利用
- 高效能
- 基於 Go 語言,執行速度快
- 多執行緒,可同時測試多個目標
- 豐富的 Payload
- 預設內建 多種 XSS Payload
- 自動編碼(如 HTML 實體、Base64 等)
- 可 自定義 Payloads,適應不同環境
- 支持外部工具
- 可以與 Burp Suite、SQLmap、Metasploit 等安全工具結合使用
- API & 自動化
- 可透過 CLI(命令行) 操作,適合整合到 DevSecOps 工作流程
- 提供 JSON 輸出,方便分析和自動化測試
安裝方式
前提條件:需要安裝 Go(>=1.14)
go install github.com/hahwul/dalfox/v2@latest
或使用 Docker:
docker pull hahwul/dalfox
docker run -it hahwul/dalfox
基本用法
- 掃描單個 URL
dalfox url "http://example.com/?q=hello"
- 掃描包含多個 URL 的文件
dalfox file target_list.txt
- 與 Burp Suite Proxy 結合
dalfox proxy -b "http://127.0.0.1:8080"
- API 模式
dalfox server --port 8080
官方資源
- GitHub: https://github.com/hahwul/dalfox
- 官方文件: https://dalfox.hahwul.com
結論
XSS 是網頁應用程式常見的安全漏洞,分為:
- 反射型 XSS:透過 URL 觸發,影響單次請求。
- DOM 型 XSS:JavaScript 操作 DOM 而導致的攻擊。
- 儲存型 XSS:惡意腳本儲存於伺服器,影響後續用戶。