Find-Sec-Bugs 漏洞范例

第一章 Find-sec-bugs简介

  1. 插件介绍:
    Find-Sec-Bugs 是一款本地 bug 扫描插件 “FindBugs-IDEA” 的 Java 安全漏洞规则扩展库,它支持在多种主流 IDE 环境进行安装:Eclipse, IntelliJ, Android Studio 和 NetBeans。
  2. 扫描范围:
    只扫描 Java 代码,支持主流的 Java 开发框架,比如 Spring-MVC, Struts 等。
  3. 扫描漏洞类型:
    通过扫描源代码,能够发现130种(2019.3.27版本)不同的安全漏洞类型,关于漏洞类型请参考:https://find-sec-bugs.github.io/bugs.htm。

第二章 Find-sec-bugs漏洞范例

以下的错误范例,源自Find-sec-bugs官网,想要查看原版可以参考:http://find-sec-bugs.github.io/bugs.htm

1. 可预测的伪随机数发生器

Predictable pseudorandom number generator
漏洞特征:PREDICTABLE_RANDOM
在某些关键的安全环境中使用可预测的随机数可能会导致漏洞,比如,当这个值被作为:
• csrf token:如果攻击者可以预测csrf的token值的话,就可以发动csrf攻击
• 重置密码的token(通过邮件发送):如果重置密码的token被替换的话,那么就会导致用户账户被接管,因为攻击者会猜测到重置密码的链接。
• 其他包含秘密的信息
修复这个漏洞最快的方式是用强随机数生成器( 比如:java.security.SecureRandom)替换掉
java.util.Random
有漏洞的代码:

String generateSecretToken() {
    Random 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)

2. 可预测的伪随机数发生器(Scala)

Predictable pseudorandom number generator (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)

3. 没有做任何安全检查的servlet 参数

Untrusted servlet parameter
漏洞特征:SERVLET_PARAMETER
Servlet 会从各种函数中获取到GET和POST的值。这些被获取的值肯定是不安全的。在进入到敏感的api函数之前你可能需要验证和过滤这些值:
• sql 查询 (可能导致sql注入)
• 文件操作 ( 可能会导致目录穿越 )
• 命令执行 ( 可能会导致命令注入 )
• html解析 (可能会导致xss)
• 其他的
引用:
CWE-20: Improper Input Validation

4. 没有做任何安全检查Content-Type 头

Untrusted Content-Type header
漏洞特征:SERVLET_CONTENT_TYPE
服务器端程序通过客户端收集http的Content-Type的值。这个值可能会影响影响应用的安全性
引用:
CWE-807: Untrusted Inputs in a Security Decision

5. 没有做任何安全检查Hostname 头

Untrusted Hostname header
漏洞特征: 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

6. 没有做任何安全检查的session cookie值

Untrusted session cookie value
漏洞特征: 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

7. 没有做任何安全检查的查询字符串

Untrusted query string
漏洞特征: 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

8. 没有做任何安全检查的HTTP头

HTTP headers untrusted
漏洞特征:SERVLET_HEADER
http请求头很容易会被用户所修改。通常,不要假想请求来自于没有被黑客修改的常规浏览器。我建议你,不要相信客户端传递进来的http头部值
引用:
CWE-807: Untrusted Inputs in a Security Decision

9. 没有做任何安全检查的Referer值

Untrusted Referer header
漏洞特征:SERVLET_HEADER_REFERER
行为:
• 如果请求来自于恶意用户,那么Referer的值会是任意的情况。
• 如果请求来自于另一个安全的源(https),那么Referer头就是空的。
建议:
• 访问控制不应该基于此标头的值。
• csrf保护不应该仅基于此值。( 因为这个选项 )
引用:
CWE-807: Untrusted Inputs in a Security Decision

10. 没有做任何安全检查的User-Agent值

Untrusted User-Agent header
漏洞特征: SERVLET_HEADER_USER_AGENT
“User-Agent” 很容易被客户端伪造,不建议基于不同的User-Agent(比如爬虫的UA)来适配不同的行为。
引用:
CWE-807: Untrusted Inputs in a Security Decision

11. 潜在的cookie中包含敏感数据

Potentially sensitive data in a cookie
漏洞特征: COOKIE_USAGE
存储在客户端中cookie的数据不应该包含敏感数据或者与session相关的数据。大多数情况下,敏感数据应该仅仅存储在session中,并且通过通过用户的session值去访问。详细请看HttpSession (HttpServletRequest.getSession())
客户端cookie应该是比特定会话维持时间更长且独立于特殊会话
引用:
CWE-315: Cleartext Storage of Sensitive Information in a Cookie

12. 潜在的路径穿越(文件读取)

Potential Path Traversal (file read)
漏洞特征: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’)

13. 潜在的路径穿越(文件写)

Potential Path Traversal (file write)
漏洞特征: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’)

14. 潜在的路径穿越(文件读取)

Potential Path Traversal (file read)
漏洞特征: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’)

15. 潜在的命令注入

Potential Command Injection
漏洞特征: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’)

16. 潜在的命令注入(Scala)

Potential 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’)

17. 文件类函数没有过滤空字符

FilenameUtils not filtering null bytes
漏洞特征: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

18. 证书管理器接受任何证书

TrustManager that accept any certificates
漏洞特征: 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

19. HostnameVerifier 接收任何签名证书

HostnameVerifier that accept any signed certificates
漏洞规则: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

20. 发现JAX-WS SOAP服务器端

Found JAX-WS SOAP endpoint
漏洞规则: JAXRS_ENDPOINT
这个方法是一个SOAP Web服务的一部分(JSR224)。
这个网站的安全性应该被分析。例如:
• 权限认证,如果强制实施,就应该被测试
• 访问控制,如果强制实施,就应该被测试
• 输入应该被追踪,因为可能会有潜在的漏洞
• 聊天程序应该使用SSL
引用:
OWASP: Web Service Security Cheat Sheet
CWE-20: Improper Input Validation

21. 发现JAX-RS REST服务器端

Found JAX-RS REST endpoint
漏洞规则: 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

22. 发现Tapestry页面

Found Tapestry page
漏洞规则: 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

23. 发现Wicket的web页面

Found Wicket WebPage
漏洞特征:WICKET_ENDPOINT
这个类代表一个Wicket web页面。输入的数据会被来自实例中的PageParameters读取,然后把它们送入后端处理程序。当前页面会被映射到视图之中[/package/WebPageName].html.
在应用中的每一个Wicket页面应该被调查,确保所有的输入都能被自动的映射,并在这些参数被使用之前都是有效的。
引用:
Apache Wicket Home Page
CWE-20: Improper Input Validation

24. MD2, MD4 和 MD5都是脆弱的哈希函数

MD2, MD4 and MD5 are weak hash functions
漏洞特征: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();

解决方案(Using bouncy castle使用轻量级密码术包):

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

25. SHA-1 是脆弱的哈希算法

SHA-1 is a weak hash function
漏洞特征: 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

26. DefaultHttpClient的默认构造函数与TLS 1.2不兼容

DefaultHttpClient with default constructor is not compatible with 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

27. 脆弱的SSLContext

Weak SSLContext
漏洞特征: SSL_CONTEXT
有漏洞的代码:

SSLContext.getInstance("SSL");

解决方案:
用下面的代码升级你的代码,并且配置jvm的https.protocols选项,使其包含TLSv1.2

SSLContext.getInstance("TLS"); 

引用:
Diagnosing TLS, SSL, and HTTPS

28. 习惯使用的信息摘要算法

Message digest is custom
漏洞特征: CUSTOM_MESSAGE_DIGEST
自己实现消息摘要算法是不靠谱的。
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

29. 读取文件的缺陷

Tainted filename read
漏洞特征: 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’)

30. 正则dos

Regex DOS (ReDOS)
漏洞特征: REDOS
正则表达式(regexs)经常导致拒绝服务攻击((DOS)。这是因为当正则表达式引擎分析一些字符串的时候会消耗大量的时间,而这也取决于正则是怎么写的。
比如,对于正则^(a+)+ , " a a a a a a a a a a a a a a a a X " 65536 + ( o r a ) + ( o r a ) + a . 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’)

31. xml解析导致xxe漏洞

XML parsing vulnerable to XXE (XMLStreamReader)
漏洞特征:XXE_XMLSTREAMREADER
当xml解析程序收到不信任的输入且如果xml解析程序支持外部实体解析的时候,那么造成xml实体解析攻击(xxe)
危害1:探测本地文件内容(xxe:xml 外部实体)

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
   <!ENTITY xxe SYSTEM "file:///etc/passwd" > ]>
<foo>&xxe;</foo>

危害2:拒绝服务攻击 (xee:xml 外部实体膨胀)

<?xml version="1.0"?>
<!DOCTYPE lolz [
 <!ENTITY lol "lol">
 <!ELEMENT lolz (#PCDATA)>
 <!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
 <!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;">
 <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
[...]
 <!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
]>
<lolz>&lol9;</lolz>

解决方法:
为了避免解析xml带来的攻击,你应该按照下面的示例代码修改你的代码
有漏洞的代码:

    public void parseXML(InputStream input) throws XMLStreamException {

    XMLInputFactory factory = XMLInputFactory.newFactory();
    XMLStreamReader reader = factory.createXMLStreamReader(input);
    [...]
}

禁用外部实体的解决方案:

public void parseXML(InputStream input) throws XMLStreamException {

    XMLInputFactory factory = XMLInputFactory.newFactory();
    factory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
    XMLStreamReader reader = factory.createXMLStreamReader(input);
    [...]
}

禁用DTD的方案:

public void parseXML(InputStream input) throws XMLStreamException {

    XMLInputFactory factory = XMLInputFactory.newFactory();
    factory.setProperty(XMLInputFactory.SUPPORT_DTD, false);
    XMLStreamReader reader = factory.createXMLStreamReader(input);
    [...]
}

引用:
CWE-611: Improper Restriction of XML External Entity Reference (‘XXE’)
CERT: IDS10-J. Prevent XML external entity attacks
OWASP.org: XML External Entity (XXE) Processing
WS-Attacks.org: XML Entity Expansion
WS-Attacks.org: XML External Entity DOS
WS-Attacks.org: XML Entity Reference Attack
Identifying Xml eXternal Entity vulnerability (XXE)
JEP 185: Restrict Fetching of External XML Resources

32. xml解析导致xxe漏洞(XPathExpression)

XML parsing vulnerable to XXE (XPathExpression)
漏洞特征:XXE_XPATH
当xml解析程序收到不信任的输入且如果xml解析程序支持外部实体解析的时候,那么造成xml实体解析攻击(xxe)
危害1:探测本地文件内容(xxe:xml 外部实体)

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
   <!ENTITY xxe SYSTEM "file:///etc/passwd" > ]>
<foo>&xxe;</foo>

危害2:拒绝服务攻击 (xee:xml 外部实体膨胀)

<?xml version="1.0"?>
<!DOCTYPE lolz [
 <!ENTITY lol "lol">
 <!ELEMENT lolz (#PCDATA)>
 <!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
 <!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;">
 <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
[...]
 <!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
]>
<lolz>&lol9;</lolz>

解决方法:
为了避免解析xml带来的攻击,你应该按照下面的示例代码修改你的代码
有漏洞的代码:

DocumentBuilder builder = df.newDocumentBuilder();

XPathFactory xPathFactory = XPathFactory.newInstance();
XPath xpath = xPathFactory.newXPath();
XPathExpression xPathExpr = xpath.compile("/somepath/text()");

xPathExpr.evaluate(new InputSource(inputStream));

下面的两个片段展示了可能的解决方案。你可以设置其中一个,或者两个都设置
使用"Secure processing" 模式的解决方案

DocumentBuilderFactory df = DocumentBuilderFactory.newInstance();
df.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
DocumentBuilder builder = df.newDocumentBuilder();

[...]

xPathExpr.evaluate( builder.parse(inputStream) );

禁用DTD的解决方案:
通过禁用DTD,大多数的xxe攻击都可以被避免

DocumentBuilderFactory df = DocumentBuilderFactory.newInstance();
spf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
DocumentBuilder builder = df.newDocumentBuilder();

[...]

xPathExpr.evaluate( builder.parse(inputStream) );

引用:
CWE-611: Improper Restriction of XML External Entity Reference (‘XXE’)
CERT: IDS10-J. Prevent XML external entity attacks
OWASP.org: XML External Entity (XXE) Processing
WS-Attacks.org: XML Entity Expansion
WS-Attacks.org: XML External Entity DOS
WS-Attacks.org: XML Entity Reference Attack
Identifying Xml eXternal Entity vulnerability (XXE)
XML External Entity (XXE) Prevention Cheat Sheet

33. xml解析导致xxe漏洞(SAXParser)

XML parsing vulnerable to XXE (SAXParser)
漏洞特征:XXE_SAXPARSER
当xml解析程序收到不信任的输入且如果xml解析程序支持外部实体解析的时候,那么造成xml实体解析攻击(xxe)
危害1:探测本地文件内容(xxe:xml 外部实体)

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
   <!ENTITY xxe SYSTEM "file:///etc/passwd" > ]>
<foo>&xxe;</foo>

危害2:拒绝服务攻击 (xee:xml 外部实体膨胀)

<?xml version="1.0"?>
<!DOCTYPE lolz [
 <!ENTITY lol "lol">
 <!ELEMENT lolz (#PCDATA)>
 <!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
 <!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;">
 <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
[...]
 <!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
]>
<lolz>&lol9;</lolz>

解决方法:
为了避免解析xml带来的攻击,你应该按照下面的示例代码修改你的代码
有漏洞的代码:

SAXParser parser = SAXParserFactory.newInstance().newSAXParser();

parser.parse(inputStream, customHandler);

下面的两个片段展示了可能的解决方案。你可以使用其中一个,或者两个都使用
使用"Secure processing" 模式的解决方案:
这个设置能保护你能避免拒绝服务攻击和ssrf漏洞

SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
SAXParser parser = spf.newSAXParser();

parser.parse(inputStream, customHandler);

禁用DTD的解决方案:
通过禁用DTD,大多数的xxe攻击都可以被避免

SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
SAXParser parser = spf.newSAXParser();

parser.parse(inputStream, customHandler);

引用:
CWE-611: Improper Restriction of XML External Entity Reference (‘XXE’)
CERT: IDS10-J. Prevent XML external entity attacks
OWASP.org: XML External Entity (XXE) Processing
WS-Attacks.org: XML Entity Expansion
WS-Attacks.org: XML External Entity DOS
WS-Attacks.org: XML Entity Reference Attack
Identifying Xml eXternal Entity vulnerability (XXE)
Xerces complete features list

34. xml解析导致xxe漏洞(XMLReader)

XML parsing vulnerable to XXE (XMLReader)
漏洞特征:XXE_XMLREADER
当xml解析程序收到不信任的输入且如果xml解析程序支持外部实体解析的时候,那么造成xml实体解析攻击(xxe)
危害1:探测本地文件内容(xxe:xml 外部实体)

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
   <!ENTITY xxe SYSTEM "file:///etc/passwd" > ]>
