Third-Party Code#

現代網站幾乎不可能從零開始建構所有程式碼。從作業系統、網頁伺服器到程式語言函式庫,大部分的程式碼都是由他人撰寫的。駭客經常鎖定熱門軟體元件中的已知漏洞進行攻擊,因此保護第三方程式碼的安全至關重要。

本章討論三個面向:保護你的 dependencies(依賴套件)、確保正確的 configuration(組態設定),以及安全地使用第三方 services(服務)。

保護依賴套件(Securing Dependencies)#

2014 年 4 月,OpenSSL 被揭露存在 Heartbleed 漏洞:攻擊者可透過 buffer over-read 讀取伺服器記憶體中的任意資料,竊取加密金鑰、帳號密碼等敏感資訊。Apache 和 Nginx 都使用 OpenSSL,超過半數的網站一夜之間暴露於風險之中。

所有第三方程式庫——即使是由安全專家撰寫的——都可能存在安全問題。保護依賴套件有三個關鍵面向:知道你在執行什麼程式碼、能夠快速部署新版本、隨時關注安全資訊。

了解你正在執行的程式碼#

現代軟體堆疊複雜且多層,開發過程中很容易加入新的函式庫後就忘記它的存在。

Dependency Management Tools#

大多數程式語言都有 dependency manager(依賴管理工具),允許團隊在設定檔中指定第三方依賴:

  • 在發布程式碼時,設定檔應明確指定每個依賴的 version number
  • 安全公告會指出哪些版本存在漏洞,固定版本號能讓你清楚知道需要修補什麼
  • 注意 dependency tree(依賴樹):你宣告的依賴本身也有依賴,評估安全風險時要考慮整棵依賴樹
npm list

Operating System Patches#

  • 除了程式語言層級的依賴,也需要追蹤作業系統層級的套件
  • 作業系統廠商(如 Red Hat、Microsoft)頻繁發布安全修補
  • 使用 Docker 做容器化是追蹤作業系統依賴的好方法,因為 Docker 設定檔會明確列出安裝的軟體

Integrity Checks#

  • 使用 checksums(校驗碼)確保依賴套件未被竄改
  • 現代瀏覽器支援 Subresource Integrity Checks(子資源完整性檢查),可在 <script><style> 標籤中加入 integrity 屬性
cat FILENAME.js | openssl dgst -sha384 -binary | openssl base64 -A
<script
  src="https://example.com/example-framework.js"
  integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlG"
  crossorigin="anonymous"
></script>

能夠快速部署新版本#

  • 發布流程應該是 reliable(可靠)、reproducible(可重現)、revertible(可回滾)的
  • 依賴管理工具的設定檔應納入版本控制
  • 部署僅包含第三方程式碼變更的 release 仍需執行 regression test(迴歸測試)
  • 投資撰寫良好的單元測試,能讓安全修補的部署更快速、更簡單

隨時關注安全議題#

Social Media#

  • 安全公告透過 Twitter、Reddit、Hacker News 等社群媒體快速傳播
  • 關注技術社群和軟體作者是掌握最新安全動態的好方法

Mailing Lists and Blogs#

  • 訂閱與你技術堆疊相關的 mailing list 和 newsletter
  • 知名安全部落格如 Brian Krebs 和 Bruce Schneier 提供深入的安全評論

