1. 程式人生 > 其它 >Java程式碼審計手冊(3)

Java程式碼審計手冊(3)

技術標籤:java安全

此文為轉載翻譯文章(可能會出現錯誤)

目錄

動態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("[email protected]");
email.setSubject("TestMail");
email.setMsg("This is a test mail ... :-)");
email.addTo("[email protected]");
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("[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普通電子郵件或簡單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>[email protected]<!---->.evil.com</saml:NameID></saml:Subject>

使用者身份是,“[email protected] .evil.com"但實際上是一個文字節點"[email protected]”,一個註釋"“和一個文字節點”.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