<foo>&xxe;</foo>

危害2:拒绝服务攻击 (xee:xml 外部实体膨胀)

<?xml version="1.0"?>
<!DOCTYPE lolz [
 <!ENTITY lol "lol">
 <!ELEMENT lolz (#PCDATA)>
 <!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
 <!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;">
 <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
[...]
 <!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
]>
<lolz>&lol9;</lolz>

解决方法:
为了避免解析xml带来的攻击,你应该按照下面的示例代码修改你的代码
有漏洞的代码:

XMLReader reader = XMLReaderFactory.createXMLReader();
reader.setContentHandler(customHandler);
reader.parse(new InputSource(inputStream));

下面的两个片段展示了可能的解决方案。你可以使用其中一个,或者两个都使用
使用"Secure processing" 模式的解决方案:
这个设置能保护你能避免拒绝服务攻击和ssrf漏洞

    XMLReader reader = XMLReaderFactory.createXMLReader();
    reader.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
    reader.setContentHandler(customHandler);

reader.parse(new InputSource(inputStream));

禁用DTD的解决方案:
通过禁用DTD,大多数的xxe攻击都可以被避免

XMLReader reader = XMLReaderFactory.createXMLReader();
reader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
reader.setContentHandler(customHandler);

reader.parse(new InputSource(inputStream));

引用:
CWE-611: Improper Restriction of XML External Entity Reference (‘XXE’)
CERT: IDS10-J. Prevent XML external entity attacks
OWASP.org: XML External Entity (XXE) Processing
WS-Attacks.org: XML Entity Expansion
WS-Attacks.org: XML External Entity DOS
WS-Attacks.org: XML Entity Reference Attack
Identifying Xml eXternal Entity vulnerability (XXE)
Xerces complete features list

35. xml解析导致xxe漏洞(DocumentBuilder)

XML parsing vulnerable to XXE (DocumentBuilder)
漏洞特征:XXE_DOCUMENT
当xml解析程序收到不信任的输入且如果xml解析程序支持外部实体解析的时候,那么造成xml实体解析攻击(xxe)
危害1:探测本地文件内容(xxe:xml 外部实体)

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
   <!ENTITY xxe SYSTEM "file:///etc/passwd" > ]>
<foo>&xxe;</foo>

危害2:拒绝服务攻击 (xee:xml 外部实体膨胀)

<?xml version="1.0"?>
<!DOCTYPE lolz [
 <!ENTITY lol "lol">
 <!ELEMENT lolz (#PCDATA)>
 <!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
 <!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;">
 <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
[...]
 <!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
]>
<lolz>&lol9;</lolz>

解决方法:
为了避免解析xml带来的攻击,你应该按照下面的示例代码修改你的代码
有漏洞的代码:

DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();

Document doc = db.parse(input);

下面的两个片段展示了可能的解决方案。你可以使用其中一个,或者两个都使用
使用"Secure processing" 模式的解决方案:
这个设置能保护你能避免拒绝服务攻击和ssrf漏洞

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
DocumentBuilder db = dbf.newDocumentBuilder();

Document doc = db.parse(input);

禁用DTD的解决方案:
通过禁用DTD,大多数的xxe攻击都可以被避免

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
DocumentBuilder db = dbf.newDocumentBuilder();

Document doc = db.parse(input);

引用:
CWE-611: Improper Restriction of XML External Entity Reference (‘XXE’)
CERT: IDS10-J. Prevent XML external entity attacks
OWASP.org: XML External Entity (XXE) Processing
WS-Attacks.org: XML Entity Expansion
WS-Attacks.org: XML External Entity DOS
WS-Attacks.org: XML Entity Reference Attack
Identifying Xml eXternal Entity vulnerability (XXE)
Xerces complete features list

36. xml解析导致xxe漏洞(TransformerFactory)

XML parsing vulnerable to XXE (TransformerFactory)
漏洞特征:XXE_DTD_TRANSFORM_FACTORY
当xml解析程序收到不信任的输入且如果xml解析程序支持外部实体解析的时候,那么造成xml实体解析攻击(xxe)
危害1:探测本地文件内容(xxe:xml 外部实体)

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
   <!ENTITY xxe SYSTEM "file:///etc/passwd" > ]>
<foo>&xxe;</foo>

危害2:拒绝服务攻击 (xee:xml 外部实体膨胀)

<?xml version="1.0"?>
<!DOCTYPE lolz [
 <!ENTITY lol "lol">
 <!ELEMENT lolz (#PCDATA)>
 <!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
 <!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;">
 <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
[...]
 <!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
]>
<lolz>&lol9;</lolz>

解决方法:
为了避免解析xml带来的攻击,你应该按照下面的示例代码修改你的代码
有漏洞的代码:

Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.transform(input, result);

下面的两个片段展示了可能的解决方案。你可以使用其中一个,或者两个都使用
使用"Secure processing" 模式的解决方案:
这个设置能保护你能避免拒绝服务攻击和ssrf漏洞

TransformerFactory factory = TransformerFactory.newInstance();
factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "all");
factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "all");

Transformer transformer = factory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");

transformer.transform(input, result);

禁用DTD的解决方案:
通过禁用DTD,大多数的xxe攻击都可以被避免

TransformerFactory factory = TransformerFactory.newInstance();
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);

Transformer transformer = factory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");

transformer.transform(input, result);

引用:
CWE-611: Improper Restriction of XML External Entity Reference (‘XXE’)
CERT: IDS10-J. Prevent XML external entity attacks
OWASP.org: XML External Entity (XXE) Processing
WS-Attacks.org: XML Entity Expansion
WS-Attacks.org: XML External Entity DOS
WS-Attacks.org: XML Entity Reference Attack
Identifying Xml eXternal Entity vulnerability (XXE)

37. XSLT解析导致xxe漏洞(TransformerFactory)

XSLT parsing vulnerable to XXE (TransformerFactory)
漏洞特征:XXE_XSLT_TRANSFORM_FACTORY
当xml解析程序收到不信任的输入且如果xml解析程序支持外部实体解析的时候,那么造成xml实体解析攻击(xxe)
危害1:探测本地文件内容(xxe:xml 外部实体)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:template match="/">
       <xsl:value-of select="document('/etc/passwd')">
   </xsl:value-of></xsl:template>
</xsl:stylesheet>

解决方法:
为了避免解析xml带来的攻击,你应该按照下面的示例代码修改你的代码
有漏洞的代码:

Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.transform(input, result);

下面的两个片段展示了可能的解决方案。你可以使用其中一个,或者两个都使用
使用"Secure processing" 模式的解决方案:
这个设置能保护你能避免ssrf漏洞但是不能避免拒绝服务攻击

TransformerFactory factory = TransformerFactory.newInstance();
factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "all");
factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "all");

Transformer transformer = factory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");

transformer.transform(input, result);

禁用DTD的解决方案:
这个设置能保护你能避免ssrf漏洞但是不能避免拒绝服务攻击

TransformerFactory factory = TransformerFactory.newInstance();
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);

Transformer transformer = factory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");

transformer.transform(input, result);

引用:
CWE-611: Improper Restriction of XML External Entity Reference (‘XXE’)
CERT: IDS10-J. Prevent XML external entity attacks
OWASP.org: XML External Entity (XXE) Processing
WS-Attacks.org: XML Entity Expansion
WS-Attacks.org: XML External Entity DOS
WS-Attacks.org: XML Entity Reference Attack
Identifying Xml eXternal Entity vulnerability (XXE)

38. 潜在的XPath注入

Potential XPath Injection
漏洞特征: XPATH_INJECTION
XPath注入的危险程度就像sql注入一样。如果XPath查询包含不信任的用户输入,那么数据库就会被完全暴露。这样就可以让攻击者访问未授权的数据或者在目标xml数据库中放入恶意数据。
引用:
WASC-39: XPath Injection
OWASP: Top 10 2013-A1-Injection
CWE-643: Improper Neutralization of Data within XPath Expressions (‘XPath Injection’)
CERT: IDS09-J. Prevent XPath Injection (archive)
Black Hat Europe 2012: Hacking XPath 2.0
Balisage: XQuery Injection

39. 发现Struts 1 服务器端

Found Struts 1 endpoint
漏洞特征: STRUTS1_ENDPOINT
这个类是Struts 1 的Action
曾清一个请求被路由到一个控制器中,Form对象将会被自动的实例化为http参数的对象。这些参数应该被严格检查,以保证它们是安全的。

40. 发现Struts 2 服务器端

Found Struts 2 endpoint
漏洞特征:STRUTS2_ENDPOINT
在Struts 2中,服务器端是简单的Java对象 (POJOs),这就意味着没有接口/类 需要被实现/拓展
当一个请求被路由到它的控制器的时候(像这些被选择的类),http提供的参数会被自动的映射到类中的setters中。所以,所有类中的setters都应该被看成来自不被信任源的输入,即使form中没有包含那些值。一个攻击者都被在请求中插入一些额外的值,他们会被当成对象,只要对象具有这样的setter。这些参数应该被严格检查,以保证它们是安全的。

41. 发现Spring 服务器端

Found Spring endpoint
漏洞特征: SPRING_ENDPOINT
这个类是一个Spring的控制器。所有方法的注解都在RequestMapping(还有一些简化注解在GetMapping, PostMapping, PutMapping, DeleteMapping, 和 PatchMapping),这些方法都能被远程访问到。这些类应该被严格的分析,以保证暴露给远程的方法是安全的,不会被攻击者轻易攻击。

42. Spring关闭 CSRF保护

Spring CSRF protection disabled
漏洞特征: SPRING_CSRF_PROTECTION_DISABLED
对于标准的web应用程序来讲,关闭Spring的CSRF保护显然是不安全的。
禁用此保护的有效使用场景是服务器暴露一个可以改变状态的接口,这个接口仅可以被非浏览器操控。
不安全的配置

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();
    }
}

引用:
Spring Security Official Documentation: When to use CSRF protection
OWASP: Cross-Site Request Forgery
OWASP: CSRF Prevention Cheat Sheet
CWE-352: Cross-Site Request Forgery (CSRF)

43. Spring 中不受CSRF限制的RequestMapping

Spring CSRF unrestricted RequestMapping
漏洞特征: SPRING_CSRF_UNRESTRICTED_REQUEST_MAPPING
通过默认的映射所有的HTTP请求方法都会被RequestMapping注解。可是,http请求中的GET, HEAD, TRACE, 和OPTIONS(可能会导致tokens被泄露)方法不会默认开启csrf保护。所以,被RequestMapping注解的可以改变状态的方法和 POST, PUT, DELETE, 或者 PATCH这些http请求方法都会受到csrf攻击。
有漏洞的代码:

@Controller
public class UnsafeController {

    @RequestMapping("/path")
    public void writeData() {
        // State-changing operations performed within this method.
    }
}

解决方案(Spring Framework 4.3和更新的版本)

@Controller
public class SafeController {

    /**
     * For methods without side-effects use @GetMapping.
     */
    @GetMapping("/path")
    public String readData() {
        // No state-changing operations performed within this method.
        return "";
    }

    /**
     * For state-changing methods use either @PostMapping, @PutMapping, @DeleteMapping, or @PatchMapping.
     */
    @PostMapping("/path")
    public void writeData() {
        // State-changing operations performed within this method.
    }
}

解决方案(在Spring Framework 4.3之前的版本)

@Controller
public class SafeController {

    /**
     * For methods without side-effects use either
     * RequestMethod.GET, RequestMethod.HEAD, RequestMethod.TRACE, or RequestMethod.OPTIONS.
     */
    @RequestMapping(value = "/path", method = RequestMethod.GET)
    public String readData() {
        // No state-changing operations performed within this method.
        return "";
    }

    /**
     * For state-changing methods use either
     * RequestMethod.POST, RequestMethod.PUT, RequestMethod.DELETE, or RequestMethod.PATCH.
     */
    @RequestMapping(value = "/path", method = RequestMethod.POST)
    public void writeData() {
        // State-changing operations performed within this method.
    }
}

引用:
[Spring Security Official Documentation: Use proper HTTP verbs (CSRF protection)](Spring Security Official Documentation: Use proper HTTP verbs (CSRF protection))
[OWASP: Cross-Site Request Forgery](OWASP: Cross-Site Request Forgery)
OWASP: CSRF Prevention Cheat Sheet
CWE-352: Cross-Site Request Forgery (CSRF)

44. 潜在的注入(custom)

Potential injection (custom)
漏洞特征: CUSTOM_INJECTION
扫描工具所识别的函数存在注射问题。应验证输入并争取转义。
有漏洞的代码:
SqlUtil.execQuery("select * from UserEntity t where id = " + parameterInput);
wiki在线有很详细的教程关于如何配置custom
引用:
WASC-19: SQL Injection
OWASP: Top 10 2013-A1-Injection
OWASP: SQL Injection Prevention Cheat Sheet
OWASP: Query Parameterization Cheat Sheet
CAPEC-66: SQL Injection
CWE-89: Improper Neutralization of Special Elements used in an SQL Command (‘SQL Injection’)

45. 潜在的sql注入

Potential SQL Injection
漏洞特征:SQL_INJECTION
输入进sql查询的数据应该通过严格的检查。在预编译中绑定参数可以更容易的缓解sql注入带来的危害。或者,每一个参数应该被正确的转义。
有漏洞的代码:

createQuery("select * from User where id = '"+inputId+"'");

解决方案:

import org.owasp.esapi.Encoder;

createQuery("select * from User where id = '"+Encoder.encodeForSQL(inputId)+"'");

引用(sql注入)
WASC-19: SQL Injection
CAPEC-66: SQL Injection
CWE-89: Improper Neutralization of Special Elements used in an SQL Command (‘SQL Injection’)
OWASP: Top 10 2013-A1-Injection
OWASP: SQL Injection Prevention Cheat Sheet
OWASP: Query Parameterization Cheat Sheet

46. 在Turbine中潜在的sql注入

