如何保護歸因追蹤,防禦 SDK 欺詐與詐騙

opoinstall
2026-09-09
5 min read

如何保護歸因追蹤以防禦 SDK 欺詐? 保護歸因追蹤免受 SDK 欺詐攻擊,需要實施伺服器對伺服器(S2S)的 HMAC-SHA256 請求簽章、動態 Nonce 重放防禦機制,以及硬體輔助的平台完整性認證。

SDK 欺詐是一種進階的行動廣告詐騙形式,惡意行為者透過逆向工程解析行動遙測協定,並直接將合成的安裝或事件封包發送至歸因端點,而無需在實際硬體上執行應用程式。在行動歸因追蹤中,防禦 SDK 欺詐需要建構雙層安全架構,將伺服器對伺服器的 HMAC-SHA256 加密簽章與動態 Nonce,結合硬體輔助的平台完整性認證。

術語 定義 相關實體 搜尋意圖角色
歸因追蹤 針對行銷接觸點與轉換進行系統化的記錄與驗證。 行動衡量夥伴 (MMP) 資訊型 / 商業型
SDK 欺詐 使用逆向工程解析後的 API 封包,於伺服器端模擬合法的 SDK 流量。 廣告詐騙 技術型 / 資訊型
HMAC 簽章 一種 HMAC 身份驗證標籤(非正式稱為 HMAC 簽章),用於驗證請求的真實性與封包完整性。 轉換追蹤 技術型 / 資訊型

為什麼 SDK 欺詐會威脅歸因追蹤與營收完整性

幽靈安裝問題:無需實體或虛擬裝置即可耗盡獲客預算

在傳統的行動廣告詐騙中,惡意行為者依賴實體裝置庫(裝置農場)或虛擬作業系統(模擬器)來模擬用戶行為。這些攻擊需要實體或計算資源來下載、安裝並執行應用程式二進位檔案。

SDK 欺詐則完全移除了裝置需求。惡意行為者分析行動歸因 SDK 與後端接收閘道之間的網路通訊協定。透過編寫伺服器端腳本,建構並將合成的 HTTP POST 請求直接傳送到歸因端點,詐騙者便能在未將任何位元組的應用程式代碼下載到真實裝置的情況下,產生數百萬次幽靈安裝。

由於幽靈安裝會消耗行銷資金來處理完全合成的事件,導致績效行銷活動出現嚴重的資金配置失當。廣告主支付 CPI(每次安裝成本)或 CPA(每次行動成本)費用給詐欺性的發佈來源,在無法獲得任何真實人類用戶的同時,耗盡了獲客預算。

偽造高價值下游轉換:應用內購買、註冊與關卡達成

早期的 SDK 欺詐實作僅專注於偽造漏斗頂端的安裝事件。然而,現代自動化殭屍網路可編寫多步驟生命週期流程,跨越數天發送模擬的安裝後遙測事件。

透過逆向工程解析事件追蹤端點,詐騙者針對高額轉換里程碑發送合成的回傳(Postback):

  • 帳號註冊:產生虛假用戶設定檔提交,以領取 CPA 註冊獎勵。
  • 遊戲與里程碑進度:模擬關卡完成、新手教學結束或互動里程碑,以達成留存門檻要求的發佈商支付。
  • 合成應用內購買:發送偽造的交易收據,欺騙衡量平台以計算出虛高的廣告支出報酬率(ROAS),進而誘導演算法出價引擎將更多行銷預算導向詐欺性的子發佈商。

信任崩潰:合成遙測如何腐蝕績效行銷 ROI

當歸因管線接收到欺詐的遙測數據時,下游的報表資料集會在結構上遭到破壞。資料科學團隊使用偽造的轉換訊號來訓練預測性 LTV 模型與自動化程式化出價演算法,導致自動化出價引擎傾向於優化那些產出零真實終身價值的來源。

密碼學身份驗證允許接收閘道在進入歸因處理前,拒絕那些未通過配置之發送者身份驗證與重放檢查的請求。此外,有效的 HMAC 身份驗證標籤能驗證發送整合的合法性並確保封包完整性;它並不單獨證明底層現實世界的轉換實際發生。建立密碼驗證與安裝後行為稽核的雙重防禦,是維持歸因帳簿準確性的關鍵。

