可預測的偽隨機數發生器
漏洞特征:PREDICTABLE_RANDOM
在某些關鍵的安全環境中使用可預測的隨機數可能會導致漏洞,比如,當這個值被作為:
- csrf token;如果攻擊者可以預測csrf的token值的話,就可以發動csrf攻擊
- 重置密碼的token(通過郵件發送);如果重置密碼的token被替換的話,那么就會導致用戶賬戶被接管,因為攻擊者會猜測到重置密碼的鏈接。
- 其他包含秘密的信息
修復這個漏洞最快的方式是用強隨機數生成器( 比如:java.security.SecureRandom
)替換掉java.util.Random
有漏洞的代碼:

String generateSecretToken(){ 隨機r = new Random(); return Long.toHexString(r.nextLong()); }
解決方案

import org.apache.commons.codec.binary.Hex; String generateSecretToken() { SecureRandom secRandom = new SecureRandom(); byte[] result = new byte[32]; secRandom.nextBytes(result); return Hex.encodeHexString(result); }
引用:
Cracking Random Number Generators - Part 1 (http://jazzy.id.au)
CERT: MSC02-J. Generate strong random numbers
CWE-330: Use of Insufficiently Random Values
Predicting Struts CSRF Token (Example of real-life vulnerability and exploitation)
可預測的偽隨機數發生器(Scala)
漏洞特征:PREDICTABLE_RANDOM_SCALA
在某些關鍵的安全環境中使用可預測的隨機數可能會導致漏洞,比如,當這個值被作為:
- csrf token;如果攻擊者可以預測csrf的token值的話,就可以發動csrf攻擊
- 重置密碼的token(通過郵件發送);如果重置密碼的token被替換的話,那么就會導致用戶賬戶被接管,因為攻擊者會猜測到重置密碼的鏈接。
- 其他包含秘密的信息
修復這個漏洞最快的方式是用強隨機數生成器( 比如:java.security.SecureRandom
)替換掉java.util.Random
有漏洞的代碼:

import scala.util.Random def generateSecretToken() { val result = Seq.fill(16)(Random.nextInt) return result.map("%02x" format _).mkString }
解決方案:

import java.security.SecureRandom def generateSecretToken() { val rand = new SecureRandom() val value = Array.ofDim[Byte](16) rand.nextBytes(value) return value.map("%02x" format _).mkString }
Cracking Random Number Generators - Part 1 (http://jazzy.id.au)
CERT: MSC02-J. Generate strong random numbers
CWE-330: Use of Insufficiently Random Values
Predicting Struts CSRF Token (Example of real-life vulnerability and exploitation)
沒有做任何安全檢查的servlet 參數
漏洞特征:SERVLET_PARAMETER
Servlet 會從各種函數中獲取到GET和POST的值。這些被獲取的值肯定是不安全的。在進入到敏感的api函數之前你可能需要驗證和過濾這些值:
- sql 查詢 (可能導致sql注入)
- 文件操作 ( 可能會導致目錄穿越 )
- 命令執行 ( 可能會導致命令注入 )
- html解析 (可能會導致xss)
- 其他的
引用:
CWE-20: Improper Input Validation
沒有做任何安全檢查Content-Type 頭
漏洞特征:SERVLET_CONTENT_TYPE
服務器端程序通過客戶端收集http的Content-Type的值。這個值可能會影響影響應用的安全性
引用:
CWE-807: Untrusted Inputs in a Security Decision
沒有做任何安全檢查Hostname 頭
漏洞特征: SERVLET_SERVER_NAME
服務器端程序通過客戶端收集http的hostname 的值。這個值可能會影響影響應用的安全性。ServletRequest.getServerName()
和 HttpServletRequest.getHeader("Host")
的行為很相似,都是從http頭部中獲取到host的值

GET /testpage HTTP/1.1
Host: www.example.com
[...]
默認情況下,web容器可能會直接將請求重定向到你的應用程序中。這就允許用戶把惡意的請求放入http的host頭中。我建議你不要信任來自客戶端的任何輸入。
引用:
CWE-807: Untrusted Inputs in a Security Decision
沒有做任何安全檢查的session cookie值
漏洞特征: SERVLET_SESSION_ID
HttpServletRequest.getRequestedSessionId()
( http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletRequest.html#getRequestedSessionId() )函數返回cookie中JSESSIONID的值。這個值通常被session 管理器訪問,而不是開發者代碼。
傳遞給客戶端的值通常是字母數字( 例如:JSESSIONID=jp6q31lq2myn ),無論如何,這個值可以被客戶端改變,下面的http請求展示了潛在的危險

GET /somePage HTTP/1.1 Host: yourwebsite.com User-Agent: Mozilla/5.0 Cookie: JSESSIONID=Any value of the user's choice!!??'''">
像這樣,JSESSIONID應該僅被使用判斷是否與存在的session ID相匹配,如果不存在對應的session ID,那么這個用戶就可能會是未授權用戶。此外, session ID的值應該從來不被記錄,如果記錄了,那么日志文件中就會包含有效的且在激活狀態的session IDs,這樣就會允許內部員工可以通過日志記錄來劫持任意在線用戶。
引用:
OWASP: Session Management Cheat Sheet
CWE-20: Improper Input Validation
沒有做任何安全檢查的查詢字符串
漏洞特征: SERVLET_QUERY_STRING
查詢字符串是get請求中參數名和參數值的串聯,可以傳入預期之外的參數。 比如URL請求:/app/servlet.htm?a=1&b=2 ,查詢字符串就是a=1&b=2
通過函數 HttpServletRequest.getParameter() 接收每一個傳遞進來的參數的值,通過 HttpServletRequest.getQueryString() 這個函數獲取到的值應該被看做不安全的。你應該在查詢字符串進入敏感函數之前去充分的效驗和過濾它們。
引用:
CWE-20: Improper Input Validation
沒有做任何安全檢查的HTTP頭
漏洞特征:SERVLET_HEADER
http請求頭很容易會被用戶所修改。通常,不要假想請求來自於沒有被黑客修改的常規瀏覽器。我建議你,不要相信客戶端傳遞進來的http頭部值
引用:
CWE-807: Untrusted Inputs in a Security Decision
沒有做任何安全檢查的Referer值
漏洞特征:SERVLET_HEADER_REFERER
行為:
- 如果請求來自於惡意用戶,那么Referer的值會是任意的情況。
- 如果請求來自於另一個安全的源(https),那么Referer頭就是空的。
建議:
- 訪問控制不應該基於此標頭的值。
- csrf保護不應該僅基於此值。( 因為這個選項 )
引用:
CWE-807: Untrusted Inputs in a Security Decision
沒有做任何安全檢查的User-Agent值
漏洞特征: SERVLET_HEADER_USER_AGENT
"User-Agent" 很容易被客戶端偽造,不建議基於不同的User-Agent(比如爬蟲的UA)來適配不同的行為。
引用:
CWE-807: Untrusted Inputs in a Security Decision
潛在的cookie中包含敏感數據
漏洞特征: COOKIE_USAGE
存儲在客戶端中cookie的數據不應該包含敏感數據或者與session相關的數據。大多數情況下,敏感數據應該僅僅存儲在session中,並且通過通過用戶的session值去訪問。詳細請看HttpSession (HttpServletRequest.getSession())
客戶端cookie應該是比特定會話維持時間更長且獨立於特殊會話
引用:
CWE-315: Cleartext Storage of Sensitive Information in a Cookie
潛在的路徑穿越(文件讀取)
漏洞特征:PATH_TRAVERSAL_IN
一個文件被打開,然后讀取文件內容,這個文件名來自於一個輸入的參數。如果沒有過濾這個傳入的參數,那么本地文件系統中任意文件都會被讀取。
這個規則識別潛在的路徑穿越漏洞。在許多場景中,用戶無法控制文件路徑,如果有工具報告了這個問題,那么這個就是誤報
有漏洞代碼:

@GET @Path("/images/{image}") @Produces("images/*") public Response getImage(@javax.ws.rs.PathParam("image") String image) { File file = new File("resources/images/", image); //Weak point if (!file.exists()) { return Response.status(Status.NOT_FOUND).build(); } return Response.ok().entity(new FileInputStream(file)).build(); }
解決方案:

import org.apache.commons.io.FilenameUtils; @GET @Path("/images/{image}") @Produces("images/*") public Response getImage(@javax.ws.rs.PathParam("image") String image) { File file = new File("resources/images/", FilenameUtils.getName(image)); //Fix if (!file.exists()) { return Response.status(Status.NOT_FOUND).build(); } return Response.ok().entity(new FileInputStream(file)).build(); }
引用:
WASC: Path Traversal
OWASP: Path Traversal
CAPEC-126: Path Traversal
CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
潛在的路徑穿越(文件寫)
漏洞特征:PATH_TRAVERSAL_OUT
一個文件被打開,然后讀取文件內容,這個文件名來自於一個輸入的參數。如果沒有過濾這個傳入的參數,那么本地文件系統中任意文件都會被修改。
這個規則識別潛在的路徑穿越漏洞。在許多場景中,用戶無法控制文件路徑,如果有工具報告了這個問題,那么這個就是誤報
引用:
WASC: Path Traversal
OWASP: Path Traversal
CAPEC-126: Path Traversal
CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
潛在的路徑穿越(文件讀取)
漏洞特征:
SCALA_PATH_TRAVERSAL_IN
一個文件被打開,然后讀取文件內容,這個文件名來自於一個輸入的參數。如果沒有過濾這個傳入的參數,那么本地文件系統中任意文件都會被讀取。
這個規則識別潛在的路徑穿越漏洞。在許多場景中,用戶無法控制文件路徑,如果有工具報告了這個問題,那么這個就是誤報
有漏洞代碼:

def getWordList(value:String) = Action { if (!Files.exists(Paths.get("public/lists/" + value))) { NotFound("File not found") } else { val result = Source.fromFile("public/lists/" + value).getLines().mkString // Weak point Ok(result) } }
解決方案:

import org.apache.commons.io.FilenameUtils; def getWordList(value:String) = Action { val filename = "public/lists/" + FilenameUtils.getName(value) if (!Files.exists(Paths.get(filename))) { NotFound("File not found") } else { val result = Source.fromFile(filename).getLines().mkString // Fix Ok(result) } }
引用:
WASC: Path Traversal
OWASP: Path Traversal
CAPEC-126: Path Traversal
CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
潛在的命令注入
漏洞特征:COMMAND_INJECTION
高亮部分的api被用來執行系統命令,如果輸入這個api的數據沒有被過濾,那么就會導致任意命令執行
有漏洞的代碼:

import java.lang.Runtime; Runtime r = Runtime.getRuntime(); r.exec("/bin/sh -c some_tool" + input);
引用:
OWASP: Command Injection
OWASP: Top 10 2013-A1-Injection
CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')
潛在的命令注入(Scala)
漏洞特征:COMMAND_INJECTION
高亮部分的api被用來執行系統命令,如果輸入這個api的數據沒有被過濾,那么就會導致任意命令執行
有漏洞的代碼:

def executeCommand(value:String) = Action { val result = value.! Ok("Result:\n"+result) }
引用:
OWASP: Command Injection
OWASP: Top 10 2013-A1-Injection
CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')
文件類函數沒有過濾空字符
漏洞特征:WEAK_FILENAMEUTILS
一些文件類中方法沒有過濾空字節(0x00)
如果空字節被注入到文件名之中,如果這個文件被放進系統之中,那么系統則只會讀取空字符之前的文件名,字符串就會被空字符截斷,甚至java本身也不能關注空字符或者處理這些特殊情況。操作系統的這一特性通常被用來繞過文件名驗證去訪問其他的文件(例如,后綴是.log"的文件)。
給出兩點建議去修復這個問題:
- 升級到7 update 40 或者最近的版本,或者java 8 +,因為空字節注入這個問題已經被這些版本的java所解決
- 要嚴格驗證用戶輸入的文件名是否是有效的(例如不能包含空字符,不能包含路徑字符)
如果你知道你使用的現有的java版本可以避免空字符注入問題,你可以忽略上面的問題。
引用:
WASC-28: Null Byte Injection
CWE-158: Improper Neutralization of Null Byte or NUL Character
證書管理器接受任何證書
漏洞特征: WEAK_TRUST_MANAGER
空的證書管理器通常可以更輕松的連接到沒有根證書的主機上。結果就是,就會更容易受到中間人攻擊,因為客戶端信任所有的證書。
一個證書管理器應該允許信任指定的一種證書(例如:基於信任庫)。下面是一種可行的實現方法:
有漏洞的代碼:

class TrustAllManager implements X509TrustManager { @Override public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { //Trust any client connecting (no certificate validation) } @Override public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { //Trust any remote server (no certificate validation) } @Override public X509Certificate[] getAcceptedIssuers() { return null; } }
解決方案(基於證書庫的證書管理器):

KeyStore ks = //Load keystore containing the certificates trusted SSLContext sc = SSLContext.getInstance("TLS"); TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); tmf.init(ks); sc.init(kmf.getKeyManagers(), tmf.getTrustManagers(),null);
引用:
WASC-04: Insufficient Transport Layer Protection
CWE-295: Improper Certificate Validation
HostnameVerifier 接收任何簽名證書
漏洞規則:WEAK_HOSTNAME_VERIFIER
因為證書會被很多主機重復使用,接收任意證書的HostnameVerifier經常被使用。結果就是,就會更容易受到中間人攻擊,因為客戶端信任所有的證書。
一個證書管理器應該允許信任指定的一種證書(例如:基於信任庫)。應該創建通配符證書,可以允許多個子域下證書。下面是一種可行的實現方法:
有漏洞的代碼:

public class AllHosts implements HostnameVerifier { public boolean verify(final String hostname, final SSLSession session) { return true; } }
解決方案(基於證書庫的證書管理器):

KeyStore ks = //Load keystore containing the certificates trusted SSLContext sc = SSLContext.getInstance("TLS"); TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); tmf.init(ks); sc.init(kmf.getKeyManagers(), tmf.getTrustManagers(),null);
引用:
WASC-04: Insufficient Transport Layer Protection
CWE-295: Improper Certificate Validation
發現JAX-RS REST服務器端
漏洞規則: JAXRS_ENDPOINT
這些函數是REST Web Service 的一部分(JSR311).
這個網站的安全性應該被分析。例如:
-
權限認證,如果強制實施,就應該被測試 訪問控制,如果強制實施,就應該被測試 輸入應該被追蹤,因為可能會有潛在的漏洞 聊天程序應該使用SSL 如果服務器支持存儲私人數據(例如,通過POST),應該調查它是否對csrf有防御
引用:
OWASP: REST Assessment Cheat Sheet
OWASP: REST Security Cheat Sheet
OWASP: Web Service Security Cheat Sheet
OWASP: Cross-Site Request Forgery)
OWASP: CSRF Prevention Cheat Sheet
CWE-20: Improper Input Validation
發現Tapestry頁面
漏洞規則: TAPESTRY_ENDPOINT
在應用啟動的時候,Tapestry會被發現。Tapestry應用的每一個頁面又后端java類和相關的Tapestry標記語言構成(a.tml 文件)。當請求到達的時候,GET/POST參數會被映射到后端的java類之中。映射可以使用fieldName完成:

[...] protected String input; [...]
或者顯示注釋的定義:

...] @org.apache.tapestry5.annotations.Parameter protected String parameter1; @org.apache.tapestry5.annotations.Component(id = "password") private PasswordField passwordField; [...]
這個頁面被映射到視圖中[/resources/package/PageName].tml.
在應用中的每一個Tapestry頁面應該被調查,確保所有的輸入都能被自動的映射,並在這些參數被使用之前都是有效的。
引用:
Apache Tapestry Home Page
CWE-20: Improper Input Validation
發現Wicket的web頁面
漏洞特征:WICKET_ENDPOINT
這個類代表一個Wicket web頁面。輸入的數據會被來自實例中的PageParameters讀取,然后把它們送入后端處理程序。當前頁面會被映射到視圖之中[/package/WebPageName].html.
在應用中的每一個Wicket頁面應該被調查,確保所有的輸入都能被自動的映射,並在這些參數被使用之前都是有效的。
引用:
Apache Wicket Home Page
CWE-20: Improper Input Validation
MD2, MD4 和 MD5都是脆弱的哈希函數
漏洞特征:WEAK_MESSAGE_DIGEST_MD5
不建議使用MD2, MD4 和 MD5這個摘要算法。應該使用PBKDF2作為密碼的摘要算法。
md5哈希算法的安全性被嚴重損害。現已存在一種碰撞攻擊,這種攻擊可以用奔騰2.6 GHz 4核處理器在幾秒內碰撞出另一個哈希相同的字符串。進一步來說,還有選擇前綴碰撞攻擊(chosen-prefix collision attack ),這種攻擊能在一個小時之內找到兩個前綴相同的哈希,只要現有計算機的計算水平就可以達到。

"SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, and SHA-512/256:
所有散列計算程序都支持這些哈希函數的使用。
NISI:通信傳輸:[傳輸中建議使用的加密算法和密鑰長度](http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-131Ar1.pdf)
PBKDF的主要思想是減緩字典生成的時間或者增加攻擊者攻擊每一個密碼的時間。攻擊者會有一個密碼表去爆破PBKDF所使用的迭代計數器和salt。因為攻擊者必須花費大量的計算時間去嘗試破解每一個密碼,所以攻擊者很難用字典攻擊和爆破攻擊去獲得成功。
NISI:基於密碼的密鑰的加密建議
有漏洞的代碼:

MessageDigest md5Digest = MessageDigest.getInstance("MD5"); md5Digest.update(password.getBytes()); byte[] hashValue = md5Digest.digest();
解決方案:

public static byte[] getEncryptedPassword(String password, byte[] salt) throws NoSuchAlgorithmException, InvalidKeySpecException { PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator(new SHA256Digest()); gen.init(password.getBytes("UTF-8"), salt.getBytes(), 4096); return ((KeyParameter) gen.generateDerivedParameters(256)).getKey(); }
解決方案(java 8 和之后的版本)

public static byte[] getEncryptedPassword(String password, byte[] salt) throws NoSuchAlgorithmException, InvalidKeySpecException { KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 4096, 256 * 8); SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); return f.generateSecret(spec).getEncoded(); }
引用:
[1] On Collisions for MD5: Master Thesis by M.M.J. Stevens
[2] Chosen-prefix collisions for MD5 and applications: Paper written by Marc Stevens
Wikipedia: MD5
NIST: Transitions: Recommendation for Transitioning the Use of Cryptographic Algorithms and Key Lengths
NIST: Recommendation for Password-Based Key Derivation
Stackoverflow: Reliable implementation of PBKDF2-HMAC-SHA256 for Java
CWE-327: Use of a Broken or Risky Cryptographic Algorithm
SHA-1 是脆弱的哈希算法
漏洞特征: WEAK_MESSAGE_DIGEST_SHA1
不建議使用SHA-1算法去加密密碼、做數字簽名和其他用途。應該使用PBKDF2作為密碼的摘要算法。
“SHA-1用於生成電子簽名:
SHA-1可能僅僅用於NIST指導的特殊協議的電子簽名的生成。但是在其他的應用中,SHA-1 不應該用於電子簽名
SHA-1用於電子簽名的驗證:
對於電子簽名的驗證,SHA-1可以被用於傳統應用
"SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, and SHA-512/256:
所有散列計算程序都支持這些哈希函數的使用。
NISI:通信傳輸:[傳輸中建議使用的加密算法和密鑰長度](http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-131Ar1.pdf)
PBKDF的主要思想是減緩字典生成的時間或者增加攻擊者攻擊每一個密碼的時間。攻擊者會有一個密碼表去爆破PBKDF所使用的迭代計數器和salt。因為攻擊者必須花費大量的計算時間去嘗試破解每一個密碼,所以攻擊者很難用字典攻擊和爆破攻擊去獲得成功。
NISI:基於密碼的密鑰的加密建議
有漏洞的代碼:

MessageDigest sha1Digest = MessageDigest.getInstance("SHA1"); sha1Digest.update(password.getBytes()); byte[] hashValue = sha1Digest.digest(); byte[] hashValue = DigestUtils.getSha1Digest().digest(password.getBytes());
解決方案:

public static byte[] getEncryptedPassword(String password, byte[] salt) throws NoSuchAlgorithmException, InvalidKeySpecException { PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator(new SHA256Digest()); gen.init(password.getBytes("UTF-8"), salt.getBytes(), 4096); return ((KeyParameter) gen.generateDerivedParameters(256)).getKey(); }
解決方案(java 8 及以后的版本)

public static byte[] getEncryptedPassword(String password, byte[] salt) throws NoSuchAlgorithmException, InvalidKeySpecException { KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 4096, 256 * 8); SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); return f.generateSecret(spec).getEncoded(); }
引用:
Qualys blog: SHA1 Deprecation: What You Need to Know
Google Online Security Blog: Gradually sunsetting SHA-1
NIST: Transitions: Recommendation for Transitioning the Use of Cryptographic Algorithms and Key Lengths
NIST: Recommendation for Password-Based Key Derivation
Stackoverflow: Reliable implementation of PBKDF2-HMAC-SHA256 for Java
CWE-327: Use of a Broken or Risky Cryptographic Algorithm
DefaultHttpClient的默認構造函數與TLS 1.2不兼容
漏洞特征: DEFAULT_HTTP_CLIENT
有漏洞的代碼:

HttpClient client = new DefaultHttpClient();
解決方案:
用建議的構造函數去升級你的代碼並且配置jvm中https.protocols選項,使其包含TLSv1.2:
使用SystemDefaultHttpClient 代替
-
示例代碼: HttpClient client = new SystemDefaultHttpClient(); 基於SSLSocketFactory類創建一個HttpClient,通過 getSystemSocketFactory()) 獲得一個SSLScoketFactory實例,用這個實例去初始化一個HttpClient 基於SSLConnectionSocketFactory類創建一個HttpClient,通過 getSystemSocketFactory()) 獲得一個SSLScoketFactory實例,用這個實例去初始化一個HttpClient 使用HttpClientBuilder,在調用build()之前調用useSystemProperties() 示例代碼: HttpClient client = HttpClientBuilder.create().useSystemProperties().build(); HttpClients,調用 createSystem()去創建一個實例 示例代碼: HttpClient client = HttpClients.createSystem();
引用:
Diagnosing TLS, SSL, and HTTPS
脆弱的SSLContext
漏洞特征: SSL_CONTEXT
有漏洞的代碼:

SSLContext.getInstance("SSL");
解決方案:
用下面的代碼升級你的代碼,並且配置jvm的https.protocols選項,使其包含TLSv1.2

SSLContext.getInstance("TLS");
引用:
Diagnosing TLS, SSL, and HTTPS
習慣使用的信息摘要算法
自己實現消息摘要算法是不靠譜的。
NIST建議使用SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, or SHA-512/256。
“SHA-1用於生成電子簽名:
SHA-1可能僅僅用於NIST指導的特殊協議的電子簽名的生成。但是在其他的應用中,SHA-1 不應該用於電子簽名
SHA-1用於電子簽名的驗證:
對於電子簽名的驗證,SHA-1可以被用於傳統應用
"SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, and SHA-512/256:
所有散列計算程序都支持這些哈希函數的使用。
NISI:通信傳輸:傳輸中建議使用的加密算法和密鑰長度
有漏洞的代碼:

MyProprietaryMessageDigest extends MessageDigest { @Override protected byte[] engineDigest() { [...] //Creativity is a bad idea return [...]; } }
使用其中一種信息摘要算法去升級你的代碼。這些算法非常強大,能足夠滿足你的安全需求。
解決方案示例:

MessageDigest sha256Digest = MessageDigest.getInstance("SHA256"); sha256Digest.update(password.getBytes());
引用:
NIST Approved Hashing Algorithms
CWE-327: Use of a Broken or Risky Cryptographic Algorithm
讀取文件的缺陷
漏洞特征: FILE_UPLOAD_FILENAME
通過篡改FileUpload API 提供的文件名,客戶端可以任意訪問系統中的文件
比如:

"../../../config/overide_file" "shell.jsp\u0000expected.gif"
所以,上面的這些值應該沒有做任何過濾就直接進入到了文件系統api之中。如果可能,應用應該生成自己的文件名,並且使用它們。
即使這樣,被提供的文件名也要去驗證它們的有效性,以確保它們沒有包含未授權的路徑(比如./\)和未授權的文件。
引用:
Securiteam: File upload security recommendations
CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
WASC-33: Path Traversal
OWASP: Path Traversal
CAPEC-126: Path Traversal
CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
正則dos
漏洞特征: REDOS
正則表達式(regexs)經常導致拒絕服務攻擊((DOS)。這是因為當正則表達式引擎分析一些字符串的時候會消耗大量的時間,而這也取決於正則是怎么寫的。
比如,對於正則^(a+)+$
,如果輸入"aaaaaaaaaaaaaaaaX",就會讓正則表達式引擎分析65536種不同的路徑。
所以,可能只要客戶端發送一個請求就可以讓服務器端消耗巨大的計算資源。問題可能就是類似於這樣的正則表達式,由於括號內的+ (or a )和括號外的+ (or a ) ,當輸入相同字符串的時候,可能會有兩種不同的處理方式。以這樣的方式去寫正則,+號會消耗字符'a'。為了修復這樣問題,正則表達式應該被重寫,目的是消除歧義.比如,上面那個有問題的正則表達式就可以被改寫為^a+$
,無論如何,這可能是作者的意思。總之,這可能是原來正則表達式的意思,這個新正則表達式會更快的匹配字符串,並且也不會受到ReDos攻擊。
引用:
Sebastian Kubeck's Weblog: Detecting and Preventing ReDoS Vulnerabilities
[1] OWASP: Regular expression Denial of Service
CWE-400: Uncontrolled Resource Consumption ('Resource Exhaustion')
參考:
http://find-sec-bugs.github.io/bugs.htm