Potential SQL Injection with Turbine
漏洞特征:SQL_INJECTION_TURBINE
输入进sql查询的数据应该通过严格的检查。在预编译中绑定参数可以更容易的缓解sql注入带来的危害。或者,每一个参数应该被正确的转义。
Turbine API 提供DSL在java代码中构建查询
有漏洞的代码:

List<Record> BasePeer.executeQuery( "select * from Customer where id=" + inputId );  

解决方案(使用Criteria DSL):

Criteria c = new Criteria();
c.add( CustomerPeer.ID, inputId );

List<Customer> customers = CustomerPeer.doSelect( c );

解决方案(使用特殊方法):

Customer customer = CustomerPeer.retrieveByPK( new NumberKey( inputId ) );

解决方法(使用OWASP提供的编码方法)

import org.owasp.esapi.Encoder;

BasePeer.executeQuery("select * from Customer where id = '"+Encoder.encodeForSQL(inputId)+"'");

引用(Turbine):
Turbine Documentation: Criteria Howto

引用(sql注入)
WASC-19: SQL Injection
CAPEC-66: SQL Injection
CWE-89: Improper Neutralization of Special Elements used in an SQL Command (‘SQL Injection’)
OWASP: Top 10 2013-A1-Injection
OWASP: SQL Injection Prevention Cheat Sheet
OWASP: Query Parameterization Cheat Sheet

47. 潜在的SQL/HQL注入(Hibernate)

Potential SQL/HQL Injection (Hibernate)
漏洞特征:SQL_INJECTION_HIBERNATE
输入进sql查询的数据应该通过严格的检查。在预编译中绑定参数可以更容易的缓解sql注入带来的危害。或者,可以使用Hibernate的Criteria。
有漏洞的代码:

Session session = sessionFactory.openSession();
Query q = session.createQuery("select t from UserEntity t where id = " + input);
q.execute(); 

解决方案:

Session session = sessionFactory.openSession();
Query q = session.createQuery("select t from UserEntity t where id = :userId");
q.setString("userId",input);
q.execute();

动态查询参数法解决方案(Hibernate Criteria)

Session session = sessionFactory.openSession();
Query q = session.createCriteria(UserEntity.class)
    .add( Restrictions.like("id", input) )
    .list();
q.execute();

引用(Hibernate)
Hibernate Documentation: Query Criteria
Hibernate Javadoc: Query Object
HQL for pentesters: Guideline to test if the suspected code is exploitable.
引用(sql注入)
WASC-19: SQL Injection
CAPEC-66: SQL Injection
CWE-89: Improper Neutralization of Special Elements used in an SQL Command (‘SQL Injection’)
OWASP: Top 10 2013-A1-Injection
OWASP: SQL Injection Prevention Cheat Sheet
OWASP: Query Parameterization Cheat Sheet

48. 潜在的sql/JDOQL注入(JDO)

Potential SQL/JDOQL Injection (JDO)
漏洞特征:SQL_INJECTION_JDO
输入进sql查询的数据应该通过严格的检查。在预编译中绑定参数可以更容易的缓解sql注入带来的危害。
有漏洞的代码:

PersistenceManager pm = getPM();

Query q = pm.newQuery("select * from Users where name = " + input);
q.execute(); 

解决方案:

PersistenceManager pm = getPM();

Query q = pm.newQuery("select * from Users where name = nameParam");
q.declareParameters("String nameParam");
q.execute(input); 

引用(JDO):
JDO: Object Retrieval
引用(sql注入)
WASC-19: SQL Injection
CAPEC-66: SQL Injection
CWE-89: Improper Neutralization of Special Elements used in an SQL Command (‘SQL Injection’)
OWASP: Top 10 2013-A1-Injection
OWASP: SQL Injection Prevention Cheat Sheet
OWASP: Query Parameterization Cheat Sheet

49. 潜在的sql/JPQL注入(JPA)

Potential SQL/JPQL Injection (JPA)
漏洞特征: SQL_INJECTION_JPA
输入进sql查询的数据应该通过严格的检查。在预编译中绑定参数可以更容易的缓解sql注入带来的危害。
有漏洞的代码:

EntityManager pm = getEM();

TypedQuery<UserEntity> q = em.createQuery(
    String.format("select * from Users where name = %s", username),
    UserEntity.class);

UserEntity res = q.getSingleResult();

解决方案:

TypedQuery<UserEntity> q = em.createQuery(
    "select * from Users where name = usernameParam",UserEntity.class)
    .setParameter("usernameParam", username);

UserEntity res = q.getSingleResult();

引用 (JPA)
The Java EE 6 Tutorial: Creating Queries Using the Java Persistence Query Language
引用(sql注入)
WASC-19: SQL Injection
CAPEC-66: SQL Injection
CWE-89: Improper Neutralization of Special Elements used in an SQL Command (‘SQL Injection’)
OWASP: Top 10 2013-A1-Injection
OWASP: SQL Injection Prevention Cheat Sheet
OWASP: Query Parameterization Cheat Sheet

50. 潜在的JDBC注入(Spring JDBC)

Potential JDBC Injection (Spring JDBC)
漏洞特征:SQL_INJECTION_SPRING_JDBC
输入进sql查询的数据应该通过严格的检查。在预编译中绑定参数可以更容易的缓解sql注入带来的危害。或者,每一个参数应该被正确的转义。
有漏洞的代码:

JdbcTemplate jdbc = new JdbcTemplate();
int count = jdbc.queryForObject("select count(*) from Users where name = '"+paramName+"'", Integer.class);  

解决方案:

JdbcTemplate jdbc = new JdbcTemplate();
int count = jdbc.queryForObject("select count(*) from Users where name = ?", Integer.class, paramName);  

引用 (Spring JDBC)
Spring Official Documentation: Data access with JDBC
引用(sql注入)
WASC-19: SQL Injection
CAPEC-66: SQL Injection
CWE-89: Improper Neutralization of Special Elements used in an SQL Command (‘SQL Injection’)
OWASP: Top 10 2013-A1-Injection
OWASP: SQL Injection Prevention Cheat Sheet
OWASP: Query Parameterization Cheat Sheet

51. 潜在的JDBC注入

Potential JDBC Injection
漏洞特征:SQL_INJECTION_JDBC
输入进sql查询的数据应该通过严格的检查。在预编译中绑定参数可以更容易的缓解sql注入带来的危害。
有漏洞的代码:

Connection conn = [...];
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("update COFFEES set SALES = "+nbSales+" where COF_NAME = '"+coffeeName+"'");  

解决方案:

Connection conn = [...];
conn.prepareStatement("update COFFEES set SALES = ? where COF_NAME = ?");
updateSales.setInt(1, nbSales);
updateSales.setString(2, coffeeName);  

引用 (JDBC)
Oracle Documentation: The Java Tutorials > Prepared Statements
引用(sql注入)
WASC-19: SQL Injection
CAPEC-66: SQL Injection
CWE-89: Improper Neutralization of Special Elements used in an SQL Command (‘SQL Injection’)
OWASP: Top 10 2013-A1-Injection
OWASP: SQL Injection Prevention Cheat Sheet
OWASP: Query Parameterization Cheat Sheet

52. 潜在的Scala Slick注入

Potential Scala Slick Injection
漏洞特征:SCALA_SQL_INJECTION_SLICK
输入进sql查询的数据应该通过严格的检查。在预编译中绑定参数可以更容易的缓解sql注入带来的危害。
有漏洞的代码:

db.run {
  sql"select * from people where name = '#$value'".as[Person]
} 

解决方案:

db.run {
  sql"select * from people where name = $value".as[Person]
} 

引用(sql注入)
WASC-19: SQL Injection
CAPEC-66: SQL Injection
CWE-89: Improper Neutralization of Special Elements used in an SQL Command (‘SQL Injection’)
OWASP: Top 10 2013-A1-Injection
OWASP: SQL Injection Prevention Cheat Sheet
OWASP: Query Parameterization Cheat Sheet

53. 潜在的Scala Anorm注入

Potential Scala Anorm Injection
漏洞特征:SCALA_SQL_INJECTION_ANORM
输入进sql查询的数据应该通过严格的检查。在预编译中绑定参数可以更容易的缓解sql注入带来的危害。
有漏洞的代码:

val peopleParser = Macro.parser[Person]("id", "name", "age")

DB.withConnection { implicit c =>
  val people: List[Person] = SQL("select * from people where name = '" + value + "'").as(peopleParser.*)
}

解决方案:

val peopleParser = Macro.parser[Person]("id", "name", "age")

DB.withConnection { implicit c =>
  val people: List[Person] = SQL"select * from people where name = $value".as(peopleParser.*)
}

引用(sql注入)
WASC-19: SQL Injection
CAPEC-66: SQL Injection
CWE-89: Improper Neutralization of Special Elements used in an SQL Command (‘SQL Injection’)
OWASP: Top 10 2013-A1-Injection
OWASP: SQL Injection Prevention Cheat Sheet
OWASP: Query Parameterization Cheat Sheet

54. 潜在的安卓sql注入

Potential Android SQL Injection
漏洞特征:SQL_INJECTION_ANDROID
输入进sql查询的数据应该通过严格的检查。在预编译中绑定参数可以更容易的缓解sql注入带来的危害。
有漏洞的代码:

String query = "SELECT * FROM  messages WHERE uid= '"+userInput+"'" ;
Cursor cursor = this.getReadableDatabase().rawQuery(query,null);

解决方案:

String query = "SELECT * FROM  messages WHERE uid= ?" ;
Cursor cursor = this.getReadableDatabase().rawQuery(query,new String[] {userInput});

引用 (Android SQLite)
InformIT.com: Practical Advice for Building Secure Android Databases in SQLite
Packtpub.com: Knowing the SQL-injection attacks and securing our Android applications from them
Android Database Support (Enterprise Android: Programming Android Database Applications for the Enterprise)
Safe example of Insert, Select, Update and Delete queryies provided by Suragch
引用(sql注入)
WASC-19: SQL Injection
CAPEC-66: SQL Injection
CWE-89: Improper Neutralization of Special Elements used in an SQL Command (‘SQL Injection’)
OWASP: Top 10 2013-A1-Injection
OWASP: SQL Injection Prevention Cheat Sheet
OWASP: Query Parameterization Cheat Sheet

55. 潜在的LDAP注入

Potential LDAP Injection
漏洞特征:LDAP_INJECTION
就像sql,所有进入到ldap查询的语句都必须要保证安全。不幸的是,ldap没有像sql那样的预编译接口。所以,现在的主要防御方式是,在参数进入ladp查询之前对其进行严格的检验。
有漏洞的代码:

NamingEnumeration<SearchResult> answers = context.search("dc=People,dc=example,dc=com",
        "(uid=" + username + ")", ctrls);

引用:
WASC-29: LDAP Injection
OWASP: Top 10 2013-A1-Injection
CWE-90: Improper Neutralization of Special Elements used in an LDAP Query (‘LDAP Injection’)
LDAP Injection Guide: Learn How to Detect LDAP Injections and Improve LDAP Security

56. 在使用脚本引擎时潜在的代码注入

Potential code injection when using Script Engine
漏洞特征:SCRIPT_ENGINE_INJECTION
请严格的评估动态代码。应该仔细分析代码的结构。恶意代码的执行会导致数据的泄露或者执行任意系统指令。
如果你想动态的运行代码,那么请找一个沙箱(见引用)
有害的代码:

public void runCustomTrigger(String script) {
    ScriptEngineManager factory = new ScriptEngineManager();
    ScriptEngine engine = factory.getEngineByName("JavaScript");

    engine.eval(script); //Bad things can happen here.
}

解决方案:
使用“Cloudbees Rhino Sandbox”库就能安全的评估Javascript代码

public void runCustomTrigger(String script) {
    SandboxContextFactory contextFactory = new SandboxContextFactory();
    Context context = contextFactory.makeContext();
    contextFactory.enterContext(context);
    try {
        ScriptableObject prototype = context.initStandardObjects();
        prototype.setParentScope(null);
        Scriptable scope = context.newObject(prototype);
        scope.setPrototype(prototype);

        context.evaluateString(scope,script, null, -1, null);
    } finally {
        context.exit();
    }
}

引用:
Cloudbees Rhino Sandbox: Utility to create sandbox with Rhino (block access to all classes)
CodeUtopia.net: Sandboxing Rhino in Java
Remote Code Execution … by design:里面有一些恶意代码的例子。这些例子能测试沙箱的规则
CWE-94: Improper Control of Generation of Code (‘Code Injection’)
CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (‘Eval Injection’)

57. 使用Spring表达式时潜在的代码注入(SpEL表达式注入)

