Python 官方在 discuss.python.org 發布公告,說明印度憑證機構 eMudhra(emSign)的中繼 CA 安全事件對 Python 使用者的影響。由於 eMudhra 有 8 張中繼 CA 憑證的私鑰產生方式有缺陷,任何人都能從公開的憑證推算出私鑰,進而簽發任意網站的憑證,對 pypi.org、python.org 在內的任何 TLS 連線發動中間人攻擊。pip、certifi、uv、conda、pixi、sigstore 與 CPython 本身都已陸續釋出更新。
CyberQ 實務上也處理了相關伺服器與不同場域的應用更新,針對這次的事件、Python 相關元件的修補版本與建議動作做了實作紀錄,並附上一台 Ubuntu 24.04 工作站上的實測結果。實測發現 Python 直譯器本身沒有受到影響,但有幾個用 Python 寫成的工具內附自己的憑證包,仍然信任遭外洩的 CA。
事件經過
根據社群整理的事件說明網站 emudhra.we-have-a-problem.com,時間軸如下:
| 日期 | 事件 |
|---|---|
| 2025 年 4 月 | 受影響的中繼 CA 憑證簽發 |
| 2026-10-17 | 通報者 Wayne 向各大根憑證計畫通報,並以 8 把私鑰分別簽署「We have a problem here」作為證明;Firefox 與 Chrome 開始封鎖 |
| 2026-10-19 | 向下游憑證庫維護者揭露 |
| 2026-10-20 | Microsoft 平台開始封鎖;事件網站公開;Python 官方發布公告 |
| 2026-10-21 | OpenJDK 發布公告;CPython 3.15.1、3.14.9、3.13.17 發布 |
| 2026-10-22 | Apple 開始封鎖 |
問題出在私鑰本身。CPython 核心開發者 Christian Heimes 在討論串中說明,8 張中繼 CA 的橢圓曲線私鑰數值都小於 256,例如 d=4。這種私鑰等同公開,只要拿到憑證,就能在極短時間內算回私鑰。
這些中繼 CA 有兩條信任鏈。一條接到 emSign ECC Root CA – G3,另一條透過 Sectigo 的交叉簽署接到 Comodo AAA Services root(憑證主體名稱為 AAA Certificate Services)。只移除 emSign 的根憑證並不夠,交叉簽署那條鏈也必須處理。Heimes 也指出,交叉簽署所用的較舊根憑證早就存在於舊版 certifi 中,因此即使是在中繼 CA 簽發之前就打包的舊版 pip,同樣會受影響。
這些中繼 CA 從未登錄在憑證透明度(Certificate Transparency,CT)日誌中。Chrome、Firefox、Edge、Safari 等會強制檢查 CT 的瀏覽器不會接受這類憑證。真正有風險的是不檢查 CT 的程式,包括 curl、各語言的 HTTP 函式庫,以及 pip。事件網站表示,目前無法確認是否已有攻擊者對這類客戶端實際利用過這些私鑰。
為什麼 Python 的 pip 特別需要注意
pip 內附一份 certifi,而且在使用系統憑證庫的同時,一律會載入這份內附的 CA 清單。也就是說,就算作業系統已經把受影響的根憑證移除,舊版 pip 仍然會信任它們,設定 REQUESTS_CA_BUNDLE 或使用 --cert 也只能追加 CA,無法排除內附的那份。Heimes 在討論串中強調,唯一可靠的作法是把 pip 升到 26.2.2 以上。
另一個難題是「用有問題的 pip 去升級 pip」。如果升級時連線被攔截,攻擊者可以直接換掉下載的 pip。公告因此提供了一個指定 wheel 網址與 SHA-256 雜湊的安裝指令,pip 會在安裝前比對雜湊:
python -m pip install "pip @ https://files.pythonhosted.org/packages/3f/06/3e4420302363fbb71be3c7f35ce042f54bfca330e3e66b3a2e3c4cca579f/pip-26.2.2-py3-none-any.whl#sha256=fd7f4dfa8190e014013b9f08f3e973f4e4c26ffd179a204895533a7254813a70"
Debian 與 Ubuntu 是例外。這兩個發行版修改過套件庫中的 pip,讓內附的 certifi 改為指向系統憑證庫 /etc/ssl/certs/ca-certificates.crt,因此只要更新 ca-certificates 套件即可。
各元件修補版本
| 元件 | 修補版本 | 說明 |
|---|---|---|
| certifi | 2026.10.19 | 公告列出 2026.10.18,但該版把所有 emSign 根憑證都移除了;2026.10.19 把未受影響的 G1、C1、C3 加回來,建議直接用 2026.10.19 |
| pip | 26.2.2 | 必須升級,只更新系統憑證庫對 pip 無效 |
| uv | 0.13.4 | 也可在系統憑證庫已更新的前提下用 UV_SYSTEM_CERTS=true |
| sigstore | 4.5.1 | |
| conda | 26.9.4 | |
| pixi | 0.82.1 | |
| CPython | 3.15.1、3.14.9、3.13.17 | 10/21 加速發布,內附的 pip 與 certifi 已更新 |
| cibuildwheel | 4.3.4 | 4.3.3 的 Python 3.9 環境仍帶有問題的 pip |
| gh-action-pypi-publish | 1.14.3 | |
| Ubuntu ca-certificates | 20260816ubuntu0.24.04.1 等 | 22.04、24.04、26.04、26.10 各有對應版本 |
CPython 另外在 ssl 模組加入一份阻擋清單(gh-160042),只要啟用憑證驗證,就會比對並拒絕這 8 張中繼 CA 的公鑰。這屬於縱深防禦,Python 核心團隊表示會回移到各維護分支。
Python 3.11 與 3.12 不會為此另外發布新版。核心開發者 Hugo van Kemenade 在討論串中說明,pip 原本就不會在安全性更新中升級,使用者可以自行更新 pip。Docker 官方的 python 映像檔是由下游維護,3.11 與 3.12 的映像檔不會因此更新,截至 10/21,3.15 映像檔也仍然內附 pip 26.2.1。
建議動作
- 以雜湊驗證的方式把 pip 升到 26.2.2,使用上一節的指令。每個既有的虛擬環境都要各自升級,而且新建虛擬環境之後也要記得再升一次,除非使用的 Python 本身已經內附新版 pip。
- 升級 certifi 與 uv。先用已升級的 pip 執行
python -m pip install --upgrade certifi。uv 可以直接uv self update,或在系統憑證庫已更新的前提下使用UV_SYSTEM_CERTS=true uv self update。 - 更新作業系統的 ca-certificates。Debian 與 Ubuntu 的 pip 依賴它;其他不使用 certifi 的程式也會受惠。
- macOS 上 python.org 安裝版另外內附一份 certifi,必須連同 pip 一起升級,各個版本(含 3.15t 等 free-threaded 版本)都要處理。
- 容器停用快取重新建置,確保拿到最新的系統憑證與 pip。官方映像檔更新前,可以設定
PIP_CERT=/etc/ssl/certs/ca-certificates.crt,讓 pip 改用已更新的系統憑證庫。 - 檢查內附憑證包的工具。許多 Python 工具不使用 certifi,而是自帶一份 CA 清單,例如 grpcio 的
roots.pem與 botocore 的cacert.pem。這些不會因為更新 pip 或 certifi 而改變,下一節的實測就遇到這種情況。
事件網站提供了檢測主機,可以直接測試自己的環境。下列兩個網址若能正常連上,代表該程式信任受影響的中繼 CA:
curl https://dv-g3b-emudhra.we-have-a-problem.com/
curl https://dv-g3b-aaa-emudhra.we-have-a-problem.com/
第一個測試 emSign ECC Root CA – G3 這條鏈,第二個測試 Sectigo 交叉簽署到 AAA Certificate Services 這條鏈。連線失敗並出現憑證驗證錯誤才是正確結果。
需要提醒的是,用 gcloud、aws 這類 CLI 搭配端點覆寫去連檢測主機時,測試這類工具請先登出,或使用 --no-sign-request 之類不帶憑證的參數。
本機實測
筆者這台工作站執行 Ubuntu 24.04(aarch64),當天稍早才把 uv 管理的 Python 升到 3.12.15 與 3.11.17。檢查範圍包括系統 Python、uv 管理的 Python、9 個虛擬環境(含 uv tool 安裝的工具),以及家目錄、/usr/local、/usr/lib/python3 底下所有 cacert.pem、roots.pem 這類憑證包。每個憑證包都直接拿來當作 CA 檔,連一次上述兩個檢測主機。
Python 直譯器與 pip:沒有受影響

