OWASP Top 10 2025 白話版:我丟給新人的第一份清單,也是我面試最愛問的題目
我面試最愛問的一題
「你聽過 OWASP Top 10 嗎?」
九成的人會說聽過。接著我請他隨便講幾個,通常會得到「SQL Injection、XSS……嗯……CSRF?」然後就停在那裡。
這個答案不能算錯,但它暴露了一件事:這個人是把 OWASP Top 10 當成一份漏洞名詞的口訣在背,而不是當成一張地圖在用。
我真正想聽的是這種回答:「排第一的一直是存取控制失效,因為它幾乎沒辦法靠工具自動掃出來——工具不知道『這個 user 該不該看這筆訂單』,只有你的商業邏輯知道。」
講得出這句話的人,我大概就知道他真的踩過坑。
而現在時機正好:OWASP Top 10 睽違四年改版了,2025 版是這份清單的第八版,上一版還停在 2021。如果你手上那份筆記是 2021 的,有兩個分類是全新的、有一個舊分類整個被吃掉、還有幾個名字改了。這篇就是我拿來帶新人的那份講義。
先講清楚:它不是什麼
新人最容易誤會的三件事,我每次都要先講。
第一,它不是「十大漏洞」,是「十大風險分類」。 SQL Injection 不是 Top 10 的其中一項,它只是 A05 Injection 這個分類底下的一種。2025 版十個分類加起來一共收了 248 個 CWE(Common Weakness Enumeration,弱點類型的標準編號)。所以講「Top 10 有十個漏洞」是講錯的。
官方在導論裡其實有回答為什麼不乾脆列十個 CWE 就好——因為不是每個 CWE 都存在於每種語言和框架,而且同一件事常常有好幾個 CWE 編號可以用(光是「injection」相關的就有一大票)。用分類才能把不同編號但同一種病因的東西收在一起。
第二,它不是完整清單。 MITRE 的 CWE 字典在這版發布時有 968 個條目,Top 10 只碰到其中 248 個。過了這十關不代表你安全,只代表你沒踩到最常見的坑。
第三,它不是稽核標準。 官方自己的定位是 awareness document,「意識文件」。你不能拿 Top 10 去做驗收——那是 ASVS(Application Security Verification Standard)的工作。Top 10 是入門地圖,ASVS 才是檢查表。
面試時如果對方能主動把這三件事講出來,我通常就不用再往下問基礎題了。
2025 版哪裡不一樣
先看變動,因為大家第一時間都最想知道新舊版有什麼差異。
flowchart LR
subgraph L["2021 版"]
direction TB
O1["A01 Broken Access Control"]
O2["A02 Cryptographic Failures"]
O3["A03 Injection"]
O4["A04 Insecure Design"]
O5["A05 Security Misconfiguration"]
O6["A06 Vulnerable and<br/>Outdated Components"]
O7["A07 Identification and<br/>Authentication Failures"]
O8["A08 Software and Data<br/>Integrity Failures"]
O9["A09 Security Logging and<br/>Monitoring Failures"]
O10["A10 SSRF"]
end
subgraph R["2025 版"]
direction TB
N1["A01 Broken Access Control"]
N2["A02 Security Misconfiguration"]
N3["A03 Software Supply<br/>Chain Failures"]
N4["A04 Cryptographic Failures"]
N5["A05 Injection"]
N6["A06 Insecure Design"]
N7["A07 Authentication Failures"]
N8["A08 Software or Data<br/>Integrity Failures"]
N9["A09 Security Logging and<br/>Alerting Failures"]
N10["A10 Mishandling of<br/>Exceptional Conditions"]
end
O1 --> N1
O10 -.被吸收.-> N1
O5 --> N2
O6 -.擴大範圍.-> N3
O2 --> N4
O3 --> N5
O4 --> N6
O7 -.改名.-> N7
O8 -.改名.-> N8
O9 -.改名.-> N9
用講的就是這幾件事:
兩個新面孔。 A03 軟體供應鏈失效,是把 2021 的「使用有已知漏洞的元件」整個擴大——不再只管你的 npm 套件有沒有 CVE,而是連建置系統、CI/CD、artifact 倉庫、開發者的筆電全都算進來。A10 例外狀況處理不當則是全新分類,講的是錯誤處理、邏輯錯誤、fail open 這一票事。
一個被吃掉。 2021 的 A10 SSRF 沒有消失,它被併進 A01 存取控制失效裡了(CWE-918 現在掛在 A01 底下)。這題面試很好用:問「SSRF 到 2025 版跑去哪了」,能答出「被歸到 A01,因為 SSRF 本質上就是繞過存取控制去打內網」的人,是真的理解而不是背的。
三個改名。 A07 從「Identification and Authentication Failures」簡化成「Authentication Failures」;A08 從 Software and Data 改成 Software or Data;A09 從 Logging and Monitoring 改成 Logging and Alerting。
A09 這個改名最有內容。官方的說法是要強調 alerting——「great logging with no alerting is of minimal value」,只記 log 卻沒有告警機制,對於發現事件的價值微乎其微。這句話我覺得每個做維運的人都該貼在螢幕上。
四個換位。 Security Misconfiguration 從 #5 衝到 #2,Cryptographic Failures 從 #2 掉到 #4,Injection 從 #3 掉到 #5,Insecure Design 從 #4 掉到 #6。
注意「掉」不等於「變安全了」。Injection 依然是所有分類裡 CVE 數量最多的(六萬多筆)。它往下掉,主要是因為別人升上來了。
十個風險,一個一個白話講
每一項我都用同一個格式:一句話、真實場景、怎麼防、面試會問什麼。
A01:2025 存取控制失效(Broken Access Control)
一句話:這個人登入了,但他能碰的東西超過他該碰的範圍。
蟬聯第一名,而且是壓倒性的——官方資料裡,受測應用有 100% 都被找出某種形式的存取控制問題,這個分類收了 40 個 CWE,是所有分類裡最多的。
最經典的場景:你的 API 是 /api/orders/1234,使用者把網址改成 1235,就看到別人的訂單。這叫 IDOR(不安全的直接物件參照),現在的 API 安全圈更常叫它 BOLA。程式碼裡通常長這樣——查得到那筆訂單,但忘了檢查那筆訂單是不是屬於這個人。
其他常見形態:把權限檢查寫在前端(攻擊者直接 curl 就繞過了)、JWT 拿到手就信不驗簽、CORS 開太寬、目錄列表沒關讓人翻到 .git。
怎麼防,記三句:
- 預設拒絕。 除了公開資源,其他一律先擋,明確允許才放行。
- 權限檢查只寫一次,全站重用。 每個 controller 各寫一份,遲早有一個會忘記。
- 一定要在伺服器端。 前端的檢查是 UX,不是安全機制。
💡 面試我會問:「你怎麼確認一個使用者只能看到自己的資料?」我想聽的是「查詢的時候就把 owner 條件帶進 WHERE,而不是查完再判斷」,以及「這種東西要寫進整合測試,用 B 的 token 去打 A 的資源,預期拿到 403」。
A02:2025 安全設定錯誤(Security Misconfiguration)
一句話:程式沒寫錯,是你把開關打錯了。
從第五名衝到第二名。官方的解釋很直白:軟體行為愈來愈多是靠設定決定的,設定變多,設錯的機會自然變多。同樣有 100% 的受測應用被找出某種設定問題。
真實場景就是那些每年都上新聞的事:S3 bucket 設成公開、admin 帳號密碼還是 admin/admin、production 開著 debug 模式把完整 stack trace 吐給使用者看、範例應用沒從正式機移除、雲端服務的分享權限預設對整個網際網路開放。
怎麼防:
- 硬化流程要可重複、要自動化。 dev / QA / production 的設定要一模一樣,只有帳密不同。手動設定的環境,第三台一定會歪。
- 最小平台。 用不到的功能、範例、文件、port,通通移除,不是關掉而是移除。
- 不要把 static key 塞進程式碼或設定檔。 用 IAM role、短期憑證、identity federation。
💡 面試我會問:「為什麼這一項今年會升到第二名?」答得出「因為現在應用的行為大量由設定驅動,IaC 和雲端把設定面放大了」就很到位。
A03:2025 軟體供應鏈失效(Software Supply Chain Failures)
一句話:你自己的程式沒問題,但你信任的東西有問題。
今年最值得聊的一項。它在社群調查裡被投成第一名,而且是整整 50% 的人把它排 #1。
它的前身是 2013 年的「使用有已知漏洞的元件」,2021 年叫 A06。但這次範圍整個擴大了:不只是「你的 lodash 有沒有 CVE」,而是整條鏈——你的 CI/CD、你的 artifact 倉庫、你的 container registry、你的 IDE 外掛、你開發機本身。
官方在這一項舉的例子讀起來像驚悚片:
- SolarWinds(2019):受信任的供應商被植入惡意程式,導致約 18,000 個組織連帶被入侵。
- Bybit(2025):15 億美元被偷,起因是錢包軟體的供應鏈攻擊,而且惡意程式只在特定條件下才發作。
- Shai-Hulud(2025):第一個成功自我複製的 npm 蠕蟲。它在熱門套件裡塞惡意版本,用 post-install script 偷資料傳到公開的 GitHub repo,還會偵測受害環境裡的 npm token,自動拿去發布更多惡意套件。散播到五百多個套件版本才被 npm 阻斷。
Shai-Hulud 那個案例官方下了一句結論,我覺得是這整個分類的重點:它證明了開發者自己現在就是供應鏈攻擊的首要目標。
還有個很反直覺的數據:這個分類對應的 CVE 少得可憐(只有十來筆),但一被測出來就是最高的平均發生率,而且平均的 exploit 與 impact 分數是十個分類裡最高的。少見、難測,但一中就是重傷。
怎麼防:
- 有 SBOM,而且要管到 transitive dependency。 你直接裝的套件你知道,它裝的那些你通常不知道。
- 只從官方來源拿套件,優先用有簽名的。
- CI/CD 的安全等級不能低於它建置的系統。 這條最多人違反——production 有 MFA、有 IAM、有稽核,build server 卻是一把萬能 token 走天下。
- 分批推送更新。 用 staged rollout 或 canary,萬一供應商被攻陷,炸的不是全部。
💡 面試我會問:「Log4Shell 那次你們怎麼處理的?」我不是要考 CVE 編號,我要知道:你多久之內盤點出「哪些服務用了 log4j、哪一版」。答不出來的團隊,通常是沒有 SBOM。
A04:2025 加密機制失效(Cryptographic Failures)
一句話:該加密的沒加密,有加密的用錯方法。
從第二名掉到第四名,但別誤會,它的平均發生率仍有 3.80%,在十個分類裡排前段。
具體長什麼樣:密碼用 MD5 或 SHA1 存(那不是密碼雜湊函數)、金鑰 commit 進 git、還在用 TLS 1.0、用 Math.random() 產 token、IV 重複使用、ECB 模式、只加密不做認證加密。
官方特別點名了一件事:這個分類裡最常見的 CWE 有好幾個都跟「亂數不夠亂」有關——弱的偽亂數產生器、熵不足、可預測的演算法。新人很容易在這裡翻車,因為 random() 看起來就很隨機。
怎麼防:
- 密碼用 Argon2、scrypt、yescrypt 或 PBKDF2-HMAC-SHA-512 這類有 work factor 的雜湊函數。 舊系統還在用 bcrypt 的,去查 OWASP 的 Password Storage Cheat Sheet。
- 傳輸一律 TLS 1.2 以上,並開 HSTS。
- 永遠用認證加密(AEAD),不要只做加密。
- 不必要的敏感資料就別存。 沒留的資料偷不走。
還有一條 2025 版新加的,值得記一下:官方要求你現在就開始準備後量子密碼學(PQC),高風險系統最晚在 2030 年底前要完成。
💡 面試我會問:「密碼要怎麼存?」聽到「加密存起來」就扣分——密碼是雜湊不是加密,因為你根本不需要還原它。能講出 salt 和 work factor 才算及格。
A05:2025 注入攻擊(Injection)
一句話:你把使用者打的字,當成指令執行了。
從第三名掉到第五名,但它依然是 CVE 數量的冠軍,六萬多筆。裡面 XSS 就佔了三萬多,SQL Injection 一萬四千多。
官方對這兩者的定位很有意思:XSS 是「高頻率、低衝擊」,SQL Injection 是「低頻率、高衝擊」。這兩句話拿來面試講,比背定義有用得多。
Injection 不只有 SQL,還有 NoSQL、OS command、ORM、LDAP、Expression Language。原理都一樣:資料跑進了指令的位置。
2025 版還加了一句,我覺得是這版最有時代感的一行字:類似的注入問題在 LLM 上已經很常見了,但那部分請看 OWASP 的 LLM Top 10,特別是 LLM01:2025 Prompt Injection。 也就是說,官方明確把 prompt injection 劃到另一份清單去了,別在這裡找它。
怎麼防,核心只有一句:把資料和指令分開。
- 用參數化查詢或 ORM,別做字串拼接。
- 注意:stored procedure 不等於安全。 如果它裡面用
EXECUTE IMMEDIATE或exec()拼字串,一樣會中。 - 白名單式的伺服器端驗證是輔助,不是主要防線。
💡 面試我會問:「用了 ORM 是不是就不會 SQL Injection?」正確答案是不一定。官方就舉了 Hibernate HQL 的例子——只要你在裡面拼字串,一樣中招。這題很能篩掉「我聽說 ORM 很安全」的人。
A06:2025 不安全的設計(Insecure Design)
一句話:這不是寫錯,是一開始就想錯。
從第四名掉到第六名,而官方認為這是好消息——威脅建模的普及和 Secure by Design 的推廣,確實看到了改善。
這一項最需要跟新人解釋清楚的,是它和「實作缺陷」的差別。官方講得很好:完美的實作救不了不安全的設計,因為那些該有的防護,你從頭到尾就沒設計過。
官方舉的三個例子都不是技術漏洞,全是商業邏輯:
- 用「密碼提示問題」做身分找回。這已經被 NIST 800-63b 明文禁止了,理由很簡單:那些答案不只你知道。
- 電影院連鎖店開放團體訂票折扣,上限十五人才要押金。攻擊者用幾個 request 就一次訂走六百個座位、把所有廳都佔滿。
- 電商沒有防機器人機制,顯示卡一上架就被黃牛程式掃光。
看出來了嗎?這三件事沒有一個是程式碼寫錯,全都是「需求階段沒人想過會被這樣玩」。
怎麼防:
- 威脅建模。 至少對認證、存取控制、商業邏輯這些關鍵流程做。
- 建立安全設計模式庫,或者說 paved road——讓做對的路變成最好走的路。
- 寫 misuse case,不只寫 use case。 除了「使用者會怎麼用」,也要寫「壞人會怎麼用」。
💡 面試我會問:「設計缺陷和實作缺陷差在哪?」這題答得漂亮的人很少,但答得出來的通常是資深的。
A07:2025 身分驗證失效(Authentication Failures)
一句話:系統把不該相信的人,當成合法使用者了。
穩坐第七名,名字從「Identification and Authentication Failures」簡化了。官方的觀察是:標準化的驗證框架普及,確實有幫助——但這一項還是沒有下降。
常見形態:
- Credential stuffing。 攻擊者拿外洩的帳密清單來試。現在還演化出混合式攻擊——用外洩密碼的變體去猜,例如
Password1!、Password2!、Password3!這樣遞增。 - 允許
Password1這種弱密碼、允許已知外洩的密碼。 - session id 出現在 URL 裡、登入成功後沒換新的 session id(session fixation)。
- 登出後 token 沒失效。
- 「密碼提示問題」——又是它,A06 也點名過一次。
怎麼防:
- 能上 MFA 就上 MFA。 這一條抵得過其他所有條加起來。
- 鼓勵使用者用密碼管理器。
- 新密碼要去比對外洩資料庫(例如 haveibeenpwned.com)。
- 不要強迫定期換密碼,除非你懷疑外洩了。這條寫在 NIST 800-63b 裡,但台灣還是一堆系統在每 90 天逼人換密碼——結果就是
Password9!變成Password10!。 - 註冊、找回密碼、API 路徑要防帳號列舉:不管哪種失敗,都回同一句「帳號或密碼錯誤」。
💡 面試我會問:「為什麼不該強迫使用者每三個月換密碼?」這題有點反直覺,而且能直接看出對方讀的是舊觀念還是新規範。
A08:2025 軟體或資料完整性失效(Software or Data Integrity Failures)
一句話:你沒驗證那個東西有沒有被動過手腳,就直接信了。
維持第八名。新人最常搞混的是它跟 A03 供應鏈的差別,官方自己有劃線:A08 談的是更低層次的「有沒有驗證完整性」,A03 談的是整條供應鏈的失效。
我自己的分法是:A03 是「你從哪裡拿到這個東西」,A08 是「你有沒有檢查它路上有沒有被換掉」。
典型場景:
- 韌體更新不驗簽章。家用路由器、機上盒大量中招,而且往往沒有補救手段,只能等舊版自然淘汰。
- CI/CD 從不受信任的地方拉 artifact,拉完不驗就用。
- 不安全的反序列化。 官方那個例子很生動:React 前端呼叫 Spring Boot 微服務,工程師為了 immutable,把使用者狀態序列化後在每個 request 之間傳來傳去。攻擊者看到 base64 開頭是
rO0(Java 物件的特徵),直接拿反序列化掃描工具打到 RCE。 - 為了方便,把
myCompany.SupportProvider.com做 DNS 對應到support.myCompany.com。結果所有myCompany.com網域的 cookie,包含驗證 cookie,全部送給了外部支援廠商。
怎麼防:用數位簽章驗證來源與完整性、只從受信任的 repository 取用、程式碼和設定變更都要 review、序列化資料一定要有完整性檢查。
💡 面試我會問:「A03 跟 A08 差在哪?」問這題不是刁難,是看對方是不是真的讀過 2025 版——因為 2021 版沒這個對照關係。
A09:2025 安全記錄與告警失效(Security Logging and Alerting Failures)
一句話:被打了,而你不知道。
維持第九名,改名的重點在 alerting。官方那句話值得再貼一次:只記 log 卻沒有告警,對於發現事件的價值微乎其微。
這一項有個很特別的地方:它在資料上永遠會被低估——只有 723 筆 CVE 對應,因為這種東西根本很難用工具測。它是靠社群調查投票才進榜的,而且這已經是第三次靠投票進來了。
官方舉的三個案例都很痛:
- 某兒童健保業者的網站沒有監控和記錄,是外部通報才知道有攻擊者存取並修改了超過 350 萬名兒童的健康紀錄。事後檢討發現,這個外洩可能從 2013 年就開始了,持續超過七年。
- 某印度大型航空公司外洩超過十年份的旅客個資,含護照和信用卡資料。事發在第三方雲端託管商,而託管商過了一段時間才通知航空公司。
- 某歐洲大型航空公司被攻擊者收割四十多萬筆付款紀錄,最後被隱私主管機關罰了兩千萬英鎊。
我特別喜歡官方提的一個防禦技巧,叫 honeytoken:在資料庫裡放一些正常業務絕對不會碰到的假資料或假帳號,任何人碰到它就發告警。因為正常情況下沒人會存取,所以誤報率幾乎是零。
其他要點:所有登入、存取控制、輸入驗證的失敗都要記;每個有安全控制的地方,成功和失敗都要記;log 本身要防竄改(append-only);log 不要記到 PII;還有一條很容易忽略——log 也要做編碼處理,不然攻擊者可以注入你的 log 系統(CWE-117)。
💡 面試我會問:「你的系統被打了,你多久會知道?誰會知道?」這題沒有標準答案,但答「應該有 log 吧」跟答「登入失敗超過閾值會進 Slack 的 oncall 頻道」是兩種人。
A10:2025 例外狀況處理不當(Mishandling of Exceptional Conditions)
一句話:出事的時候,系統不知道自己該做什麼。
2025 年的全新分類,收了 24 個 CWE。官方說這裡面有些 CWE 以前被歸在「程式碼品質不佳」,但那個標籤太籠統了,拆出來才有辦法給具體建議。
它包含三種失敗,可能同時發生:沒有預防異常發生、沒有察覺異常正在發生、發生之後反應不當或根本沒反應。
官方對它下了一個我很喜歡的定義:任何時候應用程式不確定自己下一步該做什麼,就是一次例外狀況處理不當。
三個攻擊場景:
- 資源耗盡。 檔案上傳有接住例外,但沒有釋放資源。每一次例外都鎖住一點資源,最後全部耗光,變成 DoS。
- 敏感資訊外洩。 資料庫錯誤直接把完整錯誤訊息吐給使用者。攻擊者於是刻意一直觸發錯誤,用洩漏的系統資訊拼出一個更精準的 SQL Injection。錯誤訊息成了偵察工具。
- 狀態損毀。 多步驟金流交易被網路中斷打斷。如果順序是「扣款、入帳、記錄交易」而系統沒有正確 rollback,攻擊者可能把帳戶掏空,或利用競態條件讓同一筆錢送出好幾次。
怎麼防:
- 在錯誤發生的地方就接住它,不要放到最外層才統一處理。同時要有全域 exception handler 當最後一道網。
- fail closed,不要 fail open。 交易做到一半出事,整筆 rollback 重來。官方特別提醒:試圖從交易中途「救回來」,往往就是製造不可逆錯誤的地方。
- 凡是能設限的都要設限——rate limit、資源配額、throttling。官方那句話很有畫面:資訊系統裡不該有任何東西是無限的,否則你會換來服務中斷、暴力破解成功,還有一張驚人的雲端帳單。
- 整個組織用同一套方式處理例外,這樣 code review 才審得動。
💡 面試我會問:「你的 API 掛掉的時候,是擋住還是放行?」很多系統的驗證服務逾時之後選擇放行,理由是「不能影響使用者體驗」。那就是 fail open,也就是 CWE-636。
這份榜單是怎麼排出來的
這題是我留給資深候選人的。能講清楚方法論的人,通常對「資料能證明什麼、不能證明什麼」有感覺。
flowchart TD
A["超過 280 萬個應用的測試資料<br/>由 Veracode、Semgrep、Sonar、<br/>Contrast、Bugcrowd 等組織提供"] --> B["分析 589 個 CWE<br/>2017 約 30 個、2021 約 400 個"]
B --> C["依資料排出 12 個分類"]
C --> D["取前 8 名<br/>資料驅動"]
E["社群問卷調查<br/>第一線工程師投票"] --> F["票選 2 個名額<br/>補資料看不到的風險"]
D --> G["OWASP Top 10:2025"]
F --> G
H["NVD 的 CVE 資料<br/>約 17.5 萬筆 CVE 對 CWE 的對應"] --> I["取 CVSS 的<br/>Exploit 與 Impact 分數<br/>加權平均"]
I --> G
重點在那個 8 + 2。
十個名額裡只有八個是照資料排的,另外兩個開放給社群問卷投票。官方給的理由我覺得非常誠實:「檢視貢獻的資料,本質上是在看過去。」
新的弱點被發現、被寫成測試方法、被整合進工具、再被跑過夠大量的應用——這中間可能要好幾年。等到資料看得見,事情早就發生很久了。而且有些風險可能永遠測不出來(A09 就是典型)。所以要靠第一線的人投票,把資料裡看不到的東西補進來。
官方形容自己是 data-informed, but not blindly data-driven——參考資料,但不盲從資料。
還有幾個細節值得知道:
- 這次不用 CVSS v4.0。 因為 v4 的計分演算法整個改了,不再像 v2、v3 那樣直接給出 Exploit 和 Impact 分數。官方說會想辦法在未來的版本處理。
- 只算「有沒有」,不算「有幾個」。 一個應用裡某個 CWE 出現 4 次還是 4000 次,對排名沒差別。因為人工測試通常同一種問題只記一次,自動化工具卻會每一處都記一筆——算次數只會扭曲真實的普及率。
- 每個分類最多收 40 個 CWE,這是刻意設的上限。
順帶一提,如果你去對照官方導論頁和各分類的詳細頁,會發現有幾個數字對不太起來(例如 A03 的 CWE 數量和平均發生率、A05 的 CWE 數量,兩邊寫的不一樣)。這不影響結論,但也剛好說明一件事:面試不會考你背這些數字,考的是你懂不懂它們代表什麼。
一張圖:它們分別踩在哪一段
新人最常見的困擾是「十個分類記不住,因為它們感覺是同一層的東西」。其實不是。把一個 request 的生命週期攤開來看,它們各自站在不同的位置:
flowchart TD
Start["使用者送出請求"] --> Design{"這個功能<br/>當初設計對了嗎"}
Design -->|沒想過會被這樣玩| A06["A06 不安全的設計"]
Design -->|設計沒問題| Auth{"你是誰"}
Auth -->|冒充成功| A07["A07 身分驗證失效"]
Auth -->|確認身分| Authz{"你能碰這個嗎"}
Authz -->|越權| A01["A01 存取控制失效"]
Authz -->|通過| Input{"輸入怎麼處理"}
Input -->|當成指令執行| A05["A05 注入攻擊"]
Input -->|反序列化沒驗| A08["A08 完整性失效"]
Input --> Data{"資料怎麼存怎麼傳"}
Data -->|沒加密或用錯演算法| A04["A04 加密機制失效"]
Data --> Runtime{"執行環境本身"}
Runtime -->|開關設錯| A02["A02 安全設定錯誤"]
Runtime -->|信任的元件有毒| A03["A03 軟體供應鏈失效"]
Runtime --> Err{"出錯的時候"}
Err -->|不知所措或 fail open| A10["A10 例外狀況處理不當"]
Err --> Detect{"有人看到嗎"}
Detect -->|沒記錄或沒告警| A09["A09 記錄與告警失效"]
Detect -->|正常完成| Done["回應使用者"]
這張圖我畫給新人看的時候,通常會補一句:A06 在最前面,A09 在最後面,這兩個是最容易被跳過的。 因為它們一個發生在寫程式之前,一個發生在事情結束之後,都不在「寫功能」的那段時間裡。
我實際會問的面試題
由淺到深,附上我想聽到的東西。
1. 「隨便挑一個你最有感的,講講你踩過的坑。」
開放題,用來破冰。我看的是他講的是自己的經驗還是課本的例子。講得出「那次是因為我們的 API 忘了驗 owner」的人,遠勝於背出十個名詞的人。
2. 「為什麼存取控制失效一直是第一名?」
我想聽到的關鍵字是「工具測不出來」。掃描器可以找 SQL Injection 的 pattern,但它不知道 user 42 該不該看訂單 1234——那是你的商業邏輯,只有你知道。所以這一類只能靠設計和測試,不能靠買工具解決。
3. 「SSRF 在 2025 版跑去哪了?」
考的是有沒有跟上改版。答案是併進 A01。追問「為什麼合理」,好的回答是:SSRF 本質上就是讓伺服器替你去存取你原本碰不到的資源,那是存取控制問題。
4. 「用了 ORM 是不是就不會 SQL Injection?」
答「是」就是紅旗。正確答案是不一定,只要在裡面拼字串一樣會中,官方就拿 Hibernate HQL 舉例。
5. 「你的服務依賴的某個套件爆了 RCE,你第一件事做什麼?」
我要聽的不是「趕快升級」,是「先盤點哪些服務用了它、哪一版、有沒有 transitive 帶進來的」。這題直接測有沒有 SBOM。答得出 staged rollout、虛擬修補的加分。
6. 「你的驗證服務逾時了,這個 request 你放不放行?」
fail open vs fail closed。這題沒有絕對答案,但我要聽他有意識到這是個安全決策,而不是隨口說「當然要放行啊不然使用者會抱怨」。
7.(給資深的)「這份榜單怎麼排出來的?為什麼有兩個名額是投票決定的?」
答得出 8 + 2、答得出「資料只能反映過去、有些風險永遠測不出來」的人,通常對資安的理解是有厚度的。
給新人的學習順序
我不會叫新人「把 Top 10 讀完」。那個讀完也記不住。我給的順序是這樣:
第一週:先動手打一次。 去玩 OWASP Juice Shop——一個故意寫得很爛的購物網站,你的任務是把它打穿。先體驗過「改個網址就看到別人資料」的那個瞬間,後面讀文件才有畫面。想要更循序漸進的可以用 WebGoat。
第二週:讀 Top 10 本體,但只讀 Description 和 Example Attack Scenarios。 官方頁面每一項都有攻擊情境,那才是最好讀的部分。CWE 清單先跳過,那是查表用的,不是拿來讀的。
第三週開始:改讀 Cheat Sheet Series。 這是我認為 OWASP 最被低估的資源。Top 10 告訴你「有這個問題」,Cheat Sheet 告訴你「這個語言這個框架該怎麼寫」。密碼儲存、輸入驗證、REST 安全、JWT,每一篇都是一頁式的實作指南。做開發的人,其實花在這裡的時間應該比 Top 10 多。
之後看方向分岔:
- 要做驗收、要寫安全需求 → ASVS,這才是檢查表。
- 要做測試 → Web Security Testing Guide。
- 要寫程式的防護基本功 → Proactive Controls,它是「主動該做什麼」,和 Top 10 的「不要做什麼」互補。
- 做 API 的 → OWASP API Security Top 10,那是另一份清單。
- 碰 LLM 的 → OWASP LLM Top 10,prompt injection 在那裡不在這裡。
一句話總結我的建議:Top 10 拿來建立地圖,Cheat Sheet 拿來實際幹活,ASVS 拿來驗收。
冷知識:那個 W 已經不是 Web 了
大部分人(包括我,很長一段時間)都以為 OWASP 是 Open Web Application Security Project。
但你現在去看官方的 About 頁面,寫的是 The Open Worldwide Application Security Project。W 從 Web 換成了 Worldwide。原因也很直觀:這個基金會現在管的東西早就不只是網頁——行動應用、API、雲端、IoT、機器學習模型,全都在射程內。
順帶一提,同一個頁面寫著 OWASP Foundation 在 2001 年 12 月 1 日啟動,2004 年 4 月 21 日正式登記為美國的非營利慈善組織。所以 Top 10 這份清單,比很多正在讀這篇文章的工程師還要老。
最後
如果這篇你只記得一件事,我希望是這個:
OWASP Top 10 不是拿來背的,是拿來當成提問清單的。
下次你在做 code review 或設計評估的時候,把這十個當成十個問題問一遍:這個 endpoint 有驗 owner 嗎?這個設定 production 跟 staging 一樣嗎?這個套件哪來的?這裡出錯的時候會 fail open 嗎?出事我們幾分鐘會知道?
問完這十題,你就已經比大多數團隊做得多了。
至於面試——我從來不在意有沒有人能把十項按順序背出來。我在意的是,當我問「這個功能你會怎麼確認它安全」的時候,對方腦子裡有沒有一張地圖。
有地圖的人,我就知道可以放心把東西交給他。