尋求輕量級客戶端遙測與歸因 SDK 的開發者,可透過 行動分析 SDK 套件 探索相關套件。

SDK 欺詐如何在無需實體裝置的情況下偽造轉換

協定逆向工程機制:代理攔截、反編譯與 API 對映

為了執行 SDK 欺詐,惡意行為者透過一系列逆向工程步驟拆解應用程式客戶端及其衡量庫:

  1. 靜態二進位反編譯:使用反編譯器(如 Android 的 JADX 或 iOS 的 Ghidra)檢查應用程式封包(APK 或 IPA),定位 API 端點、參數架構與寫死的驗證 Token。
  2. 中間人 (MitM) 代理攔截:將真實裝置流量導向本地代理工具(如 Charles Proxy 或 mitmproxy),並安裝根憑證來解密 TLS 流量,從而對映輸出的 JSON 封包。
  3. 動態執行時掛鉤 (Hooking):利用動態檢測框架(如 Frida 或 Xposed)繞過 SSL Pinning,檢查執行時記憶體,並提取用於請求建構的加密金鑰或參數。

一旦網路合約被對映,攻擊者便將架構編碼進自動化伺服器腳本,產生在未經身份驗證端點上模擬真實客戶端封包的合成請求。

[攻擊者機器人伺服器] ──► [逆向工程封包] ──► [偽造 HTTPS POST] ──► [歸因端點]
       │                                                                                   │
       ├─► 合成宣告識別碼 (GAID / IDFA)                                   ▼
       ├─► 重放已擷取的網路參數                                     [歸因已記錄]
       └─► 發送模擬應用內購買收據                                (支付獎勵已釋放)

欺詐封包剖析:合成硬體雜湊、時間戳與廣告識別碼

欺詐的遙測封包包含合成產生或重放的後設資料欄位,旨在模擬真實的行動裝置:

  • 廣告識別碼:輪替宣告的識別碼(如合成的 GAID 或 IDFA Token)以模擬不同用戶。
  • 宣告的裝置後設資料:程式化地變更宣告的裝置型號、CPU 架構、螢幕解析度與 OS 組建編號,製造自然裝置熵的錯覺。
  • 網路參數:透過商業代理網路或住宅 VPN 路由請求,以匹配目標地理區域的行銷活動。
  • 事件時間戳:偽造順序時間戳以模擬安裝與轉換事件之間的自然用戶互動延遲。

由於未經身份驗證的閘道僅檢查 JSON 結構與參數是否存在,它們無法判定封包是源自真實的行動作業系統,還是資料中心內執行的腳本。

客戶端嵌入式機密的缺陷:為何在應用封包中儲存靜態 API 金鑰會失敗

行動安全中常見的架構缺陷是依賴直接嵌入在客戶端應用二進位檔案中的靜態機密金鑰(例如在 Android Application 類別或 iOS 套件中硬編碼共用秘密字串)。

行動應用封包被部署在不受信任、由用戶控制的執行環境中。任何嵌入在 APK 或 IPA 中的秘密金鑰都必須被視為可透過靜態反編譯、記憶體傾印或動態檢測提取的內容。一旦被提取,詐騙者便會使用洩露的秘密來簽署合成請求,使得客戶端靜態簽章在面對蓄意攻擊者時顯得無效。

保護歸因追蹤需要將脆弱的客戶端嵌入式機密與可信任的伺服器對伺服器邊界分離,並利用硬體輔助的平台完整性認證。

SDK 欺詐繞過真實應用程式進行偽造歸因請求

伺服器對伺服器 HMAC 請求簽章的加密架構

將客戶端應用機密與伺服器對伺服器的信任邊界分離

企業級防欺詐架構在客戶端對伺服器遙測與伺服器對伺服器(S2S)回傳通訊之間建立了嚴格的分隔:

  • 伺服器對伺服器 (S2S) 整合層:廣告網路、DSP 與歸因端點之間的直接 API 整合在受信任的伺服器環境中運作。共用秘密金鑰僅儲存在安全的後端金鑰管理系統 (KMS) 或硬體安全模組 (HSM) 中,絕不會暴露給客戶端二進位檔案。
  • 客戶端遙測層:行動客戶端通訊依賴平台級的加密認證(如 Google Play Integrity 或 Apple App Attest),而非靜態嵌入式機密,以提供可驗證的執行證據。

