25個Secure Coding 的建議與業界標準(CWE)
這篇文章主要說明Coding或是進行 Code Review 時,
有沒有基本的規範讓程式可以避免已知的重大資訊安全風險?
我們主要透過一個業界Common Weakness Enumeration (CWE)的規範
說明最常見的 Top 25軟體錯誤與 Secure Coding 基本法則。
Secure Coding 的1頁摘要
在說明 Top 25與業界的一些標準前,有沒有一頁摘要?
針對研發部程式開發一頁摘要的建議? 整理如下:
25 個最常見的軟體錯誤
Rank | ID | Name |
---|---|---|
[1] | CWE-89 | SQL Injection 這是最常見的資訊安全風險。針對使用者輸入資料的驗證或是建立白名單過濾不必要的字元是必須的。一般來說,程式語言提供的 prepared statement 都可以避免SQL injection 的問題。 |
[2] | CWE-78 | OS Command Injection透過惡意的輸入執行惡意程式。通常是因為程式中使用呼叫或是執行系統外部程式,另外配合使用者輸入參數所造成。建議解決方式,盡量避免使用可以執行系統外部程式的API。如果該API一定要使用者輸入參數,限制輸入參數的範圍與驗證輸入參數的合法性。 |
[3] | CWE-120 | Buffer Overflow常見的 Buffer Overflow |
[4] | CWE-79 | XSS, (Cross-site Scripting)對於網站來說,XSS是一個常見的攻擊方式。建議防護:除了針對輸入值要檢查,HTML相關的輸出必須要經過適當的編碼。編碼可避免惡意輸入的 JavaScript 被任意的執行。 |
[5] | CWE-306 | Missing Authentication for Critical Function對於重要的功能或是網頁沒有透過認證就可以存取。舉例來說,駭客可以藉由瀏覽下頁網頁URL 存取重要資訊http://victim.com/adminhttp://victim.com/users |
[6] | CWE-862 | Missing Authorization 缺少”授權”機制這部分常見的像是駭客用一般使用者帳號登入,但是卻可以存取系統管理者的權限或是頁面。 |
[7] | CWE-798 | Use of Hard-coded Credentials實務上常見的例子,開發或是測試過程中,因為測試方便,所以可能寫入一組測試用帳號密碼。或是在程式中註解 “password=xxx”。這樣的帳號密碼在上線後忘記移除,造成資訊安全風險。 |
[8] | CWE-311 | Missing Encryption of Sensitive Data敏感性資料的加密這也是一個常見的漏洞。使用者輸入帳號、密碼、信用卡等資訊,該資料本身是否加密?傳輸時是否透過 HTTPS? 儲存在資料庫或是記錄檔是否加密處理。常見的是 debug log 中,有使用者相關敏感性資料。這是經常被忽略的。 |
[9] | CWE-434 | Unrestricted Upload of File with Dangerous Type關於 “檔案上傳”所帶來的資訊安全風險,可另外參考筆者這篇文章6個”檔案上傳”功能的資訊安全風險與防護 |
[10] | CWE-807 | Reliance on Untrusted Inputs in a Security Decision |
[11] | CWE-250 | Execution with Unnecessary Privileges |
[12] | CWE-352 | Cross-Site Request Forgery (CSRF)這是駭客常見的一種攻擊手法。主要發生在網站 Web Service。特別是透過 Http Get 來傳遞參數這種最常受到這種攻擊。舉個例子,駭客寄一封信給你,上面寫 恭喜你中獎,請點這裡。但是實際上那個 URL 很可能是銀行轉帳. 例如:http://www.bank.com/trasferMoney?=1000這就是為什麼莫名的連結不要亂點的原因! 要如何解決這個問題呢?網站必須再次驗證! 例如,執行轉帳前必須要使用者再輸入其他資訊。 |
[13] | CWE-22 | Improper Limitation of a Pathname to a Restricted Directory (‘Path Traversal’) |
[14] | CWE-494 | Download of Code Without Integrity Check |
[15] | CWE-863 | Incorrect Authorization |
[16] | CWE-829 | Inclusion of Functionality from Untrusted Control Sphere |
[17] | CWE-732 | Incorrect Permission Assignment for Critical Resource |
[18] | CWE-676 | Use of Potentially Dangerous Function |
[19] | CWE-327 | Use of a Broken or Risky Cryptographic Algorithm |
[20] | CWE-131 | Incorrect Calculation of Buffer Size |
[21] | CWE-307 | Improper Restriction of Excessive Authentication Attempts |
[22] | CWE-601 | URL Redirection to Untrusted Site (‘Open Redirect’)類似 DNS hiJacking。不同的是 URL redirection 主要利用該網站所提供的 URL re-direct的機制,巧妙的將使用者導到另外一個網站。這也就是為什麼許多電子商務或是銀行網站如果有外部連結時,都會出現警告”你即將離開本網站服務,到外部第三方的網站” |
[23] | CWE-134 | Uncontrolled Format String |
[24] | CWE-190 | Integer Overflow or Wraparound |
[25] | CWE-759 | Use of a One-Way Hash without a Salt什麼是 Salt? 為什麼要用 Salt呢? 我們用下列的圖示說明。當兩個使用者都用密碼 “bob”時,透過 Hash演算法我們會得到同樣的結果。因此,駭客只要用字典檔案比較 Hash值,自然就可以知道原始密碼為何。為了解決這樣的問題,我們必須加入 “Salt”的變量,主要目的是讓 Hash值有所不同,讓駭客無法單純由 Hash值反推原始密碼。 |
建議的寫法或修改?
我們知道這些是常見的風險。但是程式要怎樣修改有範本嗎?
https://www.securecoding.cert.org/confluence/display/seccode/SEI+CERT+Coding+Standards
C++ 可以參考: https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=637
Java 可以參考:https://www.securecoding.cert.org/confluence/display/java/SEI+CERT+Oracle+Coding+Standard+for+Java
舉Code Injection 來說(Java 為例)
下面這段程式會受到 Code Injection 的威脅影響。
[pastacode lang=”java” message=”” highlight=”” provider=”manual”]
private static void evalScript(String firstName) throws ScriptException {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("javascript");
engine.eval("print('"+ firstName + "')");
}
[/pastacode]
駭客可以輸入下列字串當作是使用者名稱
dummy\'); var bw = new JavaImporter(java.io.BufferedWriter); var fw = new JavaImporter(java.io.FileWriter); with (fw) with (bw) { bwr = new BufferedWriter( new FileWriter(\"config.cfg\")); bwr.write(\"some text\"); bwr.close(); } // ; |
要怎樣解決這樣的問題呢? 白名單或是限制合法字元是一種方式。範例程式如下:
[pastacode lang=”java” message=”” highlight=”” provider=”manual”]
private static void evalScript(String firstName) throws ScriptException {
// Allow only alphanumeric and underscore chars in firstName
// (modify if firstName may also include special characters)
if (!firstName.matches("[\\w]*")) {
// String does not match whitelisted characters
throw new IllegalArgumentException();
}
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("javascript");
engine.eval("print('"+ firstName + "')");
}
[/pastacode]
CWE程式的規範只有 25個嗎?
CWE 的程式規範有接近 1000 條。除了 Top 25 之外,還有另外 900多條。
有些是根據程式語言特性所規範、有些是根據開發環境所規範(例如 Java or .Net網站開發環境設定)
筆者建議可以先從 Top25 開始,再根據所使用的程式語言與工具參考對定的CWE規範。
或是可以透過自動化程式碼掃描的工具,這些工會掃描程式碼完之後,根據業界一些規則,列出潛在違反安全設計規則的程式碼。
還有其他業界標準嗎?
其他主要的標準像是 OWASP, MISRA, CWE, CERT等。可參考下列連結。實務執行時可能會透過程式掃描的工具來完成。
舉例來說,筆者公司其中一個程式碼掃描功聚採用的是 Klocwork。
這樣的工具會根據一定的規則 (checkers)對程式碼掃描。該工具的規則通常會依據這些業界標準定義。相關業界標準參考如下。
C/C++ coding standards
- MISRA-C rules mapped to Klocwork checkers
- MISRA-C++ rules mapped to Klocwork checkers
- CWE IDs mapped to Klocwork C and C++ checkers
- 2011 CWE-SANS Top 25 Most Dangerous Software Errors mapped to Klocwork checkers
- 2010 CWE-SANS Top 25 Most Dangerous Software Errors mapped to Klocwork checkers
- CERT C and C++ Secure Coding Standard IDs mapped to Klocwork C and C++ checkers
- DISA STIG IDs mapped to Klocwork C and C++ checkers
Java coding standards
- CWE IDs mapped to Klocwork Java checkers
- 2011 CWE-SANS Top 25 Most Dangerous Software Errors mapped to Klocwork checkers
- 2010 CWE-SANS Top 25 Most Dangerous Software Errors mapped to Klocwork checkers
- OWASP Top 10 Security Risks for 2013 mapped to Klocwork Java checkers
- DISA STIG IDs mapped to Klocwork Java checkers
CWE/SANS Top 25 Most Dangerous Software Errors
Rank | Score | ID | Name |
---|---|---|---|
[1] | 93.8 | CWE-89 | Improper Neutralization of Special Elements used in an SQL Command (‘SQL Injection’) |
[2] | 83.3 | CWE-78 | Improper Neutralization of Special Elements used in an OS Command (‘OS Command Injection’) |
[3] | 79.0 | CWE-120 | Buffer Copy without Checking Size of Input (‘Classic Buffer Overflow’) |
[4] | 77.7 | CWE-79 | Improper Neutralization of Input During Web Page Generation (‘Cross-site Scripting’) |
[5] | 76.9 | CWE-306 | Missing Authentication for Critical Function |
[6] | 76.8 | CWE-862 | Missing Authorization |
[7] | 75.0 | CWE-798 | Use of Hard-coded Credentials |
[8] | 75.0 | CWE-311 | Missing Encryption of Sensitive Data |
[9] | 74.0 | CWE-434 | Unrestricted Upload of File with Dangerous Type |
[10] | 73.8 | CWE-807 | Reliance on Untrusted Inputs in a Security Decision |
[11] | 73.1 | CWE-250 | Execution with Unnecessary Privileges |
[12] | 70.1 | CWE-352 | Cross-Site Request Forgery (CSRF) |
[13] | 69.3 | CWE-22 | Improper Limitation of a Pathname to a Restricted Directory (‘Path Traversal’) |
[14] | 68.5 | CWE-494 | Download of Code Without Integrity Check |
[15] | 67.8 | CWE-863 | Incorrect Authorization |
[16] | 66.0 | CWE-829 | Inclusion of Functionality from Untrusted Control Sphere |
[17] | 65.5 | CWE-732 | Incorrect Permission Assignment for Critical Resource |
[18] | 64.6 | CWE-676 | Use of Potentially Dangerous Function |
[19] | 64.1 | CWE-327 | Use of a Broken or Risky Cryptographic Algorithm |
[20] | 62.4 | CWE-131 | Incorrect Calculation of Buffer Size |
[21] | 61.5 | CWE-307 | Improper Restriction of Excessive Authentication Attempts |
[22] | 61.1 | CWE-601 | URL Redirection to Untrusted Site (‘Open Redirect’) |
[23] | 61.0 | CWE-134 | Uncontrolled Format String |
[24] | 60.3 | CWE-190 | Integer Overflow or Wraparound |
[25] | 59.9 | CWE-759 | Use of a One-Way Hash without a Salt |
參考資料
http://cwe.mitre.org/top25/archive/2011/2011_cwe_sans_top25.pdf