- 系統憑證庫:ca-certificates 已是 20260816ubuntu0.24.04.1,也就是事件網站列出的 Ubuntu 24.04 修補版。
/etc/ca-certificates.conf中,emSign ECC Root CA – G3 與 Comodo AAA Services root 都已被標為停用(前面加上!)。 - Python 直譯器:系統 Python 3.12.3(OpenSSL 3.0.13)、uv 管理的 3.12.15 與 3.11.17(OpenSSL 3.5.9)使用預設 SSL 設定時,兩個檢測主機都連不上。
- pip:uv 這次下載的 3.12.15 與 3.11.17 建置版本,ensurepip 內附的已是 pip 26.2.2。這點與 python.org 官方版本不同:官方的 3.12.15 與 3.11.17 是在事件之前發布的,不會為此更新。各虛擬環境中的 pip 則是 Ubuntu 修改過的 24.0,內附 certifi 實際指向系統憑證庫。
要注意的是,3.12.15 與 3.11.17 還沒有 ssl 模組的阻擋清單。CyberQ 實測把舊版 certifi 的憑證包當作 CA 檔傳給這兩個版本,仍然能連上檢測主機。換句話說,這兩個版本之所以安全,是因為系統憑證庫已經修補,而不是 Python 本身擋下了這些中繼 CA。
另外,各虛擬環境中 pip 內附的 cacert.pem,以及系統的 /usr/lib/python3/dist-packages 底下 certifi、botocore 的 cacert.pem 檔案,內容都還包含受影響的根憑證,拿來當 CA 檔也確實能連上檢測主機。不過 Ubuntu 的修改讓這些套件實際讀取的是系統憑證庫,這些檔案只是殘留,不會被使用。
用 Python 寫的工具:有 4 處仍信任遭外洩的 CA
真正有問題的是自帶憑證包的工具:
| 位置 | 修補前 | 信任的鏈 | 處理方式 | 修補後 |
|---|---|---|---|---|
| analytics-mcp(uv tool) | certifi 2026.7.22、grpcio 1.84.0 | emSign G3 | uv tool upgrade | certifi 2026.10.19、grpcio 1.84.1 |
| awscli(uv tool) | 1.46.1,內附 botocore 的 cacert.pem | AAA 交叉簽署 | uv tool upgrade | 1.46.2 |
| Google Cloud SDK | 587.0.0,內附 certifi 2021.10.08 等 | emSign G3(bq 的 certifi 兩條都有) | 更新到 590.0.0 仍未修補,改設定 core/custom_ca_certs_file | 改用系統憑證庫 |
系統 Python 的 /usr/local | grpcio 1.78.0 的 roots.pem | 兩條都有 | pip install grpcio==1.84.1 | 1.84.1 |

