Java代码审计手册(3)

此文为转载翻译文章(可能会出现错误)

目录

动态JSP包含(JSP_INCLUDE)
Spring表达式中的动态变量(JSP_SPRING_EVAL)
禁用特殊XML字符的转义(JSP_JSTL_OUT)
JSP中的潜在XSS(XSS_JSP_PRINT)
Servlet中潜在的XSS(XSS_SERVLET)
XMLDecoder用法(XML_DECODER)
静态IV(STATIC_IV)
ECB模式不安全(ECB_MODE)
密码易受Oracle填充(PADDING_ORACLE)
没有完整性的密码(CIPHER_INTEGRITY)
使用ESAPI加密器(ESAPI_ENCRYPTOR)
外部文件访问(Android)(ANDROID_EXTERNAL_FILE_ACCESS)
广播(Android)(ANDROID_BROADCAST)
世界可写文件(Android)(ANDROID_WORLD_WRITABLE)
启用了地理位置定位的WebView(Android)(ANDROID_GEOLOCATION)
启用了JavaScript的WebView(Android)(ANDROID_WEB_VIEW_JAVASCRIPT)
具有JavaScript界面​​的WebView(Android)(ANDROID_WEB_VIEW_JAVASCRIPT_INTERFACE)
不带安全标志的Cookie(INSECURE_COOKIE)
不带有HttpOnly标志的Cookie(HTTPONLY_COOKIE)
使用对象反序列化(OBJECT_DESERIALIZATION)
不安全的Jackson反序列化配置(JACKSON_UNSAFE_DESERIALIZATION)
此类可用作反序列化小工具(DESERIALIZATION_GADGET)
违反信任边界(TRUST_BOUNDARY_VIOLATION)
可以将恶意XSLT提供给JSP标签(JSP_XSLT)
可能提供了恶意的XSLT(MALICIOUS_XSLT)
Scala Play中的潜在信息泄漏(SCALA_SENSITIVE_DATA_EXPOSURE)
Scala Play服务器端请求伪造(SSRF)(SCALA_PLAY_SSRF)
URLConnection服务器端请求伪造(SSRF)和文件披露(URLCONNECTION_SSRF_FD)
Scala Twirl模板引擎(SCALA_XSS_TWIRL)中潜在的XSS
Scala MVC API引擎(SCALA_XSS_MVC_API)中潜在的XSS
速度为(TEMPLATE_INJECTION_VELOCITY)的潜在模板注入
使用Freemarker(TEMPLATE_INJECTION_FREEMARKER)进行潜在的模板注入
Pebble可能的模板注入(TEMPLATE_INJECTION_PEBBLE)
过于宽松的CORS政策(PERMISSIVE_CORS)
匿名LDAP绑定(LDAP_ANONYMOUS)
LDAP条目中毒(LDAP_ENTRY_POISONING)
永久性Cookie的使用情况(COOKIE_PERSISTENT)
URL重写方法(URL_REWRITING)
不安全的SMTP SSL连接(INSECURE_SMTP_SSL)
AWS查询注入(AWS_QUERY_INJECTION)
JavaBeans属性注入(BEAN_PROPERTY_INJECTION)
Struts文件披露(STRUTS_FILE_DISCLOSURE)
春季文件披露(SPRING_FILE_DISCLOSURE)
RequestDispatcher文件披露(REQUESTDISPATCHER_FILE_DISCLOSURE)
格式字符串操作(FORMAT_STRING_MANIPULATION)
HTTP参数污染(HTTP_PARAMETER_POLLUTION)
通过错误消息公开信息(INFORMATION_EXPOSURE_THROUGH_AN_ERROR_MESSAGE)
SMTP标头注入(SMTP_HEADER_INJECTION)
在Apache XML RPC服务器或客户端中启用扩展。(RPC_ENABLED_EXTENSIONS)
禁用HTML转义会使应用程序面临XSS的风险(WICKET_XSS1)
忽略SAML中的XML注释可能会导致身份验证绕过(SAML_IGNORE_COMMENTS)
文件权限过高(OVERLY_PERMISSIVE_FILE_PERMISSION)
Unicode转换处理不当(IMPROPER_UNICODE)

动态JSP包含

错误模式:JSP_INCLUDE

包含JSP文件允许输入动态值。它可能允许攻击者控制其中包含的JSP页面。在这种情况下,攻击者将尝试在其控制的磁盘上包括文件。通过包含任意文件,攻击者可以执行任何代码。

参考
InfosecInstitute:文件包含攻击
WASC-05:远程文件包含

