金流串接的資安底線:五件你不做就等著出事的事
金流串接的技術門檻其實不高,大多數工程師看完文件花一兩天就能讓付款流程跑起來。但「能跑」和「安全」之間的距離,往往是一場資安事件的距離。以下五件事是金流系統的絕對底線,少做任何一件都可能讓你的系統暴露在風險中。
第一,ReturnURL 收到通知時必須驗證 CheckMacValue。綠界在推送付款結果時會附上一組 CheckMacValue,這是用你的 HashKey、HashIV 和所有回傳參數計算出來的雜湊值。你的伺服器在處理通知時,必須用同樣的規則重新計算一次,確認兩者一致後才能信任這筆資料。如果你跳過這個驗證,任何人只要知道你的 ReturnURL 格式,就能偽造一筆「付款成功」的通知,讓你在沒收到錢的情況下出貨。
第二,HashKey 和 HashIV 絕對不能出現在前端程式碼中。這聽起來像是常識,但在 Next.js 或 Nuxt.js 等同構框架中,環境變數如果沒有正確區分 server-only 和 public,很容易在打包後被塞進瀏覽器端的 JavaScript Bundle。一旦 HashKey 洩漏,攻擊者就能自行計算合法的 CheckMacValue,完全繞過你的驗證機制。建議將這兩個值存放在伺服器端的環境變數中,並透過 CI/CD 管道注入,永遠不要寫死在程式碼裡。
第三,正式環境必須關閉 SimulatePaid 功能。綠界的測試環境提供了「模擬付款」功能,讓你可以在不真正扣款的情況下觸發 ReturnURL 通知,這在開發階段非常方便。但這個功能只存在於測試環境。真正的風險在於:如果你的程式邏輯中有判斷 SimulatePaid 參數並做特殊處理(例如跳過金額驗證),在切換到正式環境時忘記移除這段邏輯,攻擊者就可能利用這個缺口。最佳做法是在正式環境中完全忽略 SimulatePaid 參數,或直接在程式碼中加入環境判斷。
第四,ReturnURL 必須使用 HTTPS 並走 443 Port。綠界明確要求 ReturnURL 只支援 HTTP 80 和 HTTPS 443 兩個標準端口。如果你的伺服器跑在非標準端口(例如 8080),通知就會送不到。更重要的是,付款結果通知中包含交易金額和訂單編號等敏感資訊,如果你的 ReturnURL 走的是未加密的 HTTP 連線,這些資料在傳輸過程中就有被攔截竄改的風險。
第五,每筆通知都要做冪等性處理,並驗證金額一致。即使 CheckMacValue 驗證通過,你仍然需要比對通知中的 TradeAmt 是否等於你在建立訂單時設定的金額。這是為了防止一種罕見但可能的攻擊:攻擊者攔截合法通知後修改金額。有了金額比對,即使其他環節出了問題,你的系統也多了一道防護。同時,由於綠界可能重試通知,你的處理邏輯必須確保同一筆訂單不會被重複更新——這就是冪等性的核心概念。
這五件事沒有一件是「進階議題」,它們都是基本功。但根據社群的討論和實際的事件案例,超過半數的金流串接專案至少會漏掉其中一項。在你的系統上線前,請逐一核對這份清單。