摘要
報告探討於 Salesforce Marketing Cloud (SFMC,前身為 ExactTarget) 中發現的重大安全性漏洞。分析重點在於樣板注入(template injection)缺陷(特別是透過 AMPScript 與 Server-Side JavaScript (SSJS))如何被惡意攻擊,以達成未經授權的資料存取以及潛在的遠端程式碼執行。報告詳細說明了主要的惡意攻擊途徑,包括
LookupRows
與
TreatAsContent
等函式的誤用。報告也概述了潛在影響並討論了強化 SFMC 部署安全狀態的緩解策略。
1. 簡介
Salesforce Marketing Cloud (SFMC) 是一個廣泛用於管理大量電子郵件行銷活動與客戶互動的平台。其動態特性由 AMPScript 與 Server-Side JavaScript (SSJS) 等腳本語言驅動,得以實現高度個人化的內容傳遞。然而,這種靈活性也帶來了顯著的攻擊介面,使 SFMC 成為惡意攻擊者的高價值目標 [1] 。先前的研究已指出,類似平台中的漏洞曾導致大規模資料外洩,這突顯了在此類關鍵系統中理解與降低風險的重要性 [1] 。此報告深入探討 SFMC 中發現的漏洞技術細節,重點在於惡意攻擊機制及其對資料安全的影響。
2. Salesforce Marketing Cloud 腳本語言
SFMC 使用專屬的腳本語言,以實現電子郵件與登入頁面中的動態內容生成。兩種主要的語言是 AMPScript 與 Server-Side JavaScript (SSJS)。
2.1. AMPScript
AMPScript 是一種專屬腳本語言,用於 SFMC 中個人化電子郵件、登入頁面與其他內容。其分隔符號為
%%=
與
=%%
。AMPScript 是一種功能豐富的語言,支援變數、條件陳述式、迴圈以及完整的函式庫
[1]
。
一個用於基本計算的 AMPScript 簡單範例:
<code> Hello, %%= mul(7,7) =%%! // This AMPScript snippet performs a multiplication operation. // `mul(7,7)` calculates 7 * 7, which results in 49. // The output would be: Hello, 49! </code>
AMPScript 也可以使用
AttributeValue
等函式來取得特定訂閱者的資料:
<code> Welcome to our mailing list, %%= AttributeValue("fullName") =%%! // This snippet retrieves the 'fullName' attribute associated with the current subscriber. // If the subscriber's full name is "John Doe", the output would be: Welcome to our mailing list, John Doe! </code>
2.2. Server-Side JavaScript (SSJS)
SSJS 在 SFMC 中提供伺服器端 JavaScript 能力,為許多開發者提供了更熟悉的語法。它使用了 Jint JS 函式庫(用於 C#)的一個分支
[1]
。SSJS 程式碼通常被包在
<script runat="server"></script>
標籤內。
一個基本的 SSJS 範例:
<code> <script runat="server"> Platform.Load("Core","1"); Write("Hello world!"); </script> // This SSJS snippet loads the 'Core' library and prints "Hello world!" to the output. // It demonstrates basic server-side scripting capabilities within SFMC. </code>
3. 樣板注入漏洞
樣板注入(template injection)發生於攻擊者能將樣板語法注入至使用者控制的輸入中,而該輸入隨後被樣板引擎處理。在 SFMC 中,這可能導致在 AMPScript 或 SSJS 的環境中執行任意程式碼 [1] 。
3.1. 利用
HttpGet
進行 Blind Injection
測試 Blind Template Injection 的常見方法是使用
HttpGet
函式。此函式用於向指定的 URL 發送 GET request 並回傳其內容。攻擊者可將其用作「Canary」:若在注入帶有唯一 URL 的
HttpGet
後,觀察到對攻擊者控制之伺服器的 DNS 查詢或 HTTP 請求,即可確認樣板內的程式碼執行
[1]
。雖然初期看似可用於 Server-Side Request Forgery (SSRF),但 SFMC 實例通常位於共享租戶雲端環境中,這限制了 SSRF 對 Salesforce 內部網路的影響,且 SFMC 已有針對這類攻擊的防護機制
[1]
。
3.2. 使用
LookupRows
進行資料視圖的惡意攻擊
更具影響力的惡意攻擊涉及存取 SFMC 的系統表格,即所謂的資料視圖 (Data Views)。這些視圖包含機敏資訊,如已發送的電子郵件、SMS 訊息以及完整的聯絡人清單。
LookupRows
函式允許不受限制地查詢這些資料視圖,因此可被利用來擷取這些機敏資料
[1]
。例如,要確定資料庫中的訂閱者人數,攻擊者可注入:
<code> %%= RowCount(LookupRows("_Subscribers","SubscriberKey",_subscriberkey)) =%% // This AMPScript snippet uses the LookupRows function to query the _Subscribers data view. // It counts the number of rows where the SubscriberKey matches the current _subscriberkey. // This can be used to enumerate subscribers or confirm access to the data view. </code>
透過反覆查詢並提取個別記錄,攻擊者可能實現對 SFMC 實例中儲存的所有客戶資料的全面入侵。這包括但不限於已發送的電子郵件 (
_Sent
,
_Job
)、客戶資料 (
_Subscribers
)、已發送的 SMS (
_SMSMessageTracking
) 以及電子郵件點擊資料 (
_Click
)
[1]
。
3.3. 地雷一號:
TreatAsContent
TreatAsContent
函式是關鍵的漏洞點。它會將給予的字串作為 AMPScript 樣板進行解析,這實際上表示若未經適當的清理就將使用者控制的輸入傳遞給它,將允許任意程式碼執行。如果攻擊者能夠將惡意的 AMPScript 注入某個欄位,而該欄位隨後被
TreatAsContent
處理,他們就能達成樣板注入
[1]
。
<code> // Dangerous usage of TreatAsContent SET @user_input = RequestParameter("firstName") SET @processed_content = TreatAsContent(@user_input) // If an attacker provides `firstName=%%= Platform.Function.ContentBlockByName("MaliciousCode") =%%`, // the system will execute the malicious code block. </code>
此函式本意用於動態內容呈現,但當暴露於不受信任的輸入時,就會成為嚴重的安全性風險,使攻擊者能夠執行任意 AMPScript 並進一步惡意攻擊系統。
4. JSON Injection 漏洞
雖然主要文章聚焦於 AMPScript 與 SSJS 漏洞,但考慮其他會危及網頁應用程式的注入向量也至關重要,尤其是那些處理結構化資料的應用程式。JSON Injection 是一種網路安全漏洞,當應用程式在缺乏適當驗證或清理下處理使用者輸入,並將此未經處理的輸入直接嵌入 JSON (JavaScript Object Notation) 資料時就會發生 [2] 。
4.1. JSON Injection 的攻擊機制
攻擊者透過建立惡意輸入來操縱 JSON 資料結構,以利用 JSON Injection 漏洞。這可能導致多種安全性風險,包括資料竄改、資訊揭露,甚至跨站腳本 (Cross-Site Scripting, XSS) 攻擊 [2] 。此攻擊通常包含三個步驟:
- 輸入操縱: 攻擊者將惡意程式碼注入使用者輸入,而應用程式未能正確驗證。
- 嵌入 JSON 資料: 應用程式將此不安全的資料直接嵌入其 JSON 結構中。
- 成功惡意攻擊: 被操縱的 JSON 隨後用於後續操作(例如身分驗證、授權或程式執行),導致攻擊者達成預期目標。
考慮一個應用程式使用使用者提供的電子郵件來建構 JSON 物件的場景:
<code> // Original vulnerable code snippet jGenerator.writeRawValue("\"" + email + "\""); // If 'email' contains malicious JSON, it can break the structure. // Example: email = "attacker@example.com","isAdmin":true} // Resulting JSON: {"user":"attacker@example.com","isAdmin":true} </code>
在此範例中,如果
email
變數未經適當清理,攻擊者可以注入額外的 JSON 欄位,從而改變應用程式的邏輯。例如,將
", "isAdmin":true}
注入電子郵件欄位,若應用程式將其解析為有效的 JSON,則可能使攻擊者取得管理員權限
[2]
。
4.2. JSON Injection 的緩解策略
預防 JSON Injection 攻擊對於處理 JSON 資料的應用程式至關重要。關鍵緩解策略包括 [2] :
- 輸入驗證與過濾: 所有使用者輸入都必須經過嚴格的驗證與過濾,以排除潛在的惡意程式碼。採用白名單方法來限制輸入內容,確保僅接受符合預期格式的資料。
- 安全編碼: 將使用者輸入嵌入 JSON 時,必須對特殊字元使用適當的編碼,以防止惡意程式碼成為 JSON 結構的一部分。
- 現代框架與函式庫: 使用內建安全機制的現代開發框架與函式庫,可以自動處理使用者輸入並防範常見的攻擊(如 JSON Injection)。
- 安全性測試: 在開發過程中定期進行原始碼審查與滲透測試,對於在部署前識別與修復潛在漏洞至關重要。
示範安全 JSON 處理的更正後程式碼片段:
<code> // Corrected secure code snippet jGenerator.writeString(email); // This method ensures that the 'email' string is properly escaped and enclosed in quotes, // preventing any malicious JSON from being injected into the structure. </code>
5. SFMC 漏洞的一般緩解策略
為了保護 SFMC 部署免受樣板注入及類似漏洞的影響,需要多層次的安全性方法:
-
嚴格的輸入清理:
所有使用者提供的輸入(特別是由 AMPScript 或 SSJS 函式處理的欄位)都必須經過嚴格的清理與驗證。這包括用於
TreatAsContent與AttributeValue等函式中的參數。 - 最小權限原則: 將 SFMC 使用者與 API 整合的權限限制在僅執行其功能所必需的範圍。這能降低遭入侵帳號的潛在影響。
- 定期安全性稽核與滲透測試: 經常執行安全性評估以識別並修補漏洞。自動化工具與人工審查有助於偵測潛在的安全性問題。
- 安全編碼實務: 開發人員應接受 AMPScript 與 SSJS 安全編碼實務的教育,了解與動態內容生成及資料存取函式相關的風險。
- 監控異常活動: 實施健全的日誌記錄與監控,以偵測異常活動,例如意外的資料視圖查詢或來自 SFMC 實例的對外 HTTP 請求。
- 修補程式管理: 讓 SFMC 實例及任何整合系統保持 Salesforce 提供的最新安全性修補程式更新狀態。
6. 結論
Salesforce Marketing Cloud 雖然在其動態內容能力方面相當強大,但由於其腳本語言固有的靈活性,也帶來了顯著的安全挑戰。透過 AMPScript 與 SSJS 的樣板注入等漏洞(特別是在
TreatAsContent
與
LookupRows
等函式被誤用時),可能導致嚴重的資料外洩以及對機敏客戶資訊的未授權存取。此外,像是 JSON Injection 等相關注入技術凸顯了在所有網頁應用程式中進行嚴格輸入驗證與安全編碼實務的更廣泛需求。透過理解這些攻擊向量並實施全面的緩解策略,組織可以顯著強化其 SFMC 環境的安全狀態,並保護寶貴的客戶資料免於被惡意攻擊。