Spring表达式中的动态变量

错误模式: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:代码生成的不当控制(“代码注入”)
CWE-95:动态评估代码中的指令不当中和(“评估注入”)

禁用特殊XML字符的转义

错误模式: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:跨站点脚本
OWASP:XSS预防速查表
OWASP:前10名2013-A3:跨站点脚本(XSS)
CWE-79:网页生成期间输入的不正确中和(“跨站点脚本”)
JSTL Javadoc:输出标签

JSP中潜在的XSS

错误模式: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(样式)和URL。请遵循OWASP XSS预防备忘单中定义的XSS保护规则,该规则详细解释了这些防御措施。

参考文献
WASC-8:跨站点脚本
OWASP:XSS预防速查表
OWASP:前10名2013-A3:跨站点脚本(XSS)
CWE-79:网页生成过程中输入的不适当中和(“跨站点脚本”)
OWASP Java编码器

Servlet中潜在的XSS

错误模式: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(样式)和URL。请遵循OWASP XSS预防备忘单中定义的XSS保护规则,该规则详细解释了这些防御措施。

请注意,此Servlet规则中的XSS查找相似的问题,但查找方式与FindBugs中现有的“ XSS:Servlet反映跨站点脚本漏洞”和“ XSS:Servlet反映错误页面中跨站点脚本漏洞”规则不同。 。

参考文献
WASC-8:跨站点脚本
OWASP:XSS预防速查表
OWASP:前10名2013-A3:跨站点脚本(XSS)
CWE-79:网页生成过程中输入的不适当中和(“跨站点脚本”)
OWASP Java编码器

XMLDecoder的用法

错误模式: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博客:使用XMLDecoder在Restlet应用程序上执行服务器端Java代码
RedHat博客:Java反序列化漏洞:第2部分,XML反序列化
CWE-20:输入验证不正确

静态四

错误模式: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:初始化向量
CWE-329:不使用具有CBC模式
加密的随机IV -CBC模式IV:是否秘密?

ECB模式不安全

错误模式:ECB_MODE

应该使用提供更好的加密数据机密性的身份验证密码模式,而不是不能提供良好机密性的电子密码簿(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:认证加密
NIST:认证加密模式
Wikipedia:分组密码操作模式
NIST:关于分组密码操作模式的建议

密码易受Oracle填充的影响

错误模式:PADDING_ORACLE

带有PKCS5Padding的CBC的这种特定模式易受填充oracle攻击的影响。如果系统使用无效填充或有效填充来暴露明文之间的差异,则对手可能会解密该消息。有效填充和无效填充之间的区别通常通过针对每种情况返回的不同错误消息来揭示。

代码有风险:

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);

参考
为大众填充Oracle(由Matias Soler撰写)
维基百科:身份验证加密
NIST:身份验证加密模式
CAPEC:填充Oracle加密攻击
CWE-696:错误的行为顺序

没有完整性的密码

错误模式:CIPHER_INTEGRITY

产生的密文易于被对手更改。这意味着密码无法提供检测数据已被篡改的方法。如果密文可以由攻击者控制,则可以不经检测就对其进行更改。

解决方案是使用包含基于哈希的消息身份验证代码(HMAC)的密码对数据进行签名。将HMAC函数与现有密码结合使用容易产生错误[1]。特别是,始终建议您首先能够验证HMAC,并且只有在数据未修改的情况下,才可以对数据执行任何加密功能。

以下模式易受攻击,因为它们不提供HMAC:
-CBC
-OFB
-CTR
-ECB

以下摘录代码是易受攻击的代码的一些示例。

代码有风险:
CBC模式下的AES

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

带ECB模式的三重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);

在上面的示例解决方案中,GCM模式将HMAC引入到生成的加密数据中,从而提供了结果的完整性。

参考文献
Wikipedia:认证加密
NIST:认证加密模式
Moxie Marlinspike的博客:加密厄运原理
CWE-353:缺少对完整性检查的支持

使用ESAPI加密器

错误模式:ESAPI_ENCRYPTOR

ESAPI在加密组件内的漏洞历史很小。这是一个快速验证列表,以确保已通过身份验证的加密正常工作。

1.库版本
ESAPI 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用户,使用的jar应该是esapi-2.1.0.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安全公告1(CVE-2013-5679)
CVE-2013-5679
Synactiv的漏洞摘要:OWASP中绕过HMAC验证ESAPI对称加密
CWE-310:加密问题
ESAPI-dev邮件列表:CVE-2013-5960的状态

