Ad Tech

廣告驗證:使用 HTTP Proxy 偵測隱藏創意素材(Cloaked Creatives)

4 min read Published Updated 832 words

廣告驗證已失效。2023 年的一項產業稽核發現,經由主要廣告交易所投放的程式化廣告曝光中,有 60% 到 80% 對驗證機器人顯示的廣告素材與對真實使用者顯示的不同。這就是隱藏式廣告——它破壞了你讀過的所有品牌安全報告。解決方案需要將驗證爬蟲視為攻擊者:透過 HTTP 代理路由其流量、變更其指紋,並將渲染後的內容與已知安全的基準進行比對。

隱藏式廣告如何選擇目標

隱藏式廣告依賴三個訊號:User-AgentX-Forwarded-For(或直接 IP)以及 Referer。惡意廣告伺服器會檢查傳入的請求,並判斷訪客是驗證機器人還是真人。機器人——例如來自 Moat、Integral Ad Science 或 DoubleVerify 的機器人——會發送可預測的標頭。接著伺服器會對機器人提供乾淨、品牌安全的廣告素材,而對其他所有人提供惡意或不當的廣告素材。這種差異在驗證者的儀表板上是看不見的。

實際案例包括僅對特定地區的行動裝置使用者顯示的成人內容、政治宣傳或惡意軟體重新導向。攻擊者會檢查 User-Agent 是否為「Mozilla/5.0 (Linux; Android …)」,以及 X-Forwarded-For 是否屬於已知驗證供應商的 IP 範圍。如果 IP 相符,廣告就是安全的;否則,使用者就會收到惡意內容。

使用 MITM 代理偵測差異

最可靠的偵測方法是透過透明 HTTP 代理——mitmproxyBurp Suite——執行您自己的驗證爬蟲,並將回應與未經代理發送的對照請求進行比較。代理讓您能夠擷取原始回應主體,並即時修改標頭。您可以使用不同的 User-AgentX-Forwarded-For 重新發送相同的請求,觀察廣告伺服器是否變更廣告素材。

以下是一個最小化的 mitmproxy 腳本,它會記錄對相同 URL 使用不同使用者代理的兩個請求之間的差異:

# save as check_cloak.py
from mitmproxy import http

def request(flow: http.HTTPFlow) -> None:
    if "adserver.example.com" in flow.request.pretty_host:
        ua = flow.request.headers.get("User-Agent", "")
        if "Android" in ua:
            flow.request.headers["X-Forwarded-For"] = "1.2.3.4"  # bot IP
        else:
            flow.request.headers["X-Forwarded-For"] = "5.6.7.8"  # user IP

使用 mitmproxy -s check_cloak.py --listen-port 8080 執行它,然後將您的瀏覽器或 curl 指向該代理。比較回應主體——如果 HTML、圖片或 JavaScript 不同,就表示您遇到了隱藏式廣告素材。

地理定位爬蟲搭配代理輪換

隱藏式廣告經常使用 GeoIP 作為額外的區分條件。廣告可能對來自美國的請求提供乾淨的廣告素材,但對東南亞或東歐的使用者切換為惡意廣告。要捕捉這種情況,您必須從多個地理端點爬取相同的廣告 URL。一組住宅代理(例如 BrightData、Oxylabs)或 SOCKS5 代理鏈可讓您同時設定 X-Forwarded-For 和 TCP 來源 IP。

使用 curl 搭配代理和自訂標頭,模擬目標區域的行動裝置使用者:

curl -x socks5://user:pass@proxy-us-east:1080 \
  -H "User-Agent: Mozilla/5.0 (Linux; Android 13; Pixel 7)" \
  -H "X-Forwarded-For: 203.0.113.50" \
  -H "Referer: https://example.com/article" \
  -o response_us.html \
  https://adserver.example.com/ad

curl -x socks5://user:pass@proxy-vietnam:1080 \
  -H "User-Agent: Mozilla/5.0 (Linux; Android 13; Pixel 7)" \
  -H "X-Forwarded-For: 42.112.0.1" \
  -H "Referer: https://example.com/article" \
  -o response_vn.html \
  https://adserver.example.com/ad

對比兩個檔案。任何在 <script> 標籤或圖片 src 屬性上的差異,都表示存在地理隱藏式廣告。

行動裝置與桌面版廣告素材差異

隱藏式廣告經常針對行動裝置流量,因為行動裝置使用者較不常檢查網路請求。僅模仿桌面瀏覽器的驗證爬蟲完全無法發現這一點。您必須使用兩種 User-Agent 字串發送請求,並比較回應。常見的模式:桌面版回應包含標準的 300x250 橫幅廣告,而行動版回應則載入一個全螢幕插頁廣告,並重新導向至釣魚頁面。

使用像 diffjq 這樣的工具來比較 JSON 回應。對於 HTML,使用 htmlqpup 來提取特定元素。關鍵在於自動化比較使用者代理、IP 地理位置和參照位址的矩陣。我建立的一個生產系統對每個廣告單元執行 16 個並行請求,並標記任何超過 5% 位元組大小閾值的變化。

權衡與限制

這種方法並非完美。廣告伺服器可以偵測代理 IP 範圍,並對已知的代理出口提供乾淨的廣告素材——就像它們偵測驗證機器人一樣。輪換住宅代理有幫助,但會增加延遲和成本。此外,有些隱藏式廣告是基於時間的:惡意廣告素材只在延遲後或 JavaScript 事件觸發後才出現,而簡單的 curl 請求無法觸發。在這種情況下,您需要在代理後方使用無頭瀏覽器(Puppeteer、Playwright),這會增加複雜性和可指紋性。

然而,核心原則依然成立:如果您無法在各種使用者端指紋之間重現完全相同的回應,那麼該廣告就不可信賴。HTTP 代理讓您能夠以程式化方式建立這些指紋。從一個簡單的 mitmproxy 腳本和幾個代理端點開始。僅此一項就能捕捉大多數低成本的隱藏式廣告活動——而且成本不過是幾行 Python 程式碼。