Potential code injection when using Spring Expression
漏洞规则:SPEL_INJECTION
Spring表达式被用来构建动态的值。源数据应该被严格的检验,以避免未过滤的时候进入到表达式的执行器中
有漏洞的代码:

    public void parseExpressionInterface(Person personObj,String property) {
    
            ExpressionParser parser = new SpelExpressionParser();
    
            //Unsafe if the input is control by the user..
            Expression exp = parser.parseExpression(property+" == 'Albert'");
    
            StandardEvaluationContext testContext = new StandardEvaluationContext(personObj);
            boolean result = exp.getValue(testContext, Boolean.class);

[...]

引用:
CWE-94: Improper Control of Generation of Code (‘Code Injection’)
CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (‘Eval Injection’)
Spring Expression Language (SpEL) - Official Documentation
Minded Security: Expression Language Injection
Remote Code Execution … by design: 里面有一些恶意代码的例子。这些例子能测试沙箱的规则.
Spring Data-Commons: (CVE-2018-1273)
Spring OAuth2: CVE-2018-1260

58. 使用表达式语言时潜在的代码注入(EL)

Potential code injection when using Expression Language (EL)
漏洞特征:EL_INJECTION
表达式语言被用来构建动态的值。源数据应该被严格的检验,以避免未过滤的时候进入到表达式的执行器中
有漏洞的代码:

public void evaluateExpression(String expression) {
    FacesContext context = FacesContext.getCurrentInstance();
    ExpressionFactory expressionFactory = context.getApplication().getExpressionFactory();
    ELContext elContext = context.getELContext();
    ValueExpression vex = expressionFactory.createValueExpression(elContext, expression, String.class);
    return (String) vex.getValue(elContext);
}

引用:
Minded Security: Abusing EL for executing OS commands
The Java EE 6 Tutorial: Expression Language
CWE-94: Improper Control of Generation of Code (‘Code Injection’)
CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (‘Eval Injection’)
Minded Security: Expression Language Injection
Dan Amodio’s blog: Remote Code with Expression Language Injection
Remote Code Execution … by design: 里面有一些恶意代码的例子。这些例子能测试沙箱的规则.

59. 潜在于Seam logging call中的代码注入

Potential code injection in Seam logging call
漏洞特征:SEAM_LOG_INJECTION
Seam Logging API支持表达式语言的解析,目的是引出bean的property到日志消息中去。源数据会利用表达式执行未期望的代码。
在这个代码片段里面,表达式语言被用来构建动态的值。源数据应该被严格的检验,以避免未过滤的时候进入到表达式的执行器中
有漏洞的代码:

public void logUser(User user) {
    log.info("Current logged in user : " + user.getUsername());
    //...
}

解决方案:

public void logUser(User user) {
    log.info("Current logged in user : #0", user.getUsername());
    //...
}

引用:
JBSEAM-5130: Issue documenting the risk
JBoss Seam: Logging (Official documentation)
The Java EE 6 Tutorial: Expression Language
CWE-94: Improper Control of Generation of Code (‘Code Injection’)
CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (‘Eval Injection’)

60. 使用OGNL表达式时潜在的代码注入

Potential code injection when using OGNL expression
漏洞规则: OGNL_INJECTION
表达式语言被用来构建动态的值。源数据应该被严格的检验,以避免未过滤的时候进入到表达式的执行器中
有漏洞的代码:

public void getUserProperty(String property) {
  [...]
  //The first argument is the dynamic expression.
  return ognlUtil.getValue("user."+property, ctx, root, String.class);
}

解决方案
一般,解析OGNL表达式的函数不应该接收用户的输入。它旨在被用于静态配置和jsp。
引用:
HP Enterprise: Struts 2 OGNL Expression Injections by Alvaro Muñoz
Gotham Digital Science: An Analysis Of CVE-2017-5638
Apache Struts2: Vulnerability S2-016
Apache Struts 2 Documentation: OGNL

61. 潜在的http返回报文被分割

Potential HTTP Response Splitting
漏洞特征:HTTP_RESPONSE_SPLITTING
当http请求包含未期望的CR 和 LF字符的时候,服务器可能会把返回的报文流解析成两个HTTP返回报文(而不是一个)。攻击者可以控制第二个报文并且发动诸如xss攻击或者缓存投毒攻击。按照OWASP的建议,实际上,这个问题现代java EE应用服务器所修复,但还是要严格检验输入。如果你关注这个漏洞,你应该测试你算关心的那个平台,看看这个平台是否允许CR或者 LF被注入到返回报文的头部中。这个漏洞常常被报告为低危,如果你使用有漏洞的平台,请仔细检查低危告警。
有漏洞的代码:

String author = request.getParameter(AUTHOR_PARAMETER);
// ...
Cookie cookie = new Cookie("author", author);
response.addCookie(cookie);

引用:
OWASP: HTTP Response Splitting
CWE-113: Improper Neutralization of CRLF Sequences in HTTP Headers (‘HTTP Response Splitting’)
CWE-93: Improper Neutralization of CRLF Sequences (‘CRLF Injection’)

62. 在日志中潜在的CRLF注入

Potential CRLF Injection for logs
漏洞规则:CRLF_INJECTION_LOGS
当未被信任的输入数据进入到日志中,并且没有正确的做过滤。那么攻击者就可以伪造日志数据或者包含恶意内容。插入恶意的实体通常被用于歪曲统计,分散管理员注意力,或者甚至暗示另一方有恶意行为。如果日志文件被一些自动化的程序自动处理,那么攻击者可以通过破坏文件格式使文件无法使用或者注入一些不被期望的特殊字符。攻击者也可能注入代码或者其他的命令到日志文件中,可能会利用日志处理程序中的漏洞(例如:命令注入或者xss)
有漏洞的代码:

String val = request.getParameter("user");
String metadata = request.getParameter("metadata");
[...]
if(authenticated) {
    log.info("User " + val + " (" + metadata + ") was authenticated successfully");
}
else {
    log.info("User " + val + " (" + metadata + ") was not authenticated");
}

恶意用户可能会发送这样的metadata数据:“Firefox) was authenticated successfully\r\n[INFO] User bbb (Internet Explorer”.
解决方案:
你要手工过滤每一个参数

log.info("User " + val.replaceAll("[\r\n]","") + " (" + userAgent.replaceAll("[\r\n]","") + ") was not authenticated");

你要配置日志服务器,目的是替换掉所有消息中的\r\n。 OWASP Security Logging已经在Logback 和 Log4j.实现了这个功能。
引用:
CWE-117: Improper Output Neutralization for Logs
CWE-93: Improper Neutralization of CRLF Sequences (‘CRLF Injection’)
CWE-93: Improper Neutralization of CRLF Sequences (‘CRLF Injection’)
OWASP Security Logging

63. 潜在的外部控制配置

Potential external control of configuration
漏洞特征:EXTERNAL_CONFIG_CONTROL
允许外部控制系统设置会导致系统的中断或者导致应用行为异常,和潜在的恶意行为。攻击者通过提供不存在的catalog名称可能会导致错误,或者链接到未授权的数据库服务器。
有漏洞的代码:

conn.setCatalog(request.getParameter("catalog"));

引用:
CWE-15: External Control of System or Configuration Setting

64. 坏的十六进制数据

Bad hexadecimal concatenation
漏洞特征: BAD_HEXA_CONVERSION
当把十六进制字节数组转换为人类可读的字符串的时候,如果数组是被一个字节一个字节读取的话,可能会导致转换错误。下面这个例子是一个很明显的使用 Integer.toHexString() 做转换的例子,它可能会被字节码中的零字节所截断

MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] resultBytes = md.digest(password.getBytes("UTF-8"));

StringBuilder stringBuilder = new StringBuilder();
for(byte b :resultBytes) {
    stringBuilder.append( Integer.toHexString( b & 0xFF ) );
}

return stringBuilder.toString();

这个错误削弱了hash的计算值,因为它引入了更多的碰撞。比如,用上面的函数计算"0x0679" 和 "0x6709"都会输出679
在下面的解决方案中,使用String.format()替换toHexString()。
stringBuilder.append( String.format( “%02X”, b ) );
引用:
CWE-704: Incorrect Type Conversion or Cast

65. Hazelcast对称加密

Hazelcast symmetric encryption
漏洞规则: HAZELCAST_SYMMETRIC_ENCRYPTION
配置Hazelcast让网络通信使用对称加密(可能是DES或者其他的)
密码本身不能提供完整性和身份验证。使用非对称加密会更好一些
引用:
WASC-04: Insufficient Transport Layer Protection
Hazelcast Documentation: Encryption
CWE-326: Inadequate Encryption Strength

66. 不安全的空密码

NullCipher is insecure
漏洞特征: NULL_CIPHER
空密码很少被使用在生产环境中。它通过返回与明文相同的密文来实现Cipher接口。在极少的环境中,比如测试环境,才可能会出现空密码
有漏洞的代码:

Cipher doNothingCihper = new NullCipher();
[...]
//The ciphertext produced will be identical to the plaintext.
byte[] cipherText = c.doFinal(plainText);

解决方案
避免使用空密码,意外的使用会导致严重的安全风险。
引用:
CWE-327: Use of a Broken or Risky Cryptographic Algorithm

67. 未加密的socket

Unencrypted Socket
漏洞特征:UNENCRYPTED_SERVER_SOCKET
如果网络通信不加密的话,那么传输的数据就会被攻击者拦截并读取里面的内容。
有漏洞的代码:
明文socket(透明传输)

Socket soc = new Socket("www.google.com",80);

解决方案:
ssl socket(加密传输)

Socket soc = SSLSocketFactory.getDefault().createSocket("www.google.com", 443);

使用sslsocket,你需要确保你使用的SSLSocketFactory能验证所提供的证书是否有效,这样你就不会遭受中间人攻击。请阅读owasp中关于传输层协议的那一章,以了解更多正确的做法。
引用:
OWASP: Top 10 2010-A9-Insufficient Transport Layer Protection
OWASP: Top 10 2013-A6-Sensitive Data Exposure
OWASP: Transport Layer Protection Cheat Sheet
WASC-04: Insufficient Transport Layer Protection
CWE-319: Cleartext Transmission of Sensitive Information

68. 未加密的服务器socket

Unencrypted Server Socket
漏洞特征:UNENCRYPTED_SERVER_SOCKET
如果网络通信不加密的话,那么传输的数据就会被攻击者拦截并读取里面的内容。
有漏洞的代码:
明文socket(透明传输)

ServerSocket soc = new ServerSocket(1234);

解决方案:
ssl socket(加密传输)

ServerSocket soc = SSLServerSocketFactory.getDefault().createServerSocket(1234);

使用sslsocket,你需要确保你使用的SSLSocketFactory能验证所提供的证书是否有效,这样你就不会遭受中间人攻击。请阅读owasp中关于传输层协议的那一章,以了解更多正确的做法。
引用:
OWASP: Top 10 2010-A9-Insufficient Transport Layer Protection
OWASP: Top 10 2013-A6-Sensitive Data Exposure
OWASP: Transport Layer Protection Cheat Sheet
WASC-04: Insufficient Transport Layer Protection
CWE-319: Cleartext Transmission of Sensitive Information

69. DES是不安全的

DES is insecure
漏洞特征:DES_USAGE
DES被认为是现代加密系统中比较强壮的加密方式,当前,NIST建议使用AES block ciphers来替代DES
有漏洞的代码:

Cipher c = Cipher.getInstance("DES/ECB/PKCS5Padding");
c.init(Cipher.ENCRYPT_MODE, k, iv);
byte[] cipherText = c.doFinal(plainText);

解决方案示例代码:

Cipher c = Cipher.getInstance("AES/GCM/NoPadding");
c.init(Cipher.ENCRYPT_MODE, k, iv);
byte[] cipherText = c.doFinal(plainText);

引用:
NIST Withdraws Outdated Data Encryption Standard
CWE-326: Inadequate Encryption Strength

70. DESede是不安全的

DESede is insecure
漏洞特征:TDES_USAGE
三次DES(也被称为3DES 或者 DESede)被认为是现代加密系统中比较强壮的加密方式,当前,NIST建议使用AES block ciphers来替代DES
有漏洞的代码:

Cipher c = Cipher.getInstance("DESede/ECB/PKCS5Padding");
c.init(Cipher.ENCRYPT_MODE, k, iv);
byte[] cipherText = c.doFinal(plainText);

解决方案示例代码:

Cipher c = Cipher.getInstance("AES/GCM/NoPadding");
c.init(Cipher.ENCRYPT_MODE, k, iv);
byte[] cipherText = c.doFinal(plainText);

引用:
NIST Withdraws Outdated Data Encryption Standard
CWE-326: Inadequate Encryption Strength

71. 不用padding的RSA是不安全的

RSA with no padding is insecure
漏洞特征:RSA_NO_PADDING
软件使用RSA加密算法但是没有使用非对称加密填充(OAEP), 这种加密可能会是比较脆弱的
有漏洞的代码:

Cipher.getInstance("RSA/NONE/NoPadding")

解决方案:
应该用下面的代码来替换

Cipher.getInstance("RSA/ECB/OAEPWithMD5AndMGF1Padding")

引用:
CWE-780: Use of RSA Algorithm without OAEP
Root Labs: Why RSA encryption padding is critical

72. 硬编码密码

Hard Coded Password
漏洞特征:HARD_CODE_PASSWORD
密码不应该留在源码里面,在企业里面源码会被广泛的分享,有些部分甚至会被开源出来,为了更安全的管理,密码和密钥应该被单独的存储在配置文件中,或者keystores中(硬编码密钥会有一个单独的特征:Hard Coded Key pattern)
有漏洞的代码

private String SECRET_PASSWORD = "letMeIn!";

Properties props = new Properties();
props.put(Context.SECURITY_CREDENTIALS, "p@ssw0rd");

引用:
CWE-259: Use of Hard-coded Password

73. 硬编码密钥

Hard Coded Key
漏洞特征: HARD_CODE_KEY
加密密钥不应该留在源码里面,在企业里面源码会被广泛的分享,有些部分甚至会被开源出来,为了更安全的管理,密码和密钥应该被单独的存储在配置文件中,或者keystores中(硬编码密码会有一个单独的特征:Hard Coded Password pattern)
有漏洞的代码

byte[] key = {1, 2, 3, 4, 5, 6, 7, 8};
SecretKeySpec spec = new SecretKeySpec(key, "AES");
Cipher aes = Cipher.getInstance("AES");
aes.init(Cipher.ENCRYPT_MODE, spec);
return aesCipher.doFinal(secretData);

引用:
CWE-321: Use of Hard-coded Cryptographic Key

74. 不安全的hash比较

Unsafe hash equals
漏洞特征:UNSAFE_HASH_EQUALS
攻击者可能会通过密钥的比较时间来发现密钥的hash值,当Arrays.equals() 或者 String.equals()被调用的时候,如果有一些字节被匹配到的话,它们会推出的更早一些
有漏洞的代码:

String actualHash = ...

if(userInput.equals(actualHash)) {
    ...
}

解决方案:

String actualHash = ...

if(MessageDigest.isEqual(userInput.getBytes(),actualHash.getBytes())) {
    ...
}

引用:
CWE-203: Information Exposure Through DiscrepancyKey

75. 来自Struts Form的输入没有被验证

Struts Form without input validation
漏洞特征: STRUTS_FORM_VALIDATION
来自Form的输入应该被简单的验证一下,预防性的验证能够抵御更进一步的攻击。
validate这个函数引入了验证的实现

public class RegistrationForm extends ValidatorForm {

    private String name;
    private String email;

    [...]

    public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) {
        //Validation code for name and email parameters passed in via the HttpRequest goes here
    }
}

引用:
CWE-20: Improper Input Validation
CWE-106: Struts: Plug-in Framework not in Use

76. XSSRequestWrapper的xss防护是脆弱的