規範字串建構:結構化原始封包以防止參數竄改

為了防止竄改並確保確定性的簽章驗證,發送伺服器與接收閘道必須在計算加密身份驗證標籤前,組合出完全相同的規範字串。

該協定定義了精確且無歧義的請求目標表示法:

  1. 協定版本:明確的協定識別標頭 (X-Signature-Version: v1)。
  2. HTTP 方法:標準化大寫字串 (如 POST)。
  3. 請求 URI 路徑:絕對正規化端點路徑,不包含查詢字串 (如 /api/v1/attribution/event)。
  4. 時間戳:整數 Unix epoch 時間戳(秒)(X-Timestamp)。
  5. Nonce:唯一的加密隨機字串,至少包含 128 位元的熵 (X-Nonce),限制為字母數字字元。
  6. 金鑰識別碼:明確的金鑰版本識別碼 (X-Key-Id),匹配有效的或處於寬限期的金鑰。
  7. 原始封包雜湊:直接對確切的原始 HTTP 請求實體位元組計算出的十六進位 SHA-256 雜湊 (SHA256(RawBodyBytes))。

規範簽章字串使用豎線分隔符 (|) 進行組合,並以 UTF-8 嚴格編碼:

CanonicalString="v1"    HTTP_METHOD    URI_PATH    Timestamp    Nonce    KeyID    SHA256(RawBodyBytes)\text{CanonicalString} = \text{"v1"} \;\|\; \text{HTTP\_METHOD} \;\|\; \text{URI\_PATH} \;\|\; \text{Timestamp} \;\|\; \text{Nonce} \;\|\; \text{KeyID} \;\|\; \text{SHA256}(\text{RawBodyBytes})

HMAC-SHA256 請求簽章的數學公式

HMAC 身份驗證標籤使用 IETF RFC 2104 定義的 HMAC-SHA256 演算法計算,將版本化的共用秘密金鑰應用於規範字串:

AuthenticationTag=HMAC-SHA256(SecretKey,  CanonicalString)\text{AuthenticationTag} = \text{HMAC-SHA256}(\text{SecretKey}, \; \text{CanonicalString})

用於歸因回傳的 HMAC SHA256 規範請求簽章

\text{AuthenticationTag} = \text{HMAC-SHA256}\Big(\text{SecretKey}, \; \text{CanonicalString}\Big)OpoInstall 技術資源討論了基於 HMAC 的封包身份驗證與重放防禦模式;下方的協定代表一個說明性的參考架構,而非固定的私有 API 合約。開發者可查閱 回傳安全文件 以取得關於配置整合 Webhook 與管理合作夥伴驗證金鑰的技術指南。

下方的 Python 實作展示了一個具備完整金鑰生命週期解析(活躍、寬限期與撤銷狀態)、非對稱時間戳視窗與原子 Nonce 狀態管理的企業級 S2S HMAC-SHA256 驗證中介軟體:


