java代碼審計手書(四)

翻譯自:http://find-sec-bugs.github.io/bugs.htm
翻譯:聶心明

外部文件訪問(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

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

任意文件寫 (Android)

創建文件使用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

已激活地理位置的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. Consider privacy concerns when using Geolocation API
Wikipedia: W3C Geolocation API
W3C: Geolocation Specification

允許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("<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’)

帶有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 Official Doc: WebView.addJavascriptInterface()
CWE-749: Exposed Dangerous Method or Function

沒有用secure標誌的cookie

漏洞特徵: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

沒有用HttpOnly標誌的cookie

漏洞特徵: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

使用反序列化對象

漏洞特徵: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)

不安全的Jackson發序列化配置

漏洞特徵: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

在反序列化漏洞中被利用的類

漏洞特徵: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)

違反信任邊界

漏洞特徵: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

惡意的XSLT

漏洞特徵: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

惡意的XSLT

漏洞特徵: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

潛藏在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

Scala Play服務器端請求僞造(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

URLConnection中的服務器端請求僞造(SSRF) 和任意文件訪問

漏洞特徵: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

在Scala Twirl模板引擎裏面潛在的xss

漏洞規則: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

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

在Velocity中潛在的模板注入

漏洞特徵:TEMPLATE_INJECTION_VELOCITY
Velocity模板引擎非常強大。你可以在模板中使用條件判斷,循環,外部函數調用等邏輯代碼。它裏面也沒有一個沙箱去限制操作。一個惡意的用戶如果可以控制模板,那麼他就可以在服務器端運行惡意代碼。Velocity模板應被視爲腳本。
有漏洞的代碼:

[...]

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

解決方案:
避免讓終端用戶操作Velocity中的模板。如果你需要讓你的用戶去操作模板,那麼最好限制模板引擎的能力,就像Handlebars 或 Moustache 一樣(見引用)
引用:
PortSwigger: Server-Side Template Injection
Handlebars.java

在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

過度寬鬆的cors策略

漏洞規則: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

匿名的LDAP綁定

漏洞特徵:LDAP_ANONYMOUS
沒有做合適的訪問控制,攻擊者可以濫用ldap配置,讓ldap服務器執行一段包含用戶控制的代碼。所有依賴ctx的ldap查詢都可以以不需要用戶認證和訪問控制的方式去執行。攻擊者可以操作其中的查詢語句來獲取被directory服務器保護的數據。
有漏洞代碼:

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

解決方案:
考慮ldap中其他的用戶認證模式並且確保有合適的訪問控制

引用:
Ldap Authentication Mechanisms

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

使用持久性的cookie

漏洞特徵: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

url重寫方法

漏洞規則: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)

不安全的SMTP SSL鏈接

漏洞特徵: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);

引用:
CWE-297: Improper Validation of Certificate with Host Mismatch

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: Improper Neutralization of Special Elements in Data Query Logic

JavaBeans屬性注入

漏洞特徵: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

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: Files or Directories Accessible to External Parties

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: Files or Directories Accessible to External Parties

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: Files or Directories Accessible to External Parties

格式化字符串操作

漏洞特徵:FORMAT_STRING_MANIPULATION
如果用戶輸入能夠控制格式化字符串參數的話,那麼攻擊者這個漏洞讓應用拋出異常或者泄露信息。
攻擊者可能會改變格式化字符串的參數,比如可以讓應用拋出錯誤。如果錯誤沒有被捕獲,那麼應用就會崩潰。
此外,如果敏感信息保留在內存中的話,那麼攻擊者就會改變格式化字符串去泄露敏感數據。
下面這個示例代碼是讓用戶指定一個浮點數來展示餘額,實際上,用戶輸入任何東西都會讓應用拋出異常從而導致顯示失敗。甚至,更有害的例子是,如果攻擊者輸入"2f %3ss %4.2",那麼格式化字符串就會變成"The customer: %s %s has the balance %4.2f.2f %3s %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

http參數被污染

漏洞特徵: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)

通過報錯泄露敏感信息

漏洞特徵: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

SMTP 頭部注入

漏洞特徵:SMTP_HEADER_INJECTION
簡單郵件傳輸協議 (SMTP) 是基於純文本協議來投遞郵件的。就像http,頭部字段被new line 所分割。如果用戶輸入被放置到郵件的頭部,那麼應用應該刪除或者替換掉new line字符串(CR / LF)。你應該使用安全的封裝,比如 Apache Common EmailSimple 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 EmailSimple 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?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章