XSSRequestWrapper is a weak XSS protection
漏洞特征:XSS_REQUEST_WRAPPER
在各种公开的博客里面,博主通过实现HttpServletRequestWrapper调用XSSRequestWrapper
这个过滤函数的脆弱点在于以下的几个方面:
• 它仅仅覆盖参数,而没有覆盖到http头或者侧信道输入 。
• 简单替换的方式很容易会被绕过(见下面的例子)
• 黑名单的方式太脆弱(不如用白名单的方式来验证好的输入)
绕过示例:
scrivbscript:ptalert(1)</scrivbscript:pt>
上面的输入会被转换为:"
为了更强的保护,请在view (template, jsp, …) 中选择自动编码字符串的解决方案,解决方案里面的规则被定义在OWASP XSS Prevention 备忘录中。
引用:
WASC-8: Cross Site Scripting
OWASP: XSS Prevention Cheat Sheet
OWASP: Top 10 2013-A3: Cross-Site Scripting (XSS)
CWE-79: Improper Neutralization of Input During Web Page Generation (‘Cross-site Scripting’)

77. Blowfish 使用过短的密钥

Blowfish usage with short key
漏洞特征:BLOWFISH_KEY_SIZE
Blowfish的密钥支持32 bits 到 448 bits的长度。如果密钥太短,会导致加密内容被黑客暴力破解。如果使用Blowfish的话,密钥至少应该选择128 bits 。
如果算法被改变,那么应该AES分组密码
有漏洞的代码:

KeyGenerator keyGen = KeyGenerator.getInstance("Blowfish");
keyGen.init(64);

解决方案:

KeyGenerator keyGen = KeyGenerator.getInstance("Blowfish");
keyGen.init(128);

引用:
Blowfish (cipher)
CWE-326: Inadequate Encryption Strength

78. RSA使用了过短密钥

RSA usage with short key
漏洞特征: RSA_KEY_SIZE
NIST建议RSA算法应该使用2048bits的密钥或者更长的密钥
“电子签名验证 | RSA: 1024 ≤ len(n) < 2048 | 传统使用”
“电子签名验证 | RSA: len(n) ≥ 2048 | 可接受”
• NIST: 数据传输建议使用的加密方式和密钥长度 p.7

漏洞代码:

KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(512);

解决方案:
密钥的生成至少应该像下面这样使用2048位

KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(2048);

引用:
NIST: Latest publication on key management
NIST: Recommendation for Transitioning the Use of Cryptographic Algorithms and Key Lengths p.7
RSA Laboratories: 3.1.5 How large a key should be used in the RSA cryptosystem?
Wikipedia: Asymmetric algorithm key lengths
CWE-326: Inadequate Encryption Strength
Keylength.com (BlueKrypt): Aggregate key length recommendations.

79. 未验证的重定向

Unvalidated Redirect
漏洞特征:UNVALIDATED_REDIRECT
未验证重定向漏洞是因为应用跳转到用户输入的指定目标url,这个输入的参数没有被充分的验证。这个漏洞可能会被用来钓鱼
假设的场景:

  1. 用户被欺骗点了恶意链接:http://website.com/login?redirect=http://evil.vvebsite.com/fake/login

  2. 用户被重定向到了一个虚假的登录页面,这样页面看起来就像真的一样(http://evil.vvebsite.com/fake/login)

  3. 用户输入了他的凭据

  4. 恶意网站偷走了用户的凭据,并且跳转回了原来的网站
    这个攻击貌似是合理的,因为大多数用户在被重定向之后不会再次检查url。而且跳转到授权页面也是很普遍的现象。
    漏洞代码:

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    […]
    resp.sendRedirect(req.getParameter(“redirectUrl”));
    […]
    }

解决方案/对策
• 不要从用户的输入中接受重定向的目的url
• 接受一个目的地址的key,这个key可以查询到一个合法的目的地址。
• 仅接受相对路径
• urls白名单(如果可行的话)
• 验证url开始的部分是否在白名单里面
引用:
WASC-38: URL Redirector Abuse
OWASP: Top 10 2013-A10: Unvalidated Redirects and Forwards
OWASP: Unvalidated Redirects and Forwards Cheat Sheet
CWE-601: URL Redirection to Untrusted Site (‘Open Redirect’)

80. 未验证的重定向(Play Framework)

Unvalidated Redirect (Play Framework)
漏洞特征:PLAY_UNVALIDATED_REDIRECT
未验证重定向漏洞是因为应用跳转到用户输入的指定目标url,这个输入的参数没有被充分的验证。这个漏洞可能会被用来钓鱼
假设的场景:

  1. 用户被欺骗点了恶意链接:http://website.com/login?redirect=http://evil.vvebsite.com/fake/login

  2. 用户被重定向到了一个虚假的登录页面,这样页面看起来就像真的一样(http://evil.vvebsite.com/fake/login)

  3. 用户输入了他的凭据

  4. 恶意网站偷走了用户的凭据,并且跳转回了原来的网站
    这个攻击貌似是合理的,因为大多数用户在被重定向之后不会再次检查url。而且跳转到授权页面也是很普遍的现象。
    漏洞代码:

    def login(redirectUrl:String) = Action {
    […]
    Redirect(url)
    }

解决方案/对策
• 不要从用户的输入中接受重定向的目的url
• 接受一个目的地址的key,这个key可以查询到一个合法的目的地址。
• 仅接受相对路径
• urls白名单(如果可行的话)
• 验证url开始的部分是否在白名单里面
引用:
WASC-38: URL Redirector Abuse
OWASP: Top 10 2013-A10: Unvalidated Redirects and Forwards
OWASP: Unvalidated Redirects and Forwards Cheat Sheet
CWE-601: URL Redirection to Untrusted Site (‘Open Redirect’)

81. Spring中未验证的重定向

Spring Unvalidated Redirect
漏洞特征:SPRING_UNVALIDATED_REDIRECT
未验证重定向漏洞是因为应用跳转到用户输入的指定目标url,这个输入的参数没有被充分的验证。这个漏洞可能会被用来钓鱼
假设的场景:

  1. 用户被欺骗点了恶意链接:http://website.com/login?redirect=http://evil.vvebsite.com/fake/login

  2. 用户被重定向到了一个虚假的登录页面,这样页面看起来就像真的一样(http://evil.vvebsite.com/fake/login)

  3. 用户输入了他的凭据

  4. 恶意网站偷走了用户的凭据,并且跳转回了原来的网站
    这个攻击貌似是合理的,因为大多数用户在被重定向之后不会再次检查url。而且跳转到授权页面也是很普遍的现象。
    漏洞代码:

    @RequestMapping("/redirect")
    public String redirect(@RequestParam(“url”) String url) {
    […]
    return “redirect:” + url;
    }

解决方案/对策
• 不要从用户的输入中接受重定向的目的url
• 接受一个目的地址的key,这个key可以查询到一个合法的目的地址。
• 仅接受相对路径
• urls白名单(如果可行的话)
• 验证url开始的部分是否在白名单里面
引用:
WASC-38: URL Redirector Abuse
OWASP: Top 10 2013-A10: Unvalidated Redirects and Forwards
OWASP: Unvalidated Redirects and Forwards Cheat Sheet
CWE-601: URL Redirection to Untrusted Site (‘Open Redirect’)

82. jsp动态包含

Dynamic JSP inclusion
漏洞特征:JSP_INCLUDE
jsp允许动态包含文件。这可能允许攻击者控制jsp的文件包含。如果出现这样的漏洞的话,攻击者就会包含一个他能控制到的文件。通过直接包含文件,攻击者就能执行任意代码。
有漏洞的代码:

<jsp:include page="${param.secret_param}" />

解决方案:

<c:if test="${param.secret_param == 'page1'}">
    <jsp:include page="page1.jsp" />
</c:if>

引用:
InfosecInstitute: File Inclusion Attacks
WASC-05: Remote File Inclusion

83. Spring 表达式中的动态变量

Dynamic variable in Spring expression
漏洞特征:JSP_SPRING_EVAL
Spring使用动态值构建。应该严格检验源数据,以避免未过滤的数据进入到危险函数中。
有漏洞的代码

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>

<spring:eval expression="${param.lang}" var="lang" />

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>

<spring:eval expression="'${param.lang}'=='fr'" var="languageIsFrench" />

解决方案:

<c:set var="lang" value="${param.lang}"/>
<c:set var="languageIsFrench" value="${param.lang == 'fr'}"/>

引用:
CWE-94: Improper Control of Generation of Code (‘Code Injection’)
CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (‘Eval Injection’)

84. xml字符转义被禁用

Escaping of special XML characters is disabled
漏洞特征:JSP_JSTL_OUT
可能会有潜在的xss漏洞。这可能会在客户端执行未期望的JavaScript。(见引用)
有漏洞的代码:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<c:out value="${param.test_param}" escapeXml="false"/>

解决方案:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<c:out value="${param.test_param}"/>

引用:
WASC-8: Cross Site Scripting
OWASP: XSS Prevention Cheat Sheet
OWASP: Top 10 2013-A3: Cross-Site Scripting (XSS)
CWE-79: Improper Neutralization of Input During Web Page Generation (‘Cross-site Scripting’)
JSTL Javadoc: Out tag

85. jsp中潜在的xss

Potential XSS in JSP
漏洞特征:XSS_JSP_PRINT
可能会有潜在的xss漏洞。这可能会在客户端执行未期望的JavaScript。(见引用)
有漏洞的代码:

<%
String taintedInput = (String) request.getAttribute("input");
%>
[...]
<%= taintedInput %>

解决方案:

<%
String taintedInput = (String) request.getAttribute("input");
%>
[...]
<%= Encode.forHtml(taintedInput) %>

抵御xss最好的方式是像上面在输出中编码特殊的字符。有4种环境类型要考虑:HTML, JavaScript, CSS (styles), 和URLs.请遵守OWASP XSS Prevention备忘录中定义的xss保护规则,里面会介绍一些防御的细节。
引用:
WASC-8: Cross Site Scripting
OWASP: XSS Prevention Cheat Sheet
OWASP: Top 10 2013-A3: Cross-Site Scripting (XSS)
CWE-79: Improper Neutralization of Input During Web Page Generation (‘Cross-site Scripting’)
OWASP Java Encoder

86. Servlet中潜在的xss

Potential XSS in Servlet
漏洞特征:XSS_SERVLET
可能会有潜在的xss漏洞。这可能会在客户端执行未期望的JavaScript。(见引用)
有漏洞的代码:

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    String input1 = req.getParameter("input1");
    [...]
    resp.getWriter().write(input1);
}

解决方案:

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    String input1 = req.getParameter("input1");
    [...]
    resp.getWriter().write(Encode.forHtml(input1));
}

抵御xss最好的方式是像上面在输出中编码特殊的字符。有4种环境类型要考虑:HTML, JavaScript, CSS (styles), 和URLs.请遵守OWASP XSS Prevention备忘录中定义的xss保护规则,里面会介绍一些防御的细节。
注意Servlet中的xss规则看着都很类似,但是要用不同的规则寻找‘XSS:Servlet反射型xss’和‘xss:在Servlet错误页面中反射型xss’
引用:
WASC-8: Cross Site Scripting
OWASP: XSS Prevention Cheat Sheet
OWASP: Top 10 2013-A3: Cross-Site Scripting (XSS)
CWE-79: Improper Neutralization of Input During Web Page Generation (‘Cross-site Scripting’)
OWASP Java Encoder

87. XMLDecoder的使用

XMLDecoder usage
漏洞规则:XML_DECODER
不应该用XMLDecoder解析不受信任的数据。反序列化用户输入数据会导致代码执行。这是因为XMLDecoder 支持任意的方法调用。这个功能旨在调用setter方法,但是实际上,这个功能什么方法都能调用。
恶意的xml

<?xml version="1.0" encoding="UTF-8" ?>
<java version="1.4.0" class="java.beans.XMLDecoder">
  <object class="java.io.PrintWriter">
    <string>/tmp/Hacked.txt</string>
    <void method="println">
      <string>Hello World!</string>
    </void>
    <void method="close"/>
  </object>
</java>

上面这个xml代码可能会在服务器中创建一个内容为"Hello World!".的文件。
有漏洞的代码:

XMLDecoder d = new XMLDecoder(in);
try {
    Object result = d.readObject();
}
[...]

解决方案:
解决方案是避免使用XMLDecoder去解析不受信任的用户输入数据
引用:
Dinis Cruz Blog: Using XMLDecoder to execute server-side Java Code on an Restlet application
RedHat blog : Java deserialization flaws: Part 2, XML deserialization
CWE-20: Improper Input Validation

88. 固定IV

Static IV
漏洞规则:STATIC_IV
每一条消息都应该为它初始化生成一个新的加密向量
有漏洞的代码:

private static byte[] IV = new byte[16] {(byte)0,(byte)1,(byte)2,[...]};