```python
# [CODE_BLOCK_01] Python S2S HMAC-SHA256 簽章驗證中介軟體
import hmac
import hashlib
import time
import redis
from enum import Enum
from typing import Dict, Tuple, Optional, Set

class KeyStatus(Enum):
    ACTIVE = "active"             # 允許簽章與驗證
    GRACE_PERIOD = "grace_period" # 允許在金鑰輪替期間進行驗證;已廢棄簽章功能
    REVOKED = "revoked"           # 已洩露或明確停用;所有驗證請求均遭拒絕
    EXPIRED = "expired"           # 超過最長生命週期;驗證請求均遭拒絕

class KeyRecord:
    def __init__(self, key_id: str, secret: str, status: KeyStatus):
        self.key_id = key_id
        self.secret = secret
        self.status = status

class KeyProvider:
    """
    用於從 KMS/HSM 解析版本化共用秘密金鑰與生命週期狀態的抽象介面。
    """
    def get_key_record(self, partner_id: str, key_id: str) -> Optional[KeyRecord]:
        raise NotImplementedError

class MemoryKeyProvider(KeyProvider):
    """
    示範金鑰生命週期解析的記憶體內金鑰提供者。
    生產環境實作應查詢安全的 KMS 或 HSM 服務。
    """
    def __init__(self, key_registry: Dict[str, Dict[str, KeyRecord]]):
        # 格式: { partner_id: { key_id: KeyRecord } }
        self.key_registry = key_registry

    def get_key_record(self, partner_id: str, key_id: str) -> Optional[KeyRecord]:
        return self.key_registry.get(partner_id, {}).get(key_id)

class AttributionSecurityMiddleware:
    def __init__(
        self,
        key_provider: KeyProvider,
        redis_client: redis.Redis,
        max_past_age_seconds: int = 300,
        max_future_skew_seconds: int = 30
    ):
        """
        初始化 S2S HMAC 簽章驗證與重放防禦中介軟體。
        
        :param key_provider: 解析版本化合作夥伴秘密記錄與狀態的提供者
        :param redis_client: 用於原子 Nonce 追蹤的共享一致性儲存 (Redis)
        :param max_past_age_seconds: 過去時間戳允許的最大存續時間 (預設 300s)
        :param max_future_skew_seconds: 未來時間戳允許的最大時鐘偏移容差 (預設 30s)
        """
        self.key_provider = key_provider
        self.redis = redis_client
        self.max_past_age_seconds = max_past_age_seconds
        self.max_future_skew_seconds = max_future_skew_seconds
        # 總 TTL 確保 Nonce 的存活時間長於請求接收的最大視窗
        self.nonce_ttl_seconds = max_past_age_seconds + max_future_skew_seconds + 30

    def verify_request(
        self,
        partner_id: str,
        http_method: str,
        uri_path: str,
        headers: Dict[str, str],
        raw_body: bytes
    ) -> Tuple[bool, Optional[str]]:
        """
        對傳入的 S2S 回傳請求執行加密驗證與重放防禦。
        安全不變量:HMAC 標籤必須在 Redis 消耗 Nonce 狀態前進行驗證。
        
        :return: (是否有效, 若無效則返回錯誤代碼)
        """
        # 第 1 步:提取必要的加密標頭
        signature = headers.get("X-Signature")
        timestamp_str = headers.get("X-Timestamp")
        nonce = headers.get("X-Nonce")
        key_id = headers.get("X-Key-Id")
        sig_version = headers.get("X-Signature-Version", "v1")

        if not signature or not timestamp_str or not nonce or not key_id:
            return False, "MISSING_SECURITY_HEADERS"

        if sig_version != "v1":
            return False, "UNSUPPORTED_SIGNATURE_VERSION"

        # 驗證 Nonce 格式:僅限字母數字,長度介於 16 與 64 之間
        if not (16 <= len(nonce) <= 64 and nonce.isalnum()):
            return False, "INVALID_NONCE_FORMAT"

        # 第 2 步:根據非對稱邊界驗證整數 Unix epoch 時間戳(秒)
        try:
            request_timestamp = int(timestamp_str)
        except ValueError:
            return False, "INVALID_TIMESTAMP_FORMAT"

        current_time = int(time.time())
        age_seconds = current_time - request_timestamp
        future_skew_seconds = request_timestamp - current_time

        if age_seconds > self.max_past_age_seconds or future_skew_seconds > self.max_future_skew_seconds:
            return False, "TIMESTAMP_OUT_OF_BOUNDS"

        # 第 3 步:解析版本化秘密金鑰並評估生命週期狀態
        key_record = self.key_provider.get_key_record(partner_id, key_id)
        if not key_record:
            return False, "UNKNOWN_KEY_ID"

        if key_record.status == KeyStatus.REVOKED:
            return False, "REVOKED_KEY_ID"
        elif key_record.status == KeyStatus.EXPIRED:
            return False, "EXPIRED_KEY_ID"
        elif key_record.status == KeyStatus.GRACE_PERIOD:
            # 金鑰輪替期間允許進行驗證;記錄棄用警告
            pass

        # 第 4 步:建構規範簽章字串
        # 協定規格: "v1" | HTTP_METHOD | URI_PATH | Timestamp | Nonce | KeyID | SHA256(RawBodyBytes)
        body_sha256 = hashlib.sha256(raw_body).hexdigest()
        normalized_method = http_method.upper().strip()
        normalized_path = uri_path.strip()
        
        canonical_string = f"v1|{normalized_method}|{normalized_path}|{request_timestamp}|{nonce}|{key_id}|{body_sha256}"

        # 第 5 步:計算預期的 HMAC-SHA256 身份驗證標籤
        expected_signature = hmac.new(
            key=key_record.secret.encode("utf-8"),
            msg=canonical_string.encode("utf-8"),
            digestmod=hashlib.sha256
        ).hexdigest()

        # 第 6 步:使用恆定時間比較防止計時攻擊
        if not hmac.compare_digest(signature.lower(), expected_signature.lower()):
            return False, "INVALID_SIGNATURE"

        # 第 7 步:原子 Nonce 消耗(僅在 HMAC 驗證通過後執行)
        # 防止未經身份驗證的狀態污染,同時確保原子級一次性強制執行
        nonce_key = f"s2s_nonce:{partner_id}:{nonce}"
        is_nonce_unique = self.redis.set(
            name=nonce_key,
            value="1",
            ex=self.nonce_ttl_seconds,
            nx=True
        )

        if not is_nonce_unique:
            return False, "REPLAY_ATTACK_DETECTED"

        # 請求成功驗證並接納
        return True, None

伺服器端簽章驗證工作流程與錯誤回應標準化

當歸因接收閘道收到傳入的 S2S 請求時,它會執行連續的驗證步驟,以確保安全狀態不會被未經身份驗證的請求所污染:

  1. 標頭提取:提取 X-Signature, X-Timestamp, X-Nonce, X-Key-IdX-Signature-Version 標頭。
  2. 時間戳新鮮度驗證:確認請求時間戳(Unix epoch 秒)滿足非對稱新鮮度邊界:評估過去時間 (Age300s\text{Age} \le 300\text{s}) 與未來時鐘偏移 (Skew30s\text{Skew} \le 30\text{s})。若已過期或無效,則請求會遭 HTTP 401 Unauthorized 拒絕。
  3. 版本化金鑰解析:查詢金鑰提供者以獲取指定的 X-Key-Id。若金鑰已撤銷、過期或未知,驗證會立即失敗。若金鑰處於 GRACE_PERIOD 狀態,驗證將繼續進行,但會記錄合作夥伴金鑰輪替的棄用警告。
  4. 加密標籤驗證:使用確切的原始封包位元組重建規範字串,計算預期的 HMAC-SHA256 標籤,並針對傳入的簽章執行恆定時間比較 (hmac.compare_digest)。若無效,則請求會遭 HTTP 401 Unauthorized 拒絕。
  5. 原子 Nonce 消耗僅在加密身份驗證標籤驗證通過後,閘道會透過原子化的 SET key "1" EX TTL NX 操作,在共享一致性儲存(如 Redis)中記錄該 Nonce。若 Nonce 已存在,則請求會遭 HTTP 401 Unauthorized (REPLAY_ATTACK_DETECTED) 拒絕。

在消耗 Nonce 之前驗證 HMAC 標籤,可確保未經身份驗證的攻擊者無法污染快取或針對合法的 Nonce 執行拒絕服務攻擊。

如何實作 Nonce 快取與時間戳視窗以防禦重放攻擊

重放攻擊機制:重新發送有效的歷史擷取封包

即使請求已進行密碼學身份驗證,惡意行為者若擷取了已簽署的有效請求,仍可執行重放攻擊:擷取完整封包(包括有效的簽章、標頭與主體),並將其重新發送數千次至歸因端點。

由於簽章與封包匹配,若缺乏重放防禦的靜態驗證系統會將這些重複請求視為合法,導致單一有效用戶動作產生數千條非法轉換記錄。

執行非對稱時間戳視窗:分離過去存續時間與未來時鐘偏移

重放防禦始於嚴格的時間戳視窗強制執行。發送者在請求標頭中附加一個整數 Unix epoch 時間戳(秒)。接收時,歸因伺服器會根據其同步時鐘(透過 NTP)計算時間差:

Δtpast=tservertrequest,Δtfuture=trequesttserver\Delta t_{\text{past}} = t_{\text{server}} - t_{\text{request}}, \quad \Delta t_{\text{future}} = t_{\text{request}} - t_{\text{server}}

閘道執行下列說明性非對稱政策:

  • 允許的最大過去時間:通常為 Δtpast300 seconds\Delta t_{\text{past}} \le 300\text{ seconds},並拒絕過期的請求。
  • 允許的最大未來偏移:通常為 Δtfuture30 seconds\Delta t_{\text{future}} \le 30\text{ seconds},以容納細微的時鐘偏移,同時拒絕過於遙遠的未來時間戳。

分散式 Redis 中的 Nonce 儲存:具自動 TTL 的原子 Check-and-Set 操作

為了防止在有效時間戳視窗內的重放,閘道會追蹤 Nonce(Number used ONCE,一次性編號)。每個請求都必須包含一個由 CSPRNG 產生的唯一加密隨機 Nonce(至少 128 位元熵)。

伺服器使用原子操作將經驗證的 Nonce 儲存在分散式記憶體快取(如 Redis)中。為了徹底消除重放接收間隙,Nonce 的存活時間(TTL\text{TTL})必須涵蓋已簽署請求的整個剩餘有效期間:

TTLnonce=MaxPastAge+MaxFutureSkew+SafetyMargin=300s+30s+30s=360s\text{TTL}_{\text{nonce}} = \text{MaxPastAge} + \text{MaxFutureSkew} + \text{SafetyMargin} = 300\text{s} + 30\text{s} + 30\text{s} = 360\text{s}

以原子方式執行 Redis 指令:

Redis Command:SET"s2s_nonce:"+PartnerID+":"+Nonce"1"EX360NX\text{Redis Command}: \quad \text{SET} \quad \text{"s2s\_nonce:"} + \text{PartnerID} + \text{":"} + \text{Nonce} \quad \text{"1"} \quad \text{EX} \quad 360 \quad \text{NX}
  • 若 Redis 回傳 OK,表示 Nonce 為唯一,該 Nonce 已記錄並將在 360 秒後從記憶體中自動過期。
  • 若 Redis 回傳 nil (null),表示 Nonce 已被處理過;該請求被識別為重放攻擊並予以拒絕。
[傳入 S2S 請求]
           │
           ▼
[第 1 步:標頭檢查] ──► ( 缺少簽章 / 時間戳 / Nonce / Key-Id ) ──► [HTTP 401]
           │
           ▼ (格式有效)
[第 2 步:時間戳檢查] ──► ( 存續時間 > 300s 或 偏移 > 30s ) ───────────────────────► [HTTP 401]
           │
           ▼ (在新鮮度視窗內)
[第 3 步:解析金鑰] ──► ( 未知 / 已撤銷 Key-Id ) ───────────────────────────► [HTTP 401]
           │
           ▼ (金鑰有效或處於寬限期)
[第 4 步:HMAC 驗證] ──► ( 恆定時間比較下雜湊不匹配 ) ────────► [HTTP 401]
           │
           ▼ (標籤已驗證)
[第 5 步:原子 Nonce SET NX] ──► ( Redis 中 Nonce 已存在 ) ──────────────► [HTTP 401]
           │
           ▼ (Nonce 已消耗,TTL = 360s)
[第 6 步:事件進入歸因流]
簽署歸因請求的 Nonce 與時間戳重放防禦

系統層級下防欺詐防禦機制的比較評估

對照客戶端、網路與伺服器邊界下的安全策略

捍衛歸因追蹤管線需要評估多個實作層級下的安全機制。

下表對照了主要的防欺詐防禦機制:

安全層級 實作的防禦機制 解決的弱點 固有營運限制
客戶端混淆 代碼縮減、ProGuard Keep 規則、字串加密 阻礙靜態二進位反編譯 對動態執行時掛鉤 (Frida/Xposed) 無效
客戶端機密 在 SDK 二進位檔中嵌入對稱簽章金鑰 基礎封包完整性驗證 易受記憶體檢查的金鑰提取攻擊
S2S 請求簽章 使用後端共用秘密的 HMAC-SHA256 保護伺服器對伺服器合作夥伴 Webhook 需要預先共用金鑰;僅適用於伺服器端點
重放防禦 具時間戳 TTL 的分散式 Nonce 追蹤 阻擋已擷取請求的重新傳輸 需要分散式一致性狀態 (如 Redis)
平台認證 硬體輔助完整性 (Play Integrity / App Attest) 提供源自平台的應用/裝置完整性證據 需要平台支援;受限於網路認證延遲

硬體輔助平台認證如何驗證客戶端真實性

為何加密認證取代了脆弱的靜態客戶端機密

由於靜態的客戶端嵌入式金鑰無法抵禦不受信任行動環境中的提取攻擊,現代作業系統提供了硬體輔助的加密認證服務。

平台完整性系統揭露了不同的信任機制:Google Play Integrity 傳回繫結至受保護動作的平台評估完整性判決,而 Apple App Attest 則使用繫結至安全隔離區 (Secure Enclave) 的應用實例金鑰與後續經伺服器驗證的斷言。歸因伺服器會驗證這些平台斷言,提供可驗證的證據,證明請求源自真實物理裝置上未經竄改的應用程式。

Android 防禦:針對標準與經典請求實作 Google Play Integrity API

Android 應用程式整合 Google Play Integrity API 以評估裝置信任與應用完整性。Google Play Integrity 支援兩種截然不同的請求架構:

  • 標準 API 請求:專為低延遲應用內檢查而優化,使用初始準備呼叫並產生繫結至客戶端提供之 requestHash 的完整性 Token。Google 架構會自動管理防禦重放攻擊。
  • 經典 API 請求:專為伺服器管理的工作流程設計,開發者的後端產生包含在客戶端請求中的加密伺服器 Nonce,將產生的 Token 繫結至特定的伺服器互動。

後端歸因伺服器解密並驗證完整性 Token,在階層式強制執行政策下評估結構化的判決:

  • 應用辨識 (appRecognitionVerdict):確認應用程式二進位檔案是否匹配在 Google Play 上註冊的官方開發者簽章憑證 (PLAY_RECOGNIZED)。
  • 裝置辨識 (deviceRecognitionVerdict):評估裝置信任等級(如 MEETS_DEVICE_INTEGRITYMEETS_STRONG_INTEGRITY)。
  • 帳戶詳情 (accountDetailsVerdict):評估應用授權狀態 (LICENSED)。

較弱、缺失或非預期的完整性判決將作為風險訊號,導入階層式伺服器端評估政策,而非直接判定為二進位的欺詐分類。

iOS 防禦:部署 Apple App Attest 與 DeviceCheck 進行硬體繫結伺服器斷言

在 iOS 上,應用程式部署 App Attest 服務(DeviceCheck 框架的一部分)以驗證客戶端合法性:

  1. 金鑰產生:iOS 應用程式呼叫 DCAppAttestService.shared.generateKey(),在裝置的安全隔離區內建立硬體繫結、不可導出的加密金鑰對。
  2. 金鑰認證:應用程式請求 Apple 認證該公開金鑰 (attestKey()),提供包含公開金鑰與認證鏈的認證物件。後端伺服器使用 Apple 的根憑證驗證此認證物件,並提取與儲存公開金鑰。
  3. 斷言驗證:針對後續的轉換事件,應用程式透過使用私鑰簽署伺服器發出的挑戰 Nonce 與事件封包雜湊,產生斷言 (generateAssertion())。後端伺服器驗證該斷言簽章與儲存的公開金鑰是否匹配,從而證明遙測數據源自真實應用實例且未經重放。

作為 App Attest 的補充,DeviceCheck 允許伺服器在 Apple 伺服器上為每台裝置儲存兩個位元的持久狀態,支援跨安裝濫用追蹤,而無需存取持久性的硬體識別碼。

將平台認證判決整合至歸因接收管線

平台認證 Token 會在閘道層級與標準歸因參數一同被接收。透過結合伺服器整合的 S2S HMAC 身份驗證與客戶端端點的 Play Integrity 與 App Attest,衡量平台能建立端對端防禦,提高合成欺詐的運算成本,並提供拒絕不受信任客戶端請求的可驗證證據。

HMAC 與平台認證雙層歸因安全

績效行銷人員何時需要進階防欺詐架構

專用防欺詐基礎建設的適用條件

在特定行銷條件下,實作進階加密簽章與平台認證能提供高度的營運價值:

  • 高 CPA 獎勵計畫:針對下游轉換(如金融帳戶存款、信用卡提交、加密貨幣交易或訂閱試用)提供高額佣金的行銷活動。
  • 高量級聯盟網路:在缺乏透明度且子 syndication 常見的開放式多層級聯盟行銷活動中。
  • 歸因數據與內部帳簿不一致:應用程式觀察到行銷儀表板中的歸因轉換量與財務資料庫中實際記錄的營收之間存在巨大落差。

複雜加密中介軟體的非適用條件

在下列情境中,部署複雜的 S2S 加密中介軟體可能會帶來不必要的營運開銷:

  • 早期原型探索:專注於在啟動公開獲客活動前驗證功能機制的預商業應用程式。
  • 封閉式自我歸因網路:透過封閉網路(如 Apple Search Ads 或 Google App Campaigns)執行 100% 廣告支出,且無需外部 S2S Webhook 的行銷營運。

SDK 欺詐防禦中的常見誤解

  • 誤解 1:傳輸層安全 (TLS/HTTPS) 可防止 SDK 欺詐:HTTPS 加密客戶端與伺服器之間的傳輸數據,防止第三方在公共 Wi-Fi 上進行竊聽。然而,TLS 並不會驗證發送請求的客戶端身份;攻擊者執行 Python 腳本即可建立合法的 TLS 連接並發送欺詐封包。
  • 誤解 2:代碼混淆可消除欺詐弱點:雖然如 ProGuard 或 DexGuard 等工具增加了靜態逆向工程的複雜度,但它們無法防止動態執行時攔截(透過 Frida)或網路代理對映。混淆會拖慢攻擊者速度,但無法取代加密請求驗證。

常見問題 (FAQ)

SDK 欺詐與模擬器及裝置農場詐欺有何不同?
裝置農場與模擬器在硬體或虛擬裝置上執行真實或虛擬化的應用程式套件,透過腳本自動化執行 UI 導航。相比之下,SDK 欺詐不使用任何應用程式二進位檔案、模擬器或裝置;惡意行為者編寫伺服器端腳本,直接產生模擬 SDK 網路封包的原始 HTTP 請求傳送至歸因伺服器。
為什麼在行動應用程式中儲存加密機密是不安全的?
行動應用程式在不受信任的客戶端環境中執行,用戶擁有實體與軟體控制權。攻擊者可以反編譯套件、使用動態掛鉤工具檢查執行時記憶體或提取字串常數。任何嵌入在客戶端二進位檔中的金鑰都必須被視為可提取的,使得客戶端金鑰無法證明請求的真實性。
動態 Nonce 如何防止歸因端點上的重放攻擊?
Nonce 是包含在每個簽署請求中的唯一一次性 Token。當歸因伺服器處理經驗證的請求時,它會檢查其分散式一致性儲存(如 Redis)以確認該 Nonce 未曾出現,並將其與涵蓋剩餘時間戳有效視窗的存活時間 (TTL) 一併儲存。若攻擊者重放已擷取的請求,伺服器會在快取中檢測到重複的 Nonce 並拒絕該請求。

總結與決策框架

保護行動歸因追蹤以防禦 SDK 欺詐,需要超越靜態的客戶端嵌入式機密,轉向穩健的雙層加密架構。SDK 欺詐讓惡意行為者能夠在無需實體裝置的情況下偽造轉換,盜取行銷資金並腐蝕活動優化模型。

建構有彈性的防欺詐管線,取決於在伺服器對伺服器通訊中強制執行 HMAC-SHA256 身份驗證標籤、維護動態 Nonce 快取以封鎖重放攻擊,以及整合硬體輔助的平台完整性認證(如 Google Play Integrity 與 Apple App Attest)。透過將獨立的衡量引擎與嚴謹的加密驗證結合,像 OpoInstall 這樣的平台提供了檢查請求真實性、提高合成攻擊成本並支援強大接收身份驗證所需的基礎設施。

若要評估整合歸因與加密安全基礎建設如何保護您的行銷活動,請探索 行動歸因實作參考 或在 OpoInstall 開發者控制台 上配置您的應用程式。

相關資料

Share this article