grpcio 與 awscli 都在 10 月 21 日至 22 日釋出新版,新版內附的憑證包已移除兩個根憑證。Google Cloud SDK 更新到當時最新的 590.0.0 後,內附的 certifi 仍是 2021.10.08,所以筆者改用 gcloud 的設定,讓它與 gsutil、bq 都改讀系統憑證庫:
gcloud config set core/custom_ca_certs_file /etc/ssl/certs/ca-certificates.crt
這個設定只是暫時措施,前提是系統憑證庫已經更新。等 Google Cloud SDK 更新內附的憑證包後,可以用 gcloud config unset core/custom_ca_certs_file 移除。
系統 Python 的 grpcio 只升級 grpcio 本身。同時安裝的 grpcio-reflection 1.84.1 需要 protobuf 7,與既有環境的 protobuf 6.33.5 衝突,因此維持在 1.78.0;它只要求 grpcio 1.78.0 以上,相容性沒有問題。

自行檢查的方法
CyberQ 指出,除了用 curl 測試,也可以用 Python 測試預設 SSL 設定是否會擋下這些中繼 CA:
python3 -c "import urllib.request; urllib.request.urlopen('https://dv-g3b-emudhra.we-have-a-problem.com/')"
出現 CERTIFICATE_VERIFY_FAILED 才是正確結果。要找出內附憑證包的工具,可以搜尋含有受影響根憑證名稱的檔案:
grep -rl -e "emSign ECC Root CA - G3" -e "AAA Certificate Services" ~ /usr/local/lib /opt --include="*.pem" --include="*.crt" 2>/dev/null
搜尋結果中的檔案不一定會被使用,必須再確認程式實際讀取哪一份。例如 Debian 與 Ubuntu 修改過的 certifi,可以用 python3 -c "import certifi; print(certifi.where())" 查看實際路徑。
結論
這次事件中,瀏覽器靠 CT 檢查與自身的封鎖機制,在通報當天就已經保護使用者;真正需要動手處理的是伺服器、開發環境與 CI 中不檢查 CT 的程式。對 Python 使用者而言,重點有三個:
- pip 必須升到 26.2.2 以上,只更新系統憑證庫不夠。
- Python 3.11 與 3.12 不會發布新版,官方 Docker 映像檔也不會跟進,必須自行升級 pip。
- 「Python 沒事」不代表「用 Python 寫的工具沒事」。grpcio、botocore、Google Cloud SDK 這類自帶憑證包的工具,請全部要逐一檢查並更新。
CyberQ 手邊的工作站在升級前,Python 直譯器與 pip 就已經安全,但 awscli、gcloud 與兩處 grpcio 仍然信任遭外洩的 CA,必須另外處理。建議讀者除了照公告升級 pip 與 certifi 之外,也用檢測主機實際測一次自己常用的工具。
延伸閱讀
Python 官方公告:Information for Python users regarding eMudhra / emSign CA certificate security incident
事件說明與檢測主機:emudhra.we-have-a-problem.com
certifi 安全公告:GHSA-6q48-6c7w-9gw2
uv 安全公告:GHSA-hq85-5cpj-mr62
conda:eMudhra security updates
CPython ssl 阻擋清單:gh-160042