public void encrypt(String message) throws Exception {

    IvParameterSpec ivSpec = new IvParameterSpec(IV);
[...]

解决方案:

public void encrypt(String message) throws Exception {

    byte[] iv = new byte[16];
    new SecureRandom().nextBytes(iv);

    IvParameterSpec ivSpec = new IvParameterSpec(iv);
[...]

引用:
Wikipedia: Initialization vector
CWE-329: Not Using a Random IV with CBC Mode
Encryption - CBC Mode IV: Secret or Not?

89. ECB模式是不安全的

ECB mode is insecure
漏洞规则: ECB_MODE
提供了最好机密性的授权加密模式应该替换电码本模式(Electronic Codebook Book (ECB)),因为ecb没有提供很好的机密性。尤其,在ecb模式下,输入相同的数据,每一次的输出也是相同的。所以,如果用户发送一个密码,它的加密值每次都是相同的。这允许攻击者可以去拦截并且也可也重放这些数据
为了修复这个。一些像Galois/Counter Mode (GCM)也应该被替换
有漏洞的代码

Cipher c = Cipher.getInstance("AES/ECB/NoPadding");
c.init(Cipher.ENCRYPT_MODE, k, iv);
byte[] cipherText = c.doFinal(plainText);

解决方案:

Cipher c = Cipher.getInstance("AES/GCM/NoPadding");
c.init(Cipher.ENCRYPT_MODE, k, iv);
byte[] cipherText = c.doFinal(plainText);

引用:
Wikipedia: Authenticated encryption
NIST: Authenticated Encryption Modes
Wikipedia: Block cipher modes of operation
NIST: Recommendation for Block Cipher Modes of Operation

90. 加密容易受到Padding Oracle的影响

Cipher is susceptible to Padding Oracle
漏洞特征:PADDING_ORACLE
具有PKCS5Padding的CBC特定模式容易受到padding oracle攻击。如果系统暴露了的明文数据与有效padding或无效padding之间的差异。那么攻击者就可能会解密数据。有效padding和无效padding的差别通常可以通过每一次返回的报错信息来揭露。
有漏洞的代码:

Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
c.init(Cipher.ENCRYPT_MODE, k, iv);
byte[] cipherText = c.doFinal(plainText);

解决方案:

Cipher c = Cipher.getInstance("AES/GCM/NoPadding");
c.init(Cipher.ENCRYPT_MODE, k, iv);
byte[] cipherText = c.doFinal(plainText);

引用:
Padding Oracles for the masses (by Matias Soler)
Wikipedia: Authenticated encryption
NIST: Authenticated Encryption Modes
CAPEC: Padding Oracle Crypto Attack
CWE-696: Incorrect Behavior Order

91. 密码没有完整性

Cipher with no integrity
漏洞特征:CIPHER_INTEGRITY
产生的密文容易被对手改变。这就意味着,加密提供者没法发现数据是否遭到篡改。如果加密数据被攻击者控制,那么它可能会被偷偷改掉。
解决方案通常是加密数据通常包含基本的身份验证hash(HMAC) 去签名数据。把HMAC方法和现有的加密方式结合容易出错。尤其,推荐你要首先去验证HMAC,并且如果数据没有被篡改,你才能执行所有的解密操作。
如果没有提供HMAC,下面的模式都是有漏洞的:
• CBC
• OFB
• CTR
• ECB
下面的片段是一些有漏洞的代码:
有漏洞的代码
aes的cbc模式

Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
c.init(Cipher.ENCRYPT_MODE, k, iv);
byte[] cipherText = c.doFinal(plainText);

三次DES的ECB模式

Cipher c = Cipher.getInstance("DESede/ECB/PKCS5Padding");
c.init(Cipher.ENCRYPT_MODE, k, iv);
byte[] cipherText = c.doFinal(plainText);

解决方案:

Cipher c = Cipher.getInstance("AES/GCM/NoPadding");
c.init(Cipher.ENCRYPT_MODE, k, iv);
byte[] cipherText = c.doFinal(plainText);

在上面这个例子中,GCM模式把HMAC引入到加密数据的结果之中,提供了结果的完整性
引用:
Wikipedia: Authenticated encryption
NIST: Authenticated Encryption Modes
Moxie Marlinspike’s blog: The Cryptographic Doom Principle
CWE-353: Missing Support for Integrity Check

92. 使用ESAPI加密

Use of ESAPI Encryptor
漏洞规则:ESAPI_ENCRYPTOR
ESAPI的加密组件在历史上有一些小的漏洞。这里有一个能够快速验证的列表,以保证授权的加密是以期望的方式运行的。

  1. 库的版本
    这个问题在2.1.0这个版本被修正。在2.0.1版本以下有漏洞可以绕过MAC(CVE-2013-5679)
    对于Maven使用者,使用下面的命令可以查看插件的版本。有效的ESAPI将会被输出
    $ mvn versions:display-dependency-updates
    输出:

    […]
    [INFO] The following dependencies in Dependencies have newer versions:
    [INFO] org.slf4j:slf4j-api … 1.6.4 -> 1.7.7
    [INFO] org.owasp.esapi:esapi … 2.0.1 -> 2.1.0
    […]

或者可以直接查看配置

<dependency>
    <groupId>org.owasp.esapi</groupId>
    <artifactId>esapi</artifactId>
    <version>2.1.0</version>
</dependency>

对于Ant使用者,应该使用 esapi-2.1.0.jar 这个jar。
2.配置
在2.1.0这个版本中,在密文定义中,密钥的改变会导致漏洞(CVE-2013-5960)。需要使用一些预防措施。
如果存在以下任何元素,那么ESAPI的加密算法就是有问题的
不安全的配置:

Encryptor.CipherText.useMAC=false

Encryptor.EncryptionAlgorithm=AES
Encryptor.CipherTransformation=AES/CBC/PKCS5Padding

Encryptor.cipher_modes.additional_allowed=CBC

安全的配置:

#Needed
Encryptor.CipherText.useMAC=true

#Needed to have a solid auth. encryption
Encryptor.EncryptionAlgorithm=AES
Encryptor.CipherTransformation=AES/GCM/NoPadding

#CBC mode should be removed to avoid padding oracle
Encryptor.cipher_modes.additional_allowed=

引用:
ESAPI Security bulletin 1 (CVE-2013-5679)
Vulnerability Summary for CVE-2013-5679
Synactiv: Bypassing HMAC validation in OWASP ESAPI symmetric encryption
CWE-310: Cryptographic Issues
ESAPI-dev mailing list: Status of CVE-2013-5960

93. 外部文件访问(Android)

External file access (Android)
漏洞特征:ANDROID_EXTERNAL_FILE_ACCESS
应用经常往外部存储上写数据(可能是SD卡),这个操作可能会有多个安全问题。首先应用可以可以通过READ_EXTERNAL_STORAGE 获取SD卡上存储的文件。而且如果数据中包含用户的敏感信息的话,那么需要把这些数据加密。
有漏洞的代码:

file file = new File(getExternalFilesDir(TARGET_TYPE), filename);
fos = new FileOutputStream(file);
fos.write(confidentialData.getBytes());
fos.flush();

更好的措施:

fos = openFileOutput(filename, Context.MODE_PRIVATE);
fos.write(string.getBytes());

引用:
Android Official Doc: Security Tips
CERT: DRD00-J: Do not store sensitive information on external storage
Android Official Doc: Using the External Storage
OWASP Mobile Top 10 2014-M2: Insecure Data Storage
CWE-312: Cleartext Storage of Sensitive Information

94. Broadcast漏洞(Android)

Broadcast (Android)
漏洞规则:ANDROID_BROADCAST
所有应用通过申请适当权限就可以监听Broadcast的意图,所以尽量不要通过Broadcast传输敏感数据。
有漏洞的代码:

Intent i = new Intent();
i.setAction("com.insecure.action.UserConnected");
i.putExtra("username", user);
i.putExtra("email", email);
i.putExtra("session", newSessionId);

this.sendBroadcast(v1);

解决方案(如果有可能的话):

Intent i = new Intent();
i.setAction("com.secure.action.UserConnected");

sendBroadcast(v1);

配置(接收者)

<manifest ...>

    <!-- Permission declaration -->
    <permission android:name="my.app.PERMISSION" />

    <receiver
        android:name="my.app.BroadcastReceiver"
        android:permission="my.app.PERMISSION"> <!-- Permission enforcement -->
        <intent-filter>
            <action android:name="com.secure.action.UserConnected" />
        </intent-filter>
    </receiver>

    ...
</manifest>

配置(发送者)

<manifest>
    <!-- We declare we own the permission to send broadcast to the above receiver -->
    <uses-permission android:name="my.app.PERMISSION"/>

    <!-- With the following configuration, both the sender and the receiver apps need to be signed by the same developer certificate. -->
    <permission android:name="my.app.PERMISSION" android:protectionLevel="signature"/>
</manifest>

引用:
CERT: DRD03-J. Do not broadcast sensitive information using an implicit intent
Android Official Doc: BroadcastReceiver (Security)
Android Official Doc: Receiver configuration (see android:permission)
[1] StackOverflow: How to set permissions in broadcast sender and receiver in android
CWE-925: Improper Verification of Intent by Broadcast Receiver
CWE-927: Use of Implicit Intent for Sensitive Communication

95. 任意文件写 (Android)

World writable file (Android)
漏洞特征:ANDROID_WORLD_WRITABLE
创建文件使用MODE_WORLD_READABLE模式,可以让文件写入环境中的任意位置。一些文件文件被改写的话,可能会发生一些不希望发生的事情。
有漏洞的代码:

fos = openFileOutput(filename, MODE_WORLD_READABLE);
fos.write(userInfo.getBytes());

解决方案(使用MODE_PRIVATE):

fos = openFileOutput(filename, MODE_PRIVATE);

解决方案(使用本地SQLite数据库)
使用本地SQLite数据库可能是存储结构数据最好的解决方案了。要确定数据库文件不会被创建到外部存储中。见下面的开发文档引用
引用:
CERT: DRD11-J. Ensure that sensitive data is kept secure
Android Official Doc: Security Tips
Android Official Doc: Context.MODE_PRIVATE
vogella.com: Android SQLite database and content provider - Tutorial
OWASP Mobile Top 10 2014-M2: Insecure Data Storage
CWE-312: Cleartext Storage of Sensitive Information

96. 已激活地理位置的WebView(Android)

WebView with geolocation activated (Android)
漏洞特征:ANDROID_GEOLOCATION
建议去询问用户是否能获取他们的位置信息
漏洞代码:

webView.setWebChromeClient(new WebChromeClient() {
    @Override
    public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
        callback.invoke(origin, true, false);
    }
});

建议代码:
限制使用地理位置的例子,并且要得到用户的确认

webView.setWebChromeClient(new WebChromeClient() {
    @Override
    public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
        callback.invoke(origin, true, false);

        //Ask the user for confirmation
    }
});

引用:
CERT: DRD15-J. Consider privacy concerns when using Geolocation API
Wikipedia: W3C Geolocation API
W3C: Geolocation Specification

97. 允许JavaScript脚本运行的webview (Android)

WebView with JavaScript enabled (Android)
漏洞特征:ANDROID_WEB_VIEW_JAVASCRIPT
WebView如果允许允许JavaScript脚本的话,就意味着它会受到xss的影响。应该检查页面的渲染,以避免潜在的反射型xss,存储型xss,dom型xss。

WebView myWebView = (WebView) findViewById(R.id.webView);
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);

有漏洞的代码:
允许JavaScript运行是一个坏的习惯。这就意味着后端代码需要被审计,以避免xss。xss也会使用dom xss的形式引入到客户端。

function updateDescription(newDescription) {
    $("#userDescription").html("<p>"+newDescription+"</p>");
}

引用:
Issue: Using setJavaScriptEnabled can introduce XSS vulnerabilities
Android Official Doc: WebView
WASC-8: Cross Site Scripting
OWASP: XSS Prevention Cheat Sheet
OWASP: Top 10 2013-A3: Cross-Site Scripting (XSS)
CWE-79: Improper Neutralization of Input During Web Page Generation (‘Cross-site Scripting’)

98. 带有JavaScript接口的WebView (Android)

WebView with JavaScript interface (Android)
漏洞特征:ANDROID_WEB_VIEW_JAVASCRIPT_INTERFACE
使用JavaScript接口可能会将WebView暴露给有危害的api。如果在WebView中触发xss的话,恶意的JavaScript代码会钓鱼一些敏感的类。
有漏洞的代码:

WebView myWebView = (WebView) findViewById(R.id.webView);

myWebView.addJavascriptInterface(new FileWriteUtil(this), "fileWriteUtil");

WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);

[...]
class FileWriteUtil {
    Context mContext;

    FileOpenUtil(Context c) {
        mContext = c;
    }

    public void writeToFile(String data, String filename, String tag) {
        [...]
    }
}

引用:
Android Official Doc: WebView.addJavascriptInterface()
CWE-749: Exposed Dangerous Method or Function

99. 没有用secure标志的cookie

Cookie without the secure flag
漏洞特征:INSECURE_COOKIE
一个新的cookie的创建应该设置Secure标志。Secure标志命令浏览器确保cookie不会通过不安全的链路发送(http://)
有漏洞的代码:

Cookie cookie = new Cookie("userName",userName);
response.addCookie(cookie);  

解决方案(特殊的设置):

Cookie cookie = new Cookie("userName",userName);
cookie.setSecure(true); // Secure flag
cookie.setHttpOnly(true);

解决方案(Servlet 3.0 配置)

<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="3.0">
[...]
<session-config>
 <cookie-config>
  <http-only>true</http-only>
  <secure>true</secure>
 </cookie-config>
</session-config>
</web-app>

引用:
CWE-614: Sensitive Cookie in HTTPS Session Without ‘Secure’ Attribute
CWE-315: Cleartext Storage of Sensitive Information in a Cookie
CWE-311: Missing Encryption of Sensitive Data
OWASP: Secure Flag
Rapid7: Missing Secure Flag From SSL Cookie

100. 没有用HttpOnly标志的cookie

Cookie without the HttpOnly flag
漏洞特征:HTTPONLY_COOKIE
一个新的cookie的创建应该设置Secure标志。Secure标志命令浏览器确保cookie不会被恶意脚本读取。当用户是“跨站脚本攻击”的目标的时候,攻击者会获得用户的session id,从而能够接管用户的账户。
有漏洞的代码:

Cookie cookie = new Cookie("email",userName);
response.addCookie(cookie);

解决方案(特殊的设置):

Cookie cookie = new Cookie("email",userName);
cookie.setSecure(true);
cookie.setHttpOnly(true); //HttpOnly flag

解决方案(Servlet 3.0 配置)

<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="3.0">
[...]
<session-config>
 <cookie-config>
  <http-only>true</http-only>
  <secure>true</secure>
 </cookie-config>
</session-config>
</web-app>

引用:
Coding Horror blog: Protecting Your Cookies: HttpOnly
OWASP: HttpOnly
Rapid7: Missing HttpOnly Flag From Cookie

101. 使用反序列化对象

Object deserialization is used
漏洞特征:OBJECT_DESERIALIZATION
反序列化不受信任的数据可能会导致远程命令执行,如果有可用的执行链,那么就会触发恶意操作。库的开发者在逐渐提高防御策略,以避免潜在的恶意利用。但是还是有一些已知的类可以触发dos攻击。
反序列化是一个敏感的操作,因为历史上曾经有很多比较有名的漏洞都是出自它。web应用是很脆弱的,因为很快java虚拟机里面将会爆发出一波新的漏洞。
有漏洞的代码:

public UserData deserializeObject(InputStream receivedFile) throws IOException, ClassNotFoundException {

    try (ObjectInputStream in = new ObjectInputStream(receivedFile)) {
        return (UserData) in.readObject();
    }
}

解决方案:
避免反序列从远程用户输入的数据
引用:
CWE-502: Deserialization of Untrusted Data
Deserialization of untrusted data
Serialization and Deserialization
A tool for generating payloads that exploit unsafe Java object deserialization
[1] Example of Denial of Service using the class java.util.HashSet
[2] OpenJDK: Deserialization issue in ObjectInputStream.readSerialData() (CVE-2015-2590)
[3] Rapid7: Sun Java Calendar Deserialization Privilege Escalation (CVE-2008-5353)

102. 不安全的Jackson发序列化配置

Unsafe Jackson deserialization configuration
漏洞特征:JACKSON_UNSAFE_DESERIALIZATION
如果Jackson databind库被用来反序列不受信任的数据的话,就会导致远程命令执行。如果有可用的执行链,那么就会触发恶意操作。
解决方案:
当通过JsonTypeInfo.Id.NAME使用多态性时,应该明确定义想要的类型和子类型。并且不要调用ObjectMapper.enableDefaultTyping(readValue包含Object 或 Serializable 或 Comparable 或 已知的反序列化类型)
有漏洞的代码:

public class Example {
    static class ABean {
        public int id;
        public Object obj;
    }

    static class AnotherBean {
        @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS) // or JsonTypeInfo.Id.MINIMAL_CLASS
        public Object obj;
    }

    public void example(String json) throws JsonMappingException {
         ObjectMapper mapper = new ObjectMapper();
         mapper.enableDefaultTyping();
         mapper.readValue(json, ABean.class);
    }

    public void exampleTwo(String json) throws JsonMappingException {
         ObjectMapper mapper = new ObjectMapper();
         mapper.readValue(json, AnotherBean.class);
    }

}