外部文件访问(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官方文档:安全提示
CERT:DRD00-J:不要在外部存储上存储敏感信息[…]
Android官方文档:使用外部存储
OWASP Mobile排名前十的2014-M2:不安全的数据存储
CWE-312:明文敏感信息的存储

广播(Android)

错误模式:ANDROID_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);

配置(接收器)[1]来源:StackOverflow:

<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>

配置(发送方)[1]来源:StackOverflow:

<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。不要使用隐式意图广播敏感信息
Android官方文档:BroadcastReceiver(安全性);
Android官方文档:Receiver的配置(请参阅 参考资料android:permission)。
[1] StackOverflow:如何在android
CWE-925中设置广播发送方和接收方的权限:不正确的意图验证广播接收器
CWE-927的使用:隐式意图在敏感通信中的使用

世界可写文件(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。确保敏感数据的安全性
Android官方文档:安全提示
Android官方文档:Context.MODE_PRIVATE
vogella.com:Android SQLite数据库和内容提供程序-教程
OWASP Mobile Top 10 2014-M2:不安全的数据存储
CWE-312:明文存储敏感信息

启用了地理位置定位的WebView(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。使用Geolocation API
Wikipedia时请考虑隐私问题:W3C Geolocation API
W3C:Geolocation规范

启用JavaScript的WebView(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("
"+newDescription+"

");
}

参考文献
问题:使用 setJavaScriptEnabled 可以引入XSS漏洞
Android官方文档:WebView
WASC-8:跨站点脚本编写
OWASP:XSS预防速查表
OWASP:十大2013-A3:跨站点脚本编写(XSS)
CWE-79:在输入过程中不当中和输入网页生成(“跨站点脚本”)

带有JavaScript界面​​的WebView(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官方文件: WebView.addJavascriptInterface()
CWE-749:暴露的危险方法或功能

没有安全标志的Cookie

错误模式:INSECURE_COOKIE

创建没有设置Secure 标志的新cookie 。该 Secure 标志是浏览器的指令,以确保不会为不安全的通信(http://)发送cookie 。

代码有风险:

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:HTTPS会话中没有“安全”属性的敏感Cookie
CWE-315:Cookie中敏感信息的明文存储
CWE-311:敏感数据的加密丢失
OWASP:安全标志
Rapid7:SSL Cookie缺少安全标志

没有HttpOnly标志的Cookie

错误模式:HTTPONLY_COOKIE

创建没有设置HttpOnly 标志的新cookie 。该 HttpOnly 标志是浏览器的指令,以确保cookie不会被恶意脚本红色。当用户是“跨站点脚本”的目标时,例如,攻击者将从获取会话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>

参考
编码恐怖博客:保护您的Cookie:HttpOnly
OWASP:HttpOnly
Rapid7:Cookie中缺少HttpOnly标志

使用对象反序列化

错误模式:OBJECT_DESERIALIZATION

如果类路径中存在允许触发恶意操作的类,则不可信数据的对象反序列化可能导致远程执行代码。

库开发人员倾向于修复提供潜在恶意触发器的类。仍然有一些类会触发拒绝服务[1]。

反序列化是一项明智的操作,它具有悠久的漏洞历史。一旦在Java虚拟机[2] [3]中发现一个新漏洞,该Web应用程序就可能变得容易受到攻击。

代码有风险:

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

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

解决方案:
避免反序列化远程用户提供的对象。

参考文献
CWE-502:不可信数据的
反序列化不可信数据的
反序列化序列化和反序列化
一种工具,用于生成利用不安全的Java对象反序列化的有效负载
[1]使用类java.util.HashSet
[2]的拒绝服务示例 OpenJDK:ObjectInputStream.readSerialData()中的反序列化问题)(CVE-2015-2590)
[3] Rapid7:Sun Java日历反序列化特权升级(CVE-2008-5353)

不安全的Jackson反序列化配置

错误模式:JACKSON_UNSAFE_DESERIALIZATION

如果错误地使用了Jackson数据绑定库,则如果类路径中存在允许触发恶意操作的类,则不可信数据的反序列化会导致远程执行代码。

解决方案:
通过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 Jackson Deserializer安全漏洞
Java Unmarshaller安全-将数据转换为代码执行

此类可用作反序列化小工具

错误模式:DESERIALIZATION_GADGET

反序列化小工具是攻击者可以使用的类,以利用本机序列化来利用远程API。此类使用readObject 方法(Serializable)向反序列化添加自定义行为, 或者可以从序列化对象(InvocationHandler)进行调用。

该探测器主要供研究人员使用。真正的问题是使用反序列化进行远程操作。删除小工具是一种强化做法,可以减少被利用的风险。

参考文献
CWE-502:不可信数据的
反序列化不可信数据的
反序列化序列化和反序列化
一种工具,用于生成利用不安全的Java对象反序列化的有效负载
[1]使用类java.util.HashSet
[2]的拒绝服务示例 OpenJDK:ObjectInputStream.readSerialData()中的反序列化问题)(CVE-2015-2590)
[3] Rapid7:Sun Java日历反序列化特权升级(CVE-2008-5353)

违反信任边界

错误模式: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);
}

解决方案是在设置新的会话属性之前添加验证。如果可能,请选择安全位置的数据,而不要使用直接的用户输入。

参考文献
[1] CWE-501:违反信任边界
OWASP:违反信任边界

可以将恶意XSLT提供给JSP标签

错误模式:JSP_XSLT

“ XSLT(可扩展样式表语言转换)是一种用于将XML文档转换为其他XML文档的语言。”
可能会将恶意行为附加到这些样式表。因此,如果攻击者可以控制样式表的内容或源,则他可能能够触发远程代码执行。

代码有风险:

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

解决方案是确保从安全来源加载样式表,并确保不可能发生诸如路径遍历之类的漏洞。

参考文献
[1] Wikipedia:NicolasGrégoire的XSLT(可扩展样式表语言转换)令人反感的XSLT
[2]从NicolasGrégoire的XSLT代码执行到Meterpreter外壳XSLT,NicolasGrégoire的Hacking百科全书Acunetix.com:XSLTProcessor的隐患-远程XSL注入器w3.org XSL转换(XSLT)版本1.0:w3c规范
[3] WASC:路径遍历
[4] OWASP:路径遍历

可能提供了恶意的XSLT

错误模式:MALICIOUS_XSLT

“ XSLT(可扩展样式表语言转换)是一种用于将XML文档转换为其他XML文档的语言。”
可能会将恶意行为附加到这些样式表。因此,如果攻击者可以控制样式表的内容或源,则他可能能够触发远程代码执行。

代码有风险:

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

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

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

解决方案是启用安全处理模式,该模式将阻止对Java类(例如)的潜在引用
java.lang.Runtime。

TransformerFactory factory = TransformerFactory.newInstance();
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
Source xslt  = new StreamSource(new FileInputStream(inputUserFile));

Transformer transformer = factory.newTransformer(xslt);

另外,请确保从安全来源加载样式表,并确保不可能出现诸如路径遍历[3] [4]之类的漏洞。

参考文献
[1] Wikipedia:
NicolasGrégoire的XSLT(可扩展样式表语言转换)令人反感的XSLT
[2]从NicolasGrégoire的XSLT代码执行到Meterpreter外壳XSLT,NicolasGrégoire的Hacking百科全书Acunetix.com:XSLTProcessor的隐患-远程XSL注入器w3.org XSL转换(XSLT)版本1.0:w3c规范
[3] WASC:路径遍历
[4] OWASP:路径遍历

Scala Play中潜在的信息泄漏

错误模式:SCALA_SENSITIVE_DATA_EXPOSURE

应用程序可能会无意间泄漏有关其配置,内部工作情况的信息,或者由于各种应用程序问题而侵犯隐私。[1]根据数据的有效性提供不同响应的页面可能导致信息泄漏;特别是当Web应用程序的设计结果揭示了被认为是机密的数据时。

敏感数据的示例包括(但不限于):API密钥,密码,产品版本或环境配置。

代码有风险:

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

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

应用程序配置元素不应在响应内容中发送,并且不应允许用户控制代码将使用哪些配置元素。

参考文献
OWASP:十大2013-A6-敏感数据暴露
[1] OWASP:十大2007-信息泄漏和错误处理错误
[2] WASC-13:信息泄漏
CWE-200:信息暴露

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

错误模式:SCALA_PLAY_SSRF

服务器端请求伪造是在Web服务器执行对用户提供的未经验证的目标参数的请求时发生的。此类漏洞可能使攻击者可以访问内部服务或从Web服务器发起攻击。

脆弱代码:

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

解决方案/对策:
不接受用户的请求目的地
接受目标密钥,并使用它来查找目标(合法)目标
白名单网址(如果可能)
验证URL的开头是否为白名单的一部分

参考
CWE-918:服务器端请求伪造(SSRF)
了解服务器端请求伪造

URLConnection服务器端请求伪造(SSRF)和文件公开

错误模式:URLCONNECTION_SSRF_FD

服务器端请求伪造是在Web服务器执行对用户提供的未经验证的目标参数的请求时发生的。此类漏洞可能使攻击者可以访问内部服务或从Web服务器发起攻击。

URLConnection可以与file://协议或其他协议一起使用,以访问本地文件系统以及可能的其他服务。

脆弱代码:

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

解决方案/对策:
不接受用户的URL目标
接受目标密钥,并使用它来查找目标(合法)目标
白名单网址(如果可能)
验证URL的开头是否为白名单的一部分

参考文献
CWE-918:服务器端请求伪造(SSRF)
了解服务器端请求伪造
CWE-73:文件名或
滥用路径的外部控制jar://下载

Scala Twirl模板引擎中潜在的XSS

错误模式:SCALA_XSS_TWIRL

发现了潜在的XSS。它可以用来在客户端的浏览器中执行不需要的JavaScript。(请参阅参考资料)

脆弱代码:

@(value: Html)

@value

解决方案:

@(value: String)

@value

最好的防御XSS的方法是上下文敏感的输出编码,如上面的示例。通常要考虑4个上下文:HTML,JavaScript,CSS(样式)和URL。请遵循OWASP XSS预防备忘单中定义的XSS保护规则,该规则详细解释了这些防御措施。

参考文献
WASC-8:跨站点脚本
OWASP:XSS预防速查表
OWASP:前10名2013-A3:跨站点脚本(XSS)
CWE-79:网页生成过程中输入的不适当中和(“跨站点脚本”)
OWASP Java编码器

Scala MVC API引擎中潜在的XSS

错误模式: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(样式)和URL。请遵循OWASP XSS预防备忘单中定义的XSS保护规则,该规则详细解释了这些防御措施。

参考文献
WASC-8:跨站点脚本
OWASP:XSS预防速查表
OWASP:前10名2013-A3:跨站点脚本(XSS)
CWE-79:网页生成过程中输入的不适当中和(“跨站点脚本”)
OWASP Java编码器

潜在的模板注入速度

错误模式:TEMPLATE_INJECTION_VELOCITY

速度模板引擎功能强大。可以添加逻辑,包括条件语句,循环和外部调用。它并不是模板操作的沙箱。控制模板的恶意用户可以在服务器端运行恶意代码。速度模板应视为脚本。

脆弱代码:

[...]

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

解决方案:
避免让最终用户使用Velocity操作模板。如果您需要向用户公开模板编辑,请选择无逻辑的模板引擎,例如把手或小胡子(请参阅参考资料)。

参考
PortSwigger:服务器端模板注入
Handlebars.java

使用Freemarker的潜在模板注入

错误模式:TEMPLATE_INJECTION_FREEMARKER

Freemarker模板引擎功能强大。可以添加逻辑,包括条件语句,循环和外部调用。它并不是模板操作的沙箱。控制模板的恶意用户可以在服务器端运行恶意代码。Freemarker模板应被视为脚本。

脆弱代码:

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

解决方案:
避免让最终用户使用Freemarker操纵模板。如果您需要向用户公开模板编辑,请选择无逻辑的模板引擎,例如Handlebars或Moustache(请参阅参考资料)。

参考
PortSwigger:服务器端模板注入
Handlebars.java

Pebble可能的模板注入

错误模式:TEMPLATE_INJECTION_PEBBLE

Pebble模板引擎功能强大。可以添加逻辑,包括条件语句,循环和外部调用。它并不是模板操作的沙箱。控制模板的恶意用户可以在服务器端运行恶意代码。Pebble模板应视为脚本。

脆弱代码:

PebbleTemplate compiledTemplate = engine.getLiteralTemplate(inputFile);
[...]
compiledTemplate.evaluate(writer, context);

解决方案:
避免让最终用户使用Pebble操纵模板。如果您需要向用户公开模板编辑,请选择无逻辑的模板引擎,例如把手或小胡子(请参阅参考资料)。

参考
服务器端模板注入–以MichałBentkowski
PortSwigger的Pebble为例:服务器端模板注入
Handlebars.java

过度宽松的CORS政策

错误模式:PERMISSIVE_CORS

在HTML5之前,Web浏览器实施了Same Origin Policy,该策略可确保为了使JavaScript访问网页的内容,JavaScript和Web页面都必须源自同一域。如果没有“相同来源策略”,恶意网站可能会使用JavaScript加载JavaScript,从而使用客户端的凭据从其他网站加载敏感信息,对其进行筛选,然后将其传达回攻击者。如果定义了称为Access-Control-Allow-Origin的新HTTP标头,则HTML5使JavaScript可以跨域访问数据。Web服务器使用此标头定义使用跨域请求允许哪些其他域访问其域。然而,

脆弱代码:

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

解决方案:
避免将*用作Access-Control-Allow-Origin标头的值,该标头表示可在任何域上运行的JavaScript均可访问该应用程序的数据。

参考
W3C跨域资源共享
启用跨域资源共享

匿名LDAP绑定

错误模式:LDAP_ANONYMOUS

如果没有适当的访问控制,执行包含用户控制值的LDAP语句可能使攻击者滥用配置不良的LDAP上下文。针对上下文执行的所有LDAP查询将在没有身份验证和访问控制的情况下执行。攻击者可能能够以意想不到的方式操纵这些查询之一,以获取对记录的访问,否则该记录将受到目录的访问控制机制的保护。

脆弱代码:

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

解决方案:
考虑对LDAP的其他身份验证模式,并确保适当的访问控制机制。

参考
Ldap身份验证机制

LDAP条目中毒

错误模式: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》:AlvaroMuñoz和Oleksandr Mirosh撰写的《从JNDI / LDAP操纵到远程执行代码的梦想之地》(幻灯片和视频)
HP企业版:AlvaroMuñoz引入JNDI注入和LDAP条目中毒趋势科技:典当风波如何零天逃避Java的点击播放保护功能。

永久性Cookie的使用

错误模式:COOKIE_PERSISTENT

长时间将敏感数据存储在持久性Cookie中可能会导致违反机密性或破坏帐户的行为。

说明:
如果私有信息存储在持久性cookie中,则攻击者将有一个更大的时间窗来窃取此数据-尤其是因为持久性cookie通常被设置为在不久的将来过期。持久性cookie通常存储在客户端上的文本文件中,并且可以访问受害者计算机的攻击者可以窃取此信息。
永久cookie通常用于在用户与网站交互时对其进行概要分析。根据对此跟踪数据执行的操作,有可能使用持久性Cookie来侵犯用户的隐私。

漏洞代码: 以下代码将Cookie设置为在1年后过期。

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

解决方案:
仅在必要时使用持久性Cookie,并限制其最长使用期限。
不要对敏感数据使用持久性cookie。

参考
类Cookie setMaxAge 文档
CWE-539:通过持久性Cookie暴露信息

URL重写方法

错误模式:URL_REWRITING

此方法的实现包括确定会话ID是否需要在URL中编码的逻辑。
URL重写具有重大的安全风险。由于会话ID出现在URL中,因此第三方很容易看到它。URL中的会话ID可以通过多种方式公开,例如:

日志文件,
浏览器历史记录,
通过将其复制粘贴到电子邮件或发布中,
HTTP Referrer。

脆弱代码:

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

解决方案:
避免使用这些方法。如果要对URL字符串或表单参数进行编码,请不要将URL重写方法与URLEncoder类混淆。

参考
OWASP Top 10 2010-A3-身份验证和会话管理中断

不安全的SMTP SSL连接

错误模式:INSUCURE_SMTP_SSL

建立SSL连接时,服务器身份验证被禁用。默认情况下,某些启用SSL连接的电子邮件库不会验证服务器证书。这等效于信任所有证书。当尝试连接到服务器时,此应用程序将很容易接受颁发给“ victim.com”的证书。现在,该应用程序可能会在与受害者服务器的SSL断开连接上泄漏敏感的用户信息。

脆弱代码:

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

解决方案:
请添加以下检查以验证服务器证书:

email.setSSLCheckServerIdentity(true);

参考
CWE-297:主机不匹配的证书验证不正确

AWS查询注入

错误模式: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:数据查询逻辑中特殊元素的不正确中和

JavaBeans属性注入

错误模式:BEAN_PROPERTY_INJECTION

攻击者可以设置可以影响系统完整性的任意bean属性。Bean填充函数允许设置Bean属性或嵌套属性。攻击者可以利用此功能来访问特殊的Bean属性 class.classLoader ,从而使他可以覆盖系统属性并可能执行任意代码。

脆弱代码:

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:系统或配置设置的外部控制

Struts文件披露

错误模式: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:外部方可访问的文件或目录

Spring文件披露

错误模式: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:外部方可访问的文件或目录

RequestDispatcher文件披露

错误模式: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:外部方可访问的文件或目录

格式字符串操作

错误模式:FORMAT_STRING_MANIPULATION

允许用户输入控制格式参数可以使攻击者引发异常或泄漏信息。
攻击者可能能够修改format字符串参数,从而引发异常。如果未捕获此异常,则可能会使应用程序崩溃。或者,如果在未使用的参数中使用了敏感信息,则攻击者可能会更改格式字符串以显示此信息。
下面的示例代码使用户可以指定显示余额的小数点。用户实际上可以指定引起异常的任何内容,这可能导致应用程序失败。在此示例中甚至更关键的是,如果攻击者可以指定用户输入 “2f %3 s s %4 s.2”,则格式字符串将为 “The customer: %s %s has the balance %4 . 2 f .2f %3 .2fs %4$.2”。这将导致敏感 accountNo 包含在结果字符串中。

脆弱代码:

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:使用外部控制的格式字符串

HTTP参数污染

错误模式:HTTP_PARAMETER_POLLUTION

将未经验证的用户输入串联到URL中可以使攻击者覆盖请求参数的值。攻击者可能能够覆盖现有参数值,注入新参数或在无法直接使用的地方利用变量。HTTP参数污染(HPP)攻击包括将编码的查询字符串定界符注入其他现有参数中。如果Web应用程序未正确清理用户输入,则恶意用户可能会破坏应用程序的逻辑以执行客户端或服务器端攻击。
在下面的示例中,程序员没有考虑攻击者提供lang 诸如之类 的参数的可能性en&user_id=1,这将使攻击者可以随意 更改 user_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参数或使用之前任一编码的用户输入 UriBuilder类 从Apache的HttpClient的。

URIBuilder uriBuilder = new URIBuilder("http://www.host.com/viewDetails");
uriBuilder.addParameter("lang", input);
uriBuilder.addParameter("user_id", userId);

HttpGet httpget = new HttpGet(uriBuilder.build().toString()); //OK

参考
CAPEC-460:HTTP参数污染(HPP)

通过错误消息公开信息

错误模式:INFORMATION_EXPOSURE_THROUGH_AN_ERROR_MESSAGE

敏感信息本身可能是有价值的信息(例如密码),或者对于发起其他更致命的攻击可能很有用。如果攻击失败,则攻击者可能会使用服务器提供的错误信息来发起另一种更具针对性的攻击。例如,尝试利用路径穿越弱点(CWE-22)可能会产生已安装应用程序的完整路径名。反过来,这可以用于选择适当数量的“ …”序列以导航到目标文件。使用SQL注入(CWE-89)进行的攻击最初可能不会成功,但是错误消息可能会显示格式错误的查询,这将暴露查询逻辑,甚至可能泄露查询中使用的密码或其他敏感信息。

脆弱代码:

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

参考
CWE-209:通过错误消息公开信息

SMTP标头注入

错误模式:SMTP_HEADER_INJECTION

简单邮件传输协议(SMTP)是用于电子邮件传递的基于文本的协议。与HTTP一样,标头由换行符分隔。如果用户输入放在标题行中,则应用程序应删除或替换新的行字符(CR / LF)。您应该使用安全的包装程序,例如Apache Common Email和Simple Java Mail,它们可以过滤可能导致标头注入的特殊字符。

脆弱代码:

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

解决方案:
使用Apache普通电子邮件或简单Java邮件。

参考资料
OWASP SMTP注入
CWE-93:CRLF序列的不适当中和(“ CRLF注入”)
公用域电子邮件:用户指南
简单Java邮件网站
StackExchange InfoSec:电子邮件生成中CRLF带来了哪些威胁?

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

错误模式:RPC_ENABLED_EXTENSIONS

在Apache XML RPC服务器或客户端中启用扩展会导致反序列化漏洞,该漏洞将允许攻击者执行任意代码。
建议不要使用 或的 setEnabledForExtensions 方法 。默认情况下,客户端和服务器上的扩展名均被禁用。

org.apache.xmlrpc.client.XmlRpcClientConfigImplorg.apache.xmlrpc.XmlRpcConfigImpl

参考文献
0ang3el的博客:当心Java App
CVE-2016-5003中的WS-XMLRPC库漏洞参考

禁用HTML转义会使应用程序面临XSS的风险

错误模式:WICKET_XSS1

禁用HTML转义会使应用程序面临跨站点脚本(XSS)的风险。

脆弱代码:

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

参考
Wicket模型和表格-参考文档
WASC-8:跨站点脚本
OWASP:XSS预防速查表
OWASP:前10名2013-A3:跨站点脚本(XSS)
CWE-79:网页生成期间输入的不正确中和(‘跨站脚本’)

忽略SAML中的XML注释可能导致身份验证绕过

错误模式:SAML_IGNORE_COMMENTS

安全声明标记语言(SAML)是使用XML的单点登录协议。SAMLResponse消息包括描述经过身份验证的用户的语句。如果用户设法放置XML注释( ),则可能导致解析器提取文字值的方式出现问题。

例如,让我们看下面的XML部分:

<saml:Subject><saml:NameID>admin@domain.com<!---->.evil.com</saml:NameID></saml:Subject>

用户身份是,“admin@domain.com .evil.com"但实际上是一个文本节点"admin@domain.com”,一个注释"“和一个文本节点”.evil.com"。提取NameID时,服务提供商的实现可能会采用第一个文本节点或最后一个文本节点。
脆弱代码:

@Bean
ParserPool parserPool1() {
    BasicParserPool pool = new BasicParserPool();
    pool.setIgnoreComments(false);
    return pool;
}

解决方案:

@Bean
ParserPool parserPool1() {
    BasicParserPool pool = new BasicParserPool();
    pool.setIgnoreComments(true);
    return pool;
}

参考资料
Duo发现影响多种实现
的SAML漏洞Spring Security SAML和本周的SAML漏洞

过于宽松的文件权限

错误模式:OVERLY_PERMISSIVE_FILE_PERMISSION

通常,对所有用户设置过度宽松的文件权限(如read + write + exec)是一种不良做法。如果受影响的文件是配置,二进制文件,脚本或敏感数据,则可能导致特权提升或信息泄漏。

与您的应用程序在同一主机上运行的另一项服务可能会受到威胁。服务通常在其他用户下运行。遭到入侵的服务帐户可能被用来读取您的配置,向脚本添加执行指令或更改数据文件。为了限制其他服务或本地用户造成的损害,应限制您的应用程序文件的许可。

脆弱代码1(符号表示法):

Files.setPosixFilePermissions(configPath, PosixFilePermissions.fromString("rw-rw-rw-"));

解决方案1(符号表示法):

Files.setPosixFilePermissions(configPath, PosixFilePermissions.fromString("rw-rw----"));

漏洞代码2(面向对象的实现):

Set<PosixFilePermission> perms = new HashSet<>();
perms.add(PosixFilePermission.OWNER_READ);
perms.add(PosixFilePermission.OWNER_WRITE);
perms.add(PosixFilePermission.OWNER_EXECUTE);

perms.add(PosixFilePermission.GROUP_READ);
perms.add(PosixFilePermission.GROUP_WRITE);
perms.add(PosixFilePermission.GROUP_EXECUTE);

perms.add(PosixFilePermission.OTHERS_READ);
perms.add(PosixFilePermission.OTHERS_WRITE);
perms.add(PosixFilePermission.OTHERS_EXECUTE);

解决方案2(面向对象的实现):

Set<PosixFilePermission> perms = new HashSet<>();
perms.add(PosixFilePermission.OWNER_READ);
perms.add(PosixFilePermission.OWNER_WRITE);
perms.add(PosixFilePermission.OWNER_EXECUTE);

perms.add(PosixFilePermission.GROUP_READ);
perms.add(PosixFilePermission.GROUP_WRITE);
perms.add(PosixFilePermission.GROUP_EXECUTE);

参考
CWE-732:关键资源的错误权限分配
Linux特权升级
文件系统权限指南

Unicode转换处理不当

错误模式:IMPROPER_UNICODE

Unicode转换中的异常行为有时会导致错误,其中一些会影响软件安全性。将大写转换应用于两个字符串的代码可能会错误地将两个字符串解释为相等。

在下面的代码中,字符串"ADM\u0131N"将导致条件为true。当应用大写转换时,字符\u0131将变为\u0049(I)。如果开发人员只有一个用户,这可能是一个问题"ADMIN"。

if(username.toUpperCase().equals("ADMIN")) {
  //...
}

归一化函数可以发生类似的字符转换。在下面的代码中,字符串"BAC\u212AUP"将导致条件为true。当应用规范化转换时,字符\u212A将变为\u0048(K)。

if(Normalizer.normalize(input, Normalizer.Form.NFC).equals("BACKUP")) {
  //...
}

参考
Java TLS主机验证中的弱点
Unicode安全指南:字符转换
CWE-176:Unicode编码的不正确处理
Unicode:Unicode安全注意事项
安全专业人员的Unicode

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值