iT邦幫忙

2026 iThome 鐵人賽

DAY 21
0
Build on Google AI

30 天打造 AI Web Security Agent:從 Google AI Studio 到 Gemini Agent系列 第 21 篇

Day 21|先盤點入口,不急著把每個訊號叫做漏洞

  • 分享至 

  • xImage
  •  

前言

Day 20,我把 5 次本機 XSS 實驗排成一張可追溯總表;今天,我開始替最後的作品做入口盤點。不過,這裡的「入口」不是讓工具對任意網站爬行,也不是看到 innerHTML 就自動宣布有漏洞。我只讀取專案已保存的 HTML,整理表單、行內事件處理屬性與幾種前端資料流訊號,為後面建立 evidence bundle 準備索引。

先把範圍固定在 15 份保存 HTML

我沒有讓程式搜尋整個專案,也沒有依照超連結繼續走訪。release.json 明確列出 15 份來源:Day 14 的 3 份回應、Day 16 的 3 份表單與 3 份回應,以及 Day 18 的 3 份表單與 3 份回應。這些檔案都來自前幾天的受控本機實驗。

我從專案根目錄執行:

.venv/bin/python xss-evidence-workbench/workbench.py inventory \
  --output /tmp/xss-entry-inventory-day21.json

程式會先要求每個來源都是專案內的相對路徑,拒絕絕對路徑、越過專案範圍的 ..、符號連結和不存在的檔案,再以 UTF-8 讀取。輸出保留每份來源的 SHA-256,所以我之後可以知道盤點的是哪一個位元組版本,而不是只靠檔名猜測。

表單不只有 method 和 action

解析器遇到 <form> 時,會記錄 method、action、enctype、具名的 input、textarea、select、button,也會檢查提交按鈕上的 formaction、formmethod 與 formenctype。因為按鈕可能覆寫表單本身的提交設定,只看 <form action> 並不一定足夠。

本次共找到 6 份表單,全部使用 POST,編碼類型都是預設的 application/x-www-form-urlencoded,也都沒有提交按鈕覆寫。Day 16 的 3 份表單使用 q 欄位,分別送往 /post-vulnerable、/post-safe 和 /post-ignored;Day 18 的 3 份表單使用 message,分別送往 /vulnerable/submit、/escaped/submit 和 /rejected/submit。

這 6 條路徑看起來很具體,卻仍只是保存頁面描述的提交候選。盤點程式沒有按下按鈕,也沒有驗證伺服器此刻是否仍提供那些端點。真正的 POST 請求與後續回應,仍要回到 Day 16、Day 18 的原始證據核對。

字面訊號能提醒我,但不能替我判讀

對 <script> 內容,我只掃描事先定義的少量訊號。實際結果如下:

類別 訊號 次數
來源 location.hash 2
來源解析 URLSearchParams 2
HTML 寫入 innerHTML 1
純文字寫入 textContent 2

這些訊號全都來自 Day 14。弱點頁與純文字頁都讀取 location.hash,也都用 URLSearchParams 解析;差別是弱點頁將值交給 innerHTML,純文字頁交給 textContent。忽略片段頁沒有讀取 fragment,但會用 textContent 寫入固定內容。單看「有沒有來源」仍不夠,來源是否真的走到特定輸出位置,才是後續要對照的資料流。

另外,我在 15 份文件中找到 2 個行內事件處理屬性。它們分別位於 Day 16 和 Day 18 的弱點組回應,都是先前固定探針形成的 img onerror。這不是今天發現的兩個新漏洞,而是今天的解析器重新看見既有實驗留下的 HTML 結果。若我把「找到 onerror」直接寫成「確認 XSS」,就會丟掉當時的請求、回應、瀏覽器對話框和 DOM 旗標等關鍵上下文。

我也測試盤點器會不會拒絕模糊輸入

除了核對實際數量,我也跑過入口盤點相關測試。測試確認表單解析器會保留提交按鈕覆寫;來源路徑若跑到專案外便會被拒絕;巢狀或未閉合表單也不會被當成可靠結果。另一方面,測試要求候選訊號留在 inventory 區塊,不能混進案例的工具分類。

這套解析仍有刻意保留的限制。它不是瀏覽器,不會執行 JavaScript,所以看不到執行後才建立的表單;腳本訊號採字面比對,不是完整的 JavaScript 語意分析;來源清單也只有這 15 份檔案,不能代表應用程式全部頁面。我今天完成的是一個範圍清楚、可回查的入口索引,而不是通用網站掃描器。

我也逐份回看盤點結果,確認「沒有命中」沒有被省略成「不存在」。例如設定雖會找 location.search、outerHTML、insertAdjacentHTML、document.write、eval 和 Function,本次保存腳本沒有命中,所以輸出保留空清單,而不是替整個專案做否定宣告。這種寫法比較不吸睛,卻能讓下一位讀者分清楚「這 15 份來源沒看到」和「任何地方都沒有」的差別。

Day 21 的收穫是:候選入口應該幫我提出下一個核對問題,而不是提前替我回答。明天,我會把 Day 20 已完成的來源重驗接進工作台,讓每一組保存結果都先通過 SHA-256 與瀏覽器雙重訊號檢查,再進入整合流程。

那就…
明天見!


上一篇
Day 20|把五種 XSS 情境排成一張可追溯的證據表
下一篇
Day 22|重新相信保存結果以前,我先把來源重驗接回來
系列文
30 天打造 AI Web Security Agent:從 Google AI Studio 到 Gemini Agent 共 24 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言