引用:
Jackson Deserializer security vulnerability
Java Unmarshaller Security - Turning your data into code execution

103. 在反序列化漏洞中被利用的类

This class could be used as deserialization gadget
漏洞特征:DESERIALIZATION_GADGET
反序列化利用链是一些可以被攻击者利用的类,这些类通常存在于远程api中。这些类也会被添自定义行为,目的是用readObject方法去反序列化 (Serializable)或者调用来自序列化对象中的方法(InvocationHandler).
这个检查工具主要用于研究人员。真实的场景是反序列化会被用于远程操作。为了减少恶意代码的利用,必须要强制移除利用链中所使用的类。
引用:
CWE-502: Deserialization of Untrusted Data
Deserialization of untrusted data
Serialization and Deserialization
A tool for generating payloads that exploit unsafe Java object deserialization
[1] Example of Denial of Service using the class java.util.HashSet
[2] OpenJDK: Deserialization issue in ObjectInputStream.readSerialData() (CVE-2015-2590)
[3] Rapid7: Sun Java Calendar Deserialization Privilege Escalation (CVE-2008-5353)

104. 违反信任边界

Trust Boundary Violation
漏洞特征:TRUST_BOUNDARY_VIOLATION
信任边界被认为是通过程序画的一根线。在线的一边,数据是不可信的。在线的另一边,数据是被可信任的。身份效验的目的是为了数据能够安全的通过信任边界-从不信任的一遍到信任的一边。当程序模糊了信任数据和不信任数据的边界时就会导致违反信任边界的事情发生。把信任数据和不信任数据组合成相同的数据结构时,就会让程序员更容易在边界上的犯错。
有漏洞的代码:

public void doSomething(HttpServletRequest req, String activateProperty) {
    //..

    req.getSession().setAttribute(activateProperty,"true");

}


public void loginEvent(HttpServletRequest req, String userSubmitted) {
    //..

    req.getSession().setAttribute("user",userSubmitted);
}

解决方案:
解决方案是在设置新的session属性前要添加验证。如果有可能,最好数据是来自安全的地方而不是用户提供的输入数据
引用:
[1] CWE-501: Trust Boundary Violation
OWASP : Trust Boundary Violation

105. 恶意的XSLT

A malicious XSLT could be provided
漏洞特征:JSP_XSLT
XSLT(可扩展样式表转换语言)是一种用于将XML 文档转换为其他XML 文档的语言。
xslt的样式表中可能会携带恶意的行为。所以,如果一个攻击者控制了源样式表的内容,那么它可能会触发远程代码执行
有漏洞的代码:

<x:transform xml="${xmlData}" xslt="${xsltControlledByUser}" />

解决方案:
解决方案确保源样式表来自安全的源,并且保证不会有类似于路径穿透的漏洞。
引用
[1] Wikipedia: XSLT (Extensible Stylesheet Language Transformations)
Offensive XSLT by Nicolas Gregoire
[2] From XSLT code execution to Meterpreter shells by Nicolas Gregoire
XSLT Hacking Encyclopedia by Nicolas Gregoire
Acunetix.com : The hidden dangers of XSLTProcessor - Remote XSL injection
w3.org XSL Transformations (XSLT) Version 1.0 : w3c specification
[3] WASC: Path Traversal
[4] OWASP: Path Traversal

106. 恶意的XSLT

A malicious XSLT could be provided
漏洞特征:MALICIOUS_XSLT
XSLT(可扩展样式表转换语言)是一种用于将XML 文档转换为其他XML 文档的语言。
xslt的样式表中可能会携带恶意的行为。所以,如果一个攻击者控制了源样式表的内容,那么它可能会触发远程代码执行
有漏洞的代码:

Source xslt = new StreamSource(new FileInputStream(inputUserFile)); //Dangerous source to validate

Transformer transformer = TransformerFactory.newInstance().newTransformer(xslt);

Source text = new StreamSource(new FileInputStream("/data_2_process.xml"));
transformer.transform(text, new StreamResult(...));

解决方案:
解决方案确保源样式表来自安全的源,并且保证不会有类似于路径穿透的漏洞。
引用
[1] Wikipedia: XSLT (Extensible Stylesheet Language Transformations)
Offensive XSLT by Nicolas Gregoire
[2] From XSLT code execution to Meterpreter shells by Nicolas Gregoire
XSLT Hacking Encyclopedia by Nicolas Gregoire
Acunetix.com : The hidden dangers of XSLTProcessor - Remote XSL injection
w3.org XSL Transformations (XSLT) Version 1.0 : w3c specification
[3] WASC: Path Traversal
[4] OWASP: Path Traversal

107. 潜藏在Scala Play中的信息泄露

Potential information leakage in Scala Play
漏洞特征:SCALA_SENSITIVE_DATA_EXPOSURE
应用总是无意识的泄露一些配置信息,比如内部结构或者通过各种应用问题侵犯隐私。
基于各种有效的输入数据页面会返回不同的返回数据,尤其当机密数据被当成结果被web应用展示出来的时候,就会导致信息的泄露。
敏感数据包括(不仅仅是列出来的这些):api密钥,密码,产品版本,环境配置。
有漏洞的代码:

def doGet(value:String) = Action {
  val configElement = configuration.underlying.getString(value)

  Ok("Hello "+ configElement +" !")
}

应用配置的关键部分不应该被输出到返回数据报文中,并且用户也不能操作那些被用于代码的关键配置。
引用:
OWASP: Top 10 2013-A6-Sensitive Data Exposure
[1] OWASP: Top 10 2007-Information Leakage and Improper Error Handling
[2] WASC-13: Information Leakage
CWE-200: Information Exposure

108. Scala Play服务器端请求伪造(SSRF)

Scala Play Server-Side Request Forgery (SSRF)
漏洞特征:SCALA_PLAY_SSRF
当服务器端发送一个请求,这个请求的目标地址是用户输入指定的,且这个请求没有被严格的效验时,就会发生服务器端请求伪造漏洞。这个漏洞允许攻击者用你的web服务器访问网络上的任何一台服务器或者攻击其他服务器。
有漏洞的代码:

def doGet(value:String) = Action {
    WS.url(value).get().map { response =>
        Ok(response.body)
    }
}

解决方案/对策
• 不要让用户控制请求的目的地址
• 接受一个目的地址的key,使用这个key去查找合法的目的地址
• urls地址白名单(如果可能的话)
• 用白名单校验url地址开头的部分
引用:
CWE-918: Server-Side Request Forgery (SSRF)
Understanding Server-Side Request Forgery

109. URLConnection中的服务器端请求伪造(SSRF) 和任意文件访问

URLConnection Server-Side Request Forgery (SSRF) and File Disclosure
漏洞特征:SCALA_PLAY_SSRF
当服务器端发送一个请求,这个请求的目标地址是用户输入指定的,且这个请求没有被严格的效验时,就会发生服务器端请求伪造漏洞。这个漏洞允许攻击者用你的web服务器访问网络上的任何一台服务器或者攻击其他服务器。
URLConnection能够使用file://协议获取其他的协议去访问本地的文件系统和其他的服务
有漏洞的代码:

new URL(String url).openConnection()
new URL(String url).openStream()
new URL(String url).getContent()  

解决方案/对策
• 不要让用户控制请求的目的地址
• 接受一个目的地址的key,使用这个key去查找合法的目的地址
• urls地址白名单(如果可能的话)
• 用白名单校验url地址开头的部分
引用:
CWE-918: Server-Side Request Forgery (SSRF)
Understanding Server-Side Request Forgery
CWE-73: External Control of File Name or Path
Abusing jar:// downloads

110. 在Scala Twirl模板引擎里面潜在的xss

Potential XSS in Scala Twirl template engine
漏洞规则:SCALA_XSS_TWIRL
可能会有潜在的xss漏洞。这可能会在客户端执行未期望的JavaScript。(见引用)
有漏洞的代码:

@(value: Html)

@value

解决方案:

@(value: String)

@value

抵御xss最好的方式是像上面在输出中编码特殊的字符。有4种环境类型要考虑:HTML, JavaScript, CSS (styles), 和URLs.请遵守OWASP XSS Prevention备忘录中定义的xss保护规则,里面会介绍一些重要的防御细节。
引用:
WASC-8: Cross Site Scripting
OWASP: XSS Prevention Cheat Sheet
OWASP: Top 10 2013-A3: Cross-Site Scripting (XSS)
CWE-79: Improper Neutralization of Input During Web Page Generation (‘Cross-site Scripting’)
OWASP Java Encoder

111. 在Scala MVC API引擎里面潜在的xss

Potential XSS in Scala MVC API engine
漏洞规则: SCALA_XSS_MVC_API
可能会有潜在的xss漏洞。这可能会在客户端执行未期望的JavaScript。(见引用)
有漏洞的代码:

def doGet(value:String) = Action {
    Ok("Hello " + value + " !").as("text/html")
  }

解决方案:

def doGet(value:String) = Action {
    Ok("Hello " + Encode.forHtml(value) + " !")
  }

抵御xss最好的方式是像上面在输出中编码特殊的字符。有4种环境类型要考虑:HTML, JavaScript, CSS (styles), 和URLs.请遵守OWASP XSS Prevention备忘录中定义的xss保护规则,里面会介绍一些重要的防御细节。
引用:
WASC-8: Cross Site Scripting
OWASP: XSS Prevention Cheat Sheet
OWASP: Top 10 2013-A3: Cross-Site Scripting (XSS)
CWE-79: Improper Neutralization of Input During Web Page Generation (‘Cross-site Scripting’)
OWASP Java Encoder

112. 在Velocity中潜在的模板注入

Potential template injection with Velocity
漏洞特征:TEMPLATE_INJECTION_VELOCITY
Velocity模板引擎非常强大。你可以在模板中使用条件判断,循环,外部函数调用等逻辑代码。它里面也没有一个沙箱去限制操作。一个恶意的用户如果可以控制模板,那么他就可以在服务器端运行恶意代码。Velocity模板应被视为脚本。
有漏洞的代码:

[...]

Velocity.evaluate(context, swOut, "test", userInput);

解决方案:
避免让终端用户操作Velocity中的模板。如果你需要让你的用户去操作模板,那么最好限制模板引擎的能力,就像Handlebars 或 Moustache 一样(见引用)
引用:
PortSwigger: Server-Side Template Injection
Handlebars.java

113. 在Freemarker中潜在的模板注入

Potential template injection with Freemarker
漏洞特征:TEMPLATE_INJECTION_FREEMARKER
Freemarker模板引擎非常强大。你可以在模板中使用条件判断,循环,外部函数调用等逻辑代码。它里面也没有一个沙箱去限制操作。一个恶意的用户如果可以控制模板,那么他就可以在服务器端运行恶意代码。Velocity模板应被视为脚本。
有漏洞的代码:

Template template = cfg.getTemplate(inputTemplate);
[...]
template.process(data, swOut);  

解决方案:
避免让终端用户操作Freemarker中的模板。如果你需要让你的用户去操作模板,那么最好限制模板引擎的能力,就像Handlebars 或 Moustache 一样(见引用)
引用:
PortSwigger: Server-Side Template Injection
Handlebars.java

114. 过度宽松的cors策略

Overly permissive CORS policy
漏洞规则:PERMISSIVE_CORS
在html5之前,web浏览器强制使用同源策略,目的是保证JavaScript能够访问web页面的内容,JavaScript和web页面的起源必须来自于同一个域下。如果没有同源策略,那么恶意网站就可以用JavaScript脚本加载客户端的用户凭据,从而读取用户保存在其他网站的中敏感信息,然后把数据传送给攻击者。如果http返回头定义了Access-Control-Allow-Origin字段,那么就可以让JavaScript跨域访问数据。有了这个头,web服务器就可以定义哪些其他域可以跨域来访问这个服务器。可是应该小心定义这个头,因为过度宽松的cors策略可以让恶意的应用通过这样的方式去读取受害者应用中的敏感数据,这样就会导致欺骗,数据失窃,数据修改等其他的攻击行为。
有漏洞的代码:

response.addHeader("Access-Control-Allow-Origin", "*");

解决方案:
避免在Access-Control-Allow-Origin这个头中使用*,这表示运行在其他域下的任何JavaScript都可以访问这个域下的应用数据
引用:
W3C Cross-Origin Resource Sharing
Enable Cross-Origin Resource Sharing

115. 匿名的LDAP绑定

Anonymous LDAP bind
漏洞特征:LDAP_ANONYMOUS
没有做合适的访问控制,攻击者可以滥用ldap配置,让ldap服务器执行一段包含用户控制的代码。所有依赖ctx的ldap查询都可以以不需要用户认证和访问控制的方式去执行。攻击者可以操作其中的查询语句来获取被directory服务器保护的数据。
有漏洞的代码:

...
env.put(Context.SECURITY_AUTHENTICATION, "none");
DirContext ctx = new InitialDirContext(env);
...

解决方案:
考虑ldap中其他的用户认证模式并且确保有合适的访问控制
引用:
Ldap Authentication Mechanisms

116. Ldap 入口投毒

LDAP Entry Poisoning
漏洞特征: LDAP_ENTRY_POISONING
JNDI api支持在ldap目录上绑定序列化对象。如果提供确定的属性,反序列化对象将会被用于应用数据的查询(详细信息见Black Hat USA 2016 白皮书)。反序列化对象是一个有风险的操作,他可能会导致远程代码执行。
如果攻击者获得ldap基本查询的入口点,那么这个漏洞就可能会被利用。通过添加一个属性给已存在的ldap入口或者通过配置应用,就可以恶意的使用ldap服务器了。
有漏洞的代码:

DirContext ctx = new InitialDirContext();
//[...]

