"它是開源的,所以它是安全的。"
我總是聽到這種說法。想法很簡單:如果代碼是公開的,那麼一定有人審查過它。漏洞就會被發現。社群會去修復它們.
我決定用實際數據來測試這個假設。
我從 F-Droid 下載了 10 款流行的開源 Android 應用程式 — 這些是每天有數百萬人使用的應用程式 — 並將它們通過了我的靜態分析安全掃描器。接著我手動驗證了每一個發現,對應的 decompiled APK 程式碼。
結果:10 款應用程式中有 60 個確認的漏洞。
應用程式
我故意選擇了不同類別中知名度高且持續維護的應用程式:
- AntennaPod — Podcast 管理器
- Bitcoin Wallet — 加密貨幣錢包
- DAVx5 — CalDAV/CardDAV 同步
- GnuCash Android — 會計軟體
- K-9 Mail — 郵件客戶端
- KeePassDX — 密碼管理器
- NewPipe — YouTube 前端
- Nextcloud — 雲端儲存客戶端
- Signal — 加密通訊軟體
- VLC — 媒體播放器
這些不是被遺棄的副項目。它們是成熟的、受歡迎的應用程式,擁有活躍的開發者社群。其中一些處理極其敏感的數據 — 密碼、加密貨幣、私人訊息、財務記錄.
方法論
針對每個應用程式我:
- 從F-Droid下載APK
- 運行我的靜態分析掃描器 (自動化SAST,涵蓋清單分析、smali代碼分析、原生庫檢查、汙染分析及加密檢查)
- 使用apktool反編譯APK以獲取smali代碼、清單及資源
- 人工核實每個發現與實際反編譯代碼對比 — 核實標記的代碼是否真正易受攻擊或為假陽性
這最後一步至關重要。自動掃描器會產生很多候選項。沒有手動驗證,你不知道什麼是實際的,什麼是噪音.
我發現的:5 個最常見的漏洞
在仔細驗證了 10 個應用程式的所有發現後,清晰的模式顯現出來。相同的錯誤一再出現——無論應用程式的普及程度或其處理數據的敏感性如何。
1. 未經授權保護的導出組件
發現於:10個應用程式中的9個
Android組件(活動、服務、接收器、內容提供者)被宣告為exported="true",而無需任何權限即可與它們互動。這意味著任何安裝在同一設備上的應用程式都可以啟動這些組件、向它們發送數據,或從它們接收數據。
為何這很危險:在一個金融應用程式中,這可能意味著惡意應用程式可以啟動「發送錢」的畫面。在一個密碼管理器中,它可能觸發資料庫解除鎖定流程。在一個電子郵件客戶端中,它可能啟動填好預設資料的草稿畫面.
修正方法很簡單 — 對不需要外部訪問的組件設定 exported="false",或者添加一個android:permission 用於限制誰可以與它們互動.
2. 文件提供者路徑過於寬泛
發現於:10個應用程式的4個
安卓的FileProvider是設計用於在應用程式之間安全地分享文件。但當提供者的路徑配置包含<root-path path="." />或<external-path path="." />,它能有效地通過內容URI授權訪問整個文件系統或所有外部存儲空間。
我發現了一些應用程式,其中FileProvider的配置允許訪問/storage/(所有外部存儲空間)、整個應用程式內部目錄,在最壞的情況下,甚至是整個設備的文件系統。
儘管這些提供者通常是非導出的,但它們使用grantUriPermissions="true" — 所以如果任何導出的活動傳遞 URI 權限(一種常見的 Android 模式),廣泛的路徑就會變得可被利用。
3. 允許明文流量 + 使用者 CA 信賴
發現於:10 個應用程式中的 6 個
許多應用程式在其網路安全性設定中具有 cleartextTrafficPermitted="true",允許未加密的 HTTP 連接。幾個也明確信任使用者安裝的 CA 証明書與<certificates src="user" />.
對於連接自訂伺服器的應用程式(CalDAV、電子郵件、雲端儲存),這部分是故意的——使用者需要連接他們自己的伺服器,這些伺服器可能使用HTTP或自簽名憑證。但這個設定是全域性的,不僅適用於自訂的終端點。應用程式所建立的每一個連接——包括API呼叫、分析、更新檢查——預設允許被攔截。
一個特別令人關注的案例:一個媒體播放器透過明文HTTP下載更新檔案。在同一網路上的一個中間人攻擊者可以將一個惡意APK作為合法更新來提供。
4. 弱加密實現
發現於:10個應用程式中的3個
這些從危險到古老都有:
- SSL驗證完全禁用 — 一個應用程式呼叫了一個字面意思上接受所有憑證而不進行任何驗證的方法。在一個金融應用程式中。處理現金。
- ECB 加密模式 — 一個媒體播放器的遠程訪問功能使用 AES 在 ECB 模式下,其中相同的明文塊產生相同的密文塊。這是一本教科書中的加密錯誤。
-
java.util.Random在加密術語下 — 而不是SecureRandom,使輸出可預測。 - 信任首次使用 (TOFU) 而無釘住 — 一旦接受伺服器憑證,就永遠信任,即使憑證變更(這可能表示存在中間人攻擊)。
5. 缺少鎖定觸屏 (疊加攻擊) 保護
發現於:10 應用程式中 8 個
幾乎沒有應用程式設置filterTouchesWhenObscured="true" 在敏感的UI元素上。這意味著惡意應用程式如果有疊加權限,可以在應用程式上方繪製一層不可見的層,並捕捉用戶的點擊 — 或者騙用戶點擊他們沒有打算點擊的按鈕。
這對於以下情況尤其令人擔憂:
- 密碼管理器(捕捉主密碼輸入)
- 加密貨幣錢包(確認交易)
- 證書信任對話方塊(接受惡意證書)
- OAuth/登入螢幕(授權存取)
這代表什麼
開源不代表自動安全。它表示程式碼是 可供檢閱 — 不是表示它 已經被 已經評估。這些是備受歡迎、維護良好的應用程式,擁有活躍的社群,但它們仍然存在安全問題,這些問題可以透過系統性的評估來發現。
這不是要羞辱開發者。開源維護者通常是義工,從事非凡的工作。重點在於,安全需要專注、集中的注意。這與開發功能的技能不同,並且受益於專用的工具和專業知識。
若您的 Android 应用處理敏感資料 — 財務信息、憑證、個人通訊、健康資料 — 它值得一個安全性審查. 不僅僅是自動掃描產生數百個候選項就結束,而是一個正確的評估,其中每個發現都經過驗證和語境化.
主要收穫
自動掃描器發現候選項,而不是確認的漏洞。 沒有手動驗證,你不知道什麼是真的。
几乎每個應用程式都出現相同的 5 個漏洞模式。 輸出的組件、廣泛的檔案提供者、明文流量、弱加密和缺失的疊加保護。這些是任何安全審查都應該發現的低垂果實。
背景資訊極其重要。 媒體播放器串流公眾影片的明文交通,與銀行應用程式的明文交通所面臨的風險不同。沒有背景資訊的安全發現,僅僅是報告中的一行文字。
開源軟體促進了安全審查,但它並不能取代審查。 語言公開是進行全面分析的先決條件,而不是保證分析已經發生。
我是一名專業從事安卓應用程式安全評估的移動安全研究者。如果您想討論您的應用程式的安全性,隨時可以透過yehor.mamaiev@gmail.com聯繫我。