Official Advisories#

  • 注意來自託管服務商和軟體廠商的安全警報
  • Microsoft 每週二發布修補(Patch Tuesday

Software Tools#

  • npm audit 可交叉比對依賴版本與已知漏洞資料庫
  • Ruby 有 bundler-audit,Java/.NET 有 OWASP 的 dependency-check
  • GitHub 會自動掃描程式碼並在發現有漏洞的依賴時發出安全警報

何時該升級#

並非所有安全問題都需要立即處理。大型組織有正式的安全警報審查流程,會根據優先級決定行動方案。將次要安全升級納入下次排程的 release 是完全可以接受的,前提是你的團隊已評估過風險。

保護組態設定(Securing Configuration)#

軟體的安全性取決於其組態設定。駭客會頻繁掃描使用預設設定的軟體元件,因為他們知道許多網站管理員不會自訂設定。

資安顧問公司 Offensive Security 維護的 Google Hacking Database 列出了透過簡單 Google 搜尋就能找到的不安全軟體。例如搜尋 index of /etc/certs 就能列出數百萬個暴露數位憑證目錄的網頁伺服器。

停用預設憑證(Disable Default Credentials)#

  • 許多軟體套件附帶預設登入憑證
  • 部署到測試或正式環境前,務必停用這些預設憑證
  • 使用 admin 帳號的資料庫或 CMS 會被機器人快速偵測到

停用目錄列表(Disable Open Directory Listings)#

  • 舊版 Apache 會在 URL 省略檔名時列出目錄內容
  • Open directory listings 讓駭客可以探索檔案系統,搜尋敏感資料和安全金鑰
<Directory /var/www/>
  Options Indexes FollowSymLinks
  AllowOverride None
  Require all granted
</Directory>

移除 Indexes 關鍵字即可防止產生目錄列表。

保護設定資訊#

設定檔通常包含資料庫憑證和 API 金鑰等敏感資訊,不應存放在版本控制系統中。

保護敏感設定的方法:

  • 使用 environment variables(環境變數)在作業系統層級記錄敏感設定
  • 使用專用的 configuration store(如 AWS Systems Manager Parameter Store、Azure Active Directory)
  • 以 AES-128 等演算法加密設定資訊,並將解密金鑰與設定檔分開存放

強化測試環境(Harden Test Environments)#

  • 預生產環境通常安全性較低,但可能包含從正式環境複製的敏感資料
  • 正式和非正式環境不應共用憑證或 API 金鑰

保護管理介面(Secure Administrative Frontends)#

  • 許多軟體元件附帶可透過網際網路存取的管理工具
  • 如不使用管理介面,應停用;如需使用,應移除預設憑證並限制可存取的 IP 範圍

保護你使用的服務(Securing the Services That You Use)#

第三方服務(如 Facebook Login、Google AdSense、Stripe)在現代 Web 開發中廣泛使用。整合這些服務會帶來兩個安全考量:駭客會嘗試竊取你的存取憑證,以及每個第三方服務都是潛在的攻擊向量。

保護你的 API Keys#

  • API 金鑰需要安全地儲存在伺服器的組態設定中
  • 某些 API 發出兩組金鑰:可安全傳遞給瀏覽器的 public key 和必須保存在伺服器端的 private key
  • 確保程式碼不會意外將高權限的 private key 傳送給客戶端
  • 使用 temporary access tokens(臨時存取令牌)來防範 replay attacks(重放攻擊)

保護你的 Webhooks#

  • Webhook 是一種「反向 API」,讓服務提供者在事件發生時向你的網站發送 HTTPS 請求
  • 由於 webhook URL 是公開的,任何人都可以呼叫它
  • 如果服務提供者支援在 webhook 呼叫中附帶憑證,應驗證這些憑證
  • 對於無憑證的 webhook,應透過回呼服務提供者的 API 來驗證通知的真實性

保護第三方提供的內容#

  • 使用者已習慣信任瀏覽器中的鎖頭圖示,駭客會利用這種信任
  • 使用 CDN 或雲端儲存時,確保 DNS 記錄指向有效的 IP 位址
  • 駭客會進行 subdomain takeover(子網域接管):掃描指向未初始化或已停用服務的子網域 DNS 記錄,然後在該 IP 位址上註冊並部署惡意內容

只有在驗證服務已啟用並在你的控制之下後,才進行 DNS 變更。當你更換服務提供者時,應立即撤銷 DNS 變更。

服務作為攻擊向量(Services as an Attack Vector)#

在客戶端整合的第三方服務尤其危險,因為從第三方網域匯入的任何 JavaScript 都帶有安全風險。匯入的程式碼可以讀取頁面 DOM 中的所有內容,包括使用者輸入的敏感資料,也可以修改 DOM 來誤導使用者。

小心 Malvertising(惡意廣告)#

線上廣告是一個龐大的產業,網站擁有者(publisher)訂閱廣告平台,在網頁上預留廣告空間,廣告平台透過 JavaScript 在頁面載入時填入廣告內容。

Malvertising 指的是駭客利用廣告平台作為攻擊向量,透過 exploit kits 判斷瀏覽器和作業系統是否存在漏洞,然後投放惡意的 payload(如重導向腳本、病毒、勒索軟體、挖礦程式碼)。

防範惡意廣告的措施#

使用信譽良好的廣告平台#

  • Google 是廣告領域最大的參與者,透過 AdSenseAdX 提供服務
  • Google 在防禦惡意廣告方面投入大量資源,應優先選擇
  • 較小的廣告平台可能缺乏資源和意願來保護你免受惡意軟體侵害

使用 SafeFrame#

  • 將第三方內容隔離在 <iframe> 標籤中是最有效的方式
  • HTML5 的 sandbox 屬性提供更細緻的控制
  • SafeFrame 是廣告業界採用的標準,規定廣告必須在 iframe 中執行
  • 選擇只顯示符合 SafeFrame 標準的廣告

調整廣告偏好#

  • 確保只顯示來自 Google 認證廣告網路的內容
  • 封鎖快速致富計畫、多層次行銷、可下載工具等類別的廣告

審查並舉報可疑廣告#

  • 定期從廣告平台的後台審查網站上的廣告
  • 舉報並封鎖任何看起來可疑的廣告
  • 記錄使用者離開網站時的外連 URL,追蹤是否有廣告將使用者導向可疑網站

總結#

  • 使用 dependency manager 追蹤第三方依賴,明確指定版本號並納入版本控制
  • 確保建構和部署流程是腳本化的,以便在安全公告發布時快速升級
  • 使用 integrity 屬性驗證匯入的 JavaScript 檔案
  • 確保軟體未使用不安全的組態設定;停用預設憑證和目錄列表
  • 敏感設定(如資料庫憑證、API 金鑰)應存放在專用的 configuration store 中
  • 保護 API 金鑰和 webhook,防範 subdomain takeover
  • 使用信譽良好的廣告網路,啟用 SafeFrame,定期審查廣告內容