ctx.search(query, filter,
        new SearchControls(scope, countLimit, timeLimit, attributes,
            true, //Enable object deserialization if bound in directory
            deref));

解决方案:

DirContext ctx = new InitialDirContext();
//[...]

ctx.search(query, filter,
        new SearchControls(scope, countLimit, timeLimit, attributes,
            false, //Disable
            deref));

引用:
Black Hat USA 2016: A Journey From JNDI/LDAP Manipulation to Remote Code Execution Dream Land (slides & video) by Alvaro Muñoz and Oleksandr Mirosh
HP Enterprise: Introducing JNDI Injection and LDAP Entry Poisoning by Alvaro Muñoz
TrendMicro: How The Pawn Storm Zero-Day Evaded Java’s Click-to-Play Protection by Jack Tang

117. 使用持久性的cookie

Persistent Cookie Usage
漏洞特征:COOKIE_PERSISTENT
将敏感数据存储在持久性的cookie中会危害到数据的保密性和账户的安全性
解释:
如果隐私信息被存储在持久性的cookie中,攻击者就会利用这个巨大的时间窗口来窃取数据,尤其持久性cookie会在用户的电脑中保存非常长的一段时间。持久性cookie一般是以文本的形式存储在客户端,攻击者可以同年哥哥访问受害者的机器来获取到这些信息。
持久性cookie会被经常使用,目的是为了在用户和网站互动时能够分析用户的行为。依靠持久性cookie去追踪数据,这可能已经侵犯了用户的隐私
有漏洞的代码:下面的代码可以让cookie保存一年

[...]
Cookie cookie = new Cookie("email", email);
cookie.setMaxAge(60*60*24*365);
[...]

解决方案:
• 在有必要的时候使用持久性cookie,并且要限制最大过期时间
• 不要在敏感上使用持久性cookie
引用:
Class Cookie setMaxAge documentation
CWE-539: Information Exposure Through Persistent Cookies

118. URL重写方法

URL rewriting method
漏洞规则:URL_REWRITING
该方法的实现包括确定是否需要在URL中编码session ID的逻辑。
url重写已经是非常严重的安全问题了,因为session ID 出现在url中,这就很容易被第三方获取到。在url中的session ID会以很多种的方式被暴露。
• 日志
• 浏览器历史
• 复制粘贴到邮件中或者文章中
• http的Referrer头中
有漏洞的代码:

out.println("Click <a href=" + 
                res.encodeURL(HttpUtils.getRequestURL(req).toString()) + 
                ">here</a>");

解决方案:
避免使用这些方法,如果您要编码URL字符串或表单参数,请不要将URL重写方法与URLEncoder类混淆。
引用:
[OWASP Top 10 2010-A3-Broken Authentication and Session Management](OWASP Top 10 2010-A3-Broken Authentication and Session Management)

119. 不安全的SMTP SSL链接

Insecure SMTP SSL connection
漏洞特征:INSECURE_SMTP_SSL
当进行ssl连接时,服务器会禁用身份验证。一些启用ssl连接的邮件库默认情况下不会验证服务器的证书。这就等于信任所有的证书。当试图去连接服务器的时候,应用会很乐意的接收由"hackedserver.com"签发的证书。当应用连接到黑客的邮件服务器时会有泄露用户敏感信息的风险。
有漏洞的代码:

...
Email email = new SimpleEmail();
email.setHostName("smtp.servermail.com");
email.setSmtpPort(465);
email.setAuthenticator(new DefaultAuthenticator(username, password));
email.setSSLOnConnect(true);
email.setFrom("[email protected]");
email.setSubject("TestMail");
email.setMsg("This is a test mail ... :-)");
email.addTo("[email protected]");
email.send();
...

解决方案:
请添加验证服务器证书的模块
email.setSSLCheckServerIdentity(true);
• 1
引用:
CWE-297: Improper Validation of Certificate with Host Mismatch

120. AWS查询注入

AWS Query Injection
漏洞特征:AWS_QUERY_INJECTION
如果SimpleDB数据库查询字符串中包含用户输入的话就会让攻击者查看未授权的记录。
下面这个例子就是动态的创建查询字符串并且执行SimpleDB的select()查询,这个查询中允许用户指定productCategory。攻击者可以修改查询,绕过customerID的身份验证从而查看所有消费者的记录。
有漏洞的代码:

...
String customerID = getAuthenticatedCustomerID(customerName, customerCredentials);
String productCategory = request.getParameter("productCategory");
...
AmazonSimpleDBClient sdbc = new AmazonSimpleDBClient(appAWSCredentials);
String query = "select * from invoices where productCategory = '"
            + productCategory + "' and customerID = '"
            + customerID + "' order by '"
            + sortColumn + "' asc";
SelectResult sdbResult = sdbc.select(new SelectRequest(query));

解决方案:
这个问题类似于sql注入,在进入SimpleDB数据库查询语句的之前要过滤用户的输入
引用:
CWE-943: Improper Neutralization of Special Elements in Data Query Logic

121. JavaBeans属性注入

JavaBeans Property Injection
漏洞特征:BEAN_PROPERTY_INJECTION
攻击者可以设置任意bean的属性,这样会降低系统的完整性。Bean的population函数允许设置bean的属性或者嵌套属性。
攻击者会影响这个函数从而去访问特殊的bean属性,比如class。类加载器允许他去操控系统属性并且会有潜在的执行任意代码的可能性。
有漏洞的代码:

MyBean bean = ...;
HashMap map = new HashMap();
Enumeration names = request.getParameterNames();
while (names.hasMoreElements()) {
    String name = (String) names.nextElement();
    map.put(name, request.getParameterValues(name));
}
BeanUtils.populate(bean, map);

解决方案:
避免使用用户能够控制的数据去设置Bean属性的名称
引用:
CWE-15: External Control of System or Configuration Setting

122. Struts敏感文件暴露

Struts File Disclosure
漏洞特征:STRUTS_FILE_DISCLOSURE
用户通过输入去访问服务器端的任意路径,这样会允许攻击者下载服务器端的任意文件(包含应用的类文件或者jar文件),或者直接查看在保护目录下的文件。
攻击者可能会伪造请求去寻找服务器中敏感的文件。例如,请求"http://example.com/?returnURL=WEB-INF/applicationContext.xml",服务器就会展示出applicationContext.xml的内容。攻击者就能通过applicationContext.xml精确的定位其他配置文件的位置,并且下载这些配置文件,甚至是类文件或者jar文件。获取到敏感信息之后,攻击者就会进行其他类型的攻击了。
有漏洞的代码:

... 
String returnURL = request.getParameter("returnURL"); 
Return new ActionForward(returnURL); 
...

解决方案:
避免把用户输入的数据放入路径查询字符串之中。
引用:
CWE-552: Files or Directories Accessible to External Parties

123. Spring敏感文件暴露

Spring File Disclosure
漏洞特征:SPRING_FILE_DISCLOSURE
用户通过输入去访问服务器端的任意路径,这样会允许攻击者下载服务器端的任意文件(包含应用的类文件或者jar文件),或者直接查看在保护目录下的文件。
攻击者可能会伪造请求去寻找服务器中敏感的文件。例如,请求"http://example.com/?returnURL=WEB-INF/applicationContext.xml",服务器就会展示出applicationContext.xml的内容。攻击者就能通过applicationContext.xml精确的定位其他配置文件的位置,并且下载这些配置文件,甚至是类文件或者jar文件。获取到敏感信息之后,攻击者就会进行其他类型的攻击了。
有漏洞的代码:

... 
String returnURL = request.getParameter("returnURL");
return new ModelAndView(returnURL); 
...

解决方案:
避免把用户输入的数据放入路径查询字符串之中。
引用:
CWE-552: Files or Directories Accessible to External Parties

124. RequestDispatcher敏感文件暴露

RequestDispatcher File Disclosure
漏洞特征:REQUESTDISPATCHER_FILE_DISCLOSURE
用户通过输入去访问服务器端的任意路径,这样会允许攻击者下载服务器端的任意文件(包含应用的类文件或者jar文件),或者直接查看在保护目录下的文件。
攻击者可能会伪造请求去寻找服务器中敏感的文件。例如,请求http://example.com/?jspFile=…/applicationContext.xml%3F",服务器就会展示出applicationContext.xml的内容。攻击者就能通过applicationContext.xml精确的定位其他配置文件的位置,并且下载这些配置文件,甚至是类文件或者jar文件。获取到敏感信息之后,攻击者就会进行其他类型的攻击了。
有漏洞的代码:

...
String jspFile = request.getParameter("jspFile");
request.getRequestDispatcher("/WEB-INF/jsps/" + jspFile + ".jsp").include(request, response);
...

解决方案:
避免把用户输入的数据放入路径查询字符串之中。
引用:
CWE-552: Files or Directories Accessible to External Parties

125. 格式化字符串操作

Format String Manipulation
漏洞特征:FORMAT_STRING_MANIPULATION
如果用户输入能够控制格式化字符串参数的话,那么攻击者这个漏洞让应用抛出异常或者泄露信息。
攻击者可能会改变格式化字符串的参数,比如可以让应用抛出错误。如果错误没有被捕获,那么应用就会崩溃。
此外,如果敏感信息保留在内存中的话,那么攻击者就会改变格式化字符串去泄露敏感数据。
下面这个示例代码是让用户指定一个浮点数来展示余额,实际上,用户输入任何东西都会让应用抛出异常从而导致显示失败。甚至,更有害的例子是,如果攻击者输入"2f %3s
s.2",那么格式化字符串就会变成"The customer: %s %s has the balance %4.2f
.2fs %4$.2"。这就会导致在输出结果中显示敏感的账户ID。
有漏洞的代码:

Formatter formatter = new Formatter(Locale.US);
String format = "The customer: %s %s has the balance %4$." + userInput + "f";
formatter.format(format, firstName, lastName, accountNo, balance);

解决方案:
避免让用户输入控制格式化字符串参数
引用:
CWE-134: Use of Externally-Controlled Format String

126. HTTP参数被污染

HTTP Parameter Pollution
漏洞特征:HTTP_PARAMETER_POLLUTION
将未验证的用户输入直接拼接到url中,这会让攻击者操控请求参数的值。攻击者可能会操控已存在参数的值,注入新的参数或者利用非变量字典中的参数。http参数污染 (HPP) 攻击包含将已编码的查询字符串分隔符注入其他现有参数。如果应用没有过滤用户输入,那么恶意的用户就可以构造特殊的输入攻击服务器端或者客户端程序。
在下面的例子中,程序员可能没有考虑到攻击者会给参数lang输入en&user_id=1,这可能会让他的用户id发生改变。
有漏洞的代码:

String lang = request.getParameter("lang");
GetMethod get = new GetMethod("http://www.host.com");
get.setQueryString("lang=" + lang + "&user_id=" + user_id);
get.execute();

解决方案:
在使用http参数之前过滤用户输入数据
引用:
CAPEC-460: HTTP Parameter Pollution (HPP)

127. 通过报错泄露敏感信息

Information Exposure Through An Error Message
漏洞特征:INFORMATION_EXPOSURE_THROUGH_AN_ERROR_MESSAGE
在用户看来敏感信息是非常有价值的(比如密码),或者它可能会对其他平台有用,更多的情况下,会引发非常致命的攻击。如果攻击失败,攻击者就会参考服务器提供的错误信息来做更针对性的攻击。比如,试图利用目录穿越漏洞(CWE-22)可能会显示出应用安装的绝对路径。反过来,这样就可以选择合适数量的"…"去跳转到目标文件上。攻击者使用的sql注入(CWE-89)可能在一开始的时候不会成功,但是错误信息可能会展示畸形的查询,这可能会暴露查询逻辑,甚至密码或者包含在数据库中的其他敏感信息
有漏洞的代码:

try {
  out = httpResponse.getOutputStream()
} catch (Exception e) {
  e.printStackTrace(out);
}

引用:
CWE-209: Information Exposure Through an Error Message

128. SMTP头部注入

SMTP Header Injection
漏洞特征:SMTP_HEADER_INJECTION
简单邮件传输协议 (SMTP) 是基于纯文本协议来投递邮件的。就像http,头部字段被new line 所分割。如果用户输入被放置到邮件的头部,那么应用应该删除或者替换掉new line字符串(CR / LF)。你应该使用安全的封装,比如 Apache Common Email 和Simple Java Mail ,这些库会过滤掉那些会导致头部注入的特殊字符。
有漏洞的代码:

Message message = new MimeMessage(session);
message.setFrom(new InternetAddress("[email protected]"));
message.setRecipients(Message.RecipientType.TO, new InternetAddress[] {new InternetAddress("[email protected]")});
message.setSubject(usernameDisplay + " has sent you notification"); //Injectable API
message.setText("Visit your ACME Corp profile for more info.");
Transport.send(message);

解决方案:
使用Apache Common Email 或Simple Java Mail
引用:
OWASP SMTP Injection
CWE-93: Improper Neutralization of CRLF Sequences (‘CRLF Injection’)
Commons Email: User Guide
Simple Java Mail Website
StackExchange InfoSec: What threats come from CRLF in email generation?

129. 在Apache XML RPC服务器或客户端中启用扩展

Enabling extensions in Apache XML RPC server or client.
漏洞特征:WICKET_XSS1
在Apache XML RPC服务器或客户端中启用扩展可能会导致反序列化漏洞,从而允许攻击者执行任意代码。
建议不要使用org.apache.xmlrpc.client.XmlRpcClientConfigImpl或org.apache.xmlrpc.XmlRpcConfigImpl的setEnabledForExtensions方法。默认情况下,在客户端和服务器上都禁用扩展。
引用:
0ang3el’s Blog: Beware of WS-XMLRPC library in your Java App
CVE-2016-5003 vulnerability reference

130. 禁用HTML转义,这样会使应用程序面临XSS风险

Disabling HTML escaping put the application at risk for XSS

漏洞特征:WICKET_XSS1
禁用HTML转义,这样会使应用程序面临跨站点脚本(XSS)的风险。
有漏洞的代码:

add(new Label("someLabel").setEscapeModelStrings(false));

引用:
Wicket models and forms - Reference Documentation
WASC-8: Cross Site Scripting
OWASP: XSS Prevention Cheat Sheet
OWASP: Top 10 2013-A3: Cross-Site Scripting (XSS)
CWE-79: Improper Neutralization of Input During Web Page Generation (‘Cross-site Scripting’)

猜你喜欢

转载自blog.csdn.net/zhaohonghan/article/details/88994382
sec
今日推荐