如何從代碼層防護10大安全威脅中的 Xpath Injection?

廣泛性和可檢測性:

Xpath 注入是 OWASP TOP10 安全威脅中 A1 Injection 中的一種,注入漏洞發生在應用程序將不可信的數據發送到解釋器時。雖然注入漏洞很容易經過審查代碼發現,可是卻不容易在測試中發現。html

影響嚴重:

注入能致使數據丟失或數據破壞、缺少可審計性或者是拒絕服務。注入漏洞有時候甚至能致使徹底主機接管。前端

從代碼層次如何防護:

首先咱們先來看一下在 Java 中引用 xpath 須要用的 lib 庫:java

  • javax.xml.xpath
  • org.jdom.xpath
  • org.jdom2.xpath等

那麼xpath注入是從哪些途徑進入到代碼邏輯的呢?你們仔細思考一下無外乎三個途徑:cookieheaderrequest parameters/input。若是咱們能對這三個注入源頭進行嚴格得入參檢查是否就可以防護絕大部分的注入攻擊了呢?git

答案是能夠防護大部分注入攻擊,下面咱們就一塊兒來看一下如何進行有效得進行入參檢查: 咱們將入參都轉化爲 Map 對象,Map<K, Collection<V>> asMap();github

而後經過CheckMap(finnal Map<String, String> params)方法,檢查入參是否合法。安全

下面咱們來實現這個CheckMap內部方法:

1. 經過遍歷檢查Map中key得合法性cookie

for (final String key : params.keySet()) {
        if (this.checkString(key)) {
            return true;
        }

2.檢查每個 key 對應得 value 得合法性:網絡

final Collection<String> coll = (Collection<String>)params.get((Object)key);
        for (final String input : coll) {
            if (this.checkString(input)) {
                return true;
            }
        }

作完這些就是細節方面得檢測了,具體得就是 checkString 如何實現。筆者暫時能想到認爲一個入參是 xpath 得檢測條件大概有如下幾點:架構

private boolean checkString(final String input) {
    return null != input && input.length() > 1 && (this.parser.IsOutBoundary(input) || (-1 != input.indexOf(39) && (this.parser.IsOutBoundary(input.replace("'", "''")) || this.parser.IsOutBoundary(input.replace("'", "\\'")))) || (-1 != input.indexOf(34) && (this.parser.IsOutBoundary(input.replace("\"", "\"\"")) || this.parser.IsOutBoundary(input.replace("\"", "\\\"")))) || this.parser.IsQuoteUnbalanced(input));
}

經過查 ASCII 碼錶咱們知道39對應「'」,34對應「"」;因此有了檢測條件less

-1!=input.indexOf(39)&&(this.parser.IsOutBoundary(input.replace("'","''")
-1!=input.indexOf(34)&& this.parser.IsOutBoundary(input.replace("\"", "\"\""))

上述檢測條件中用到兩個關鍵方法IsOutBoundaryIsQuoteUnbalance

public boolean IsOutBoundary(String input) {
    int offset = 0;
    if (null == input || input.length() <= 1) {
        return false;
    }
    input = input.toLowerCase();
    while (true) {
        final int x = this.getRawValue().indexOf(input, offset);
        final int y = x + input.length();
        if (-1 == x) {
            return false;
        }
        final int ceil = this.getCeiling(this.boundaries, x + 1);
        if (-1 != ceil && ceil < y) {
            return true;
        }
        offset = y;
    }
}

public boolean IsQuoteUnbalanced(String input) {
    input = input.toLowerCase();
    return this.getRawValue().contains(input) && this.stack.size() > 0 && input.indexOf(this.stack.peek()) != -1;
}

 public String getRawValue() {
        return this.input;
    }
 
 private int getCeiling(final List<Integer> boundaries, final int value) {
    for (final int x : boundaries) {
        if (x >= value) {
            return x;
        }
    }
    return -1;
}
漏洞攻擊示例

看完代碼是如何檢查得咱們來一個真真正正 Xpath 注入的示例;來檢驗一下咱們代碼是都有效。

WebGoat 是 OWASP 推出得一款開源的含有大量漏洞攻擊的應用,在 Github 上能夠直接搜到源碼。

咱們找到 Xpath Injection 得 lession,以下圖:

如何從代碼層防護10大安全威脅中的 Xpath Injection

hints提示咱們攻擊的入參

Try username: Smith' or 1=1 or 'a'='a and a password: anything

點擊 Submit 以後神奇得事情出現了!

如何從代碼層防護10大安全威脅中的 Xpath Injection

面對這樣得一種攻擊那麼咱們該如何防護呢?若是對代碼感興趣得同窗能夠把 WebGoat 得源碼 down 下來;而後將上面得入參檢測得方法封裝一下嵌入到 WebGoat 得源碼中,而後咱們再攻擊一下,那麼接下來會發生什麼樣的事情呢?

Xpath 查詢失敗了,並無返回任何結果,攻擊被攔截以後,前端頁面沒有渲染任何東西。因而可知入參檢查在注入類得漏洞防護中能夠起到立竿見影得做用。

如何從代碼層防護10大安全威脅中的 Xpath Injection

Xpath 查詢失敗了,並無返回任何結果,攻擊被攔截以後,前端頁面沒有渲染任何東西。因而可知入參檢查在注入類得漏洞防護中能夠起到立竿見影得做用。

參考文獻:

[1] OWASP TOP10-2013 release

[2] ASCII(wikipedia)

[3] WebGoat

本文系 OneAPM 架構師呂龍濤原創文章。現在,多樣化的攻擊手段層出不窮,傳統安全解決方案愈來愈難以應對網絡安全攻擊。OneASP 自適應安全平臺集成了預測、預防、檢測和響應的能力,爲您提供精準、持續、可視化的安全防禦。想閱讀更多技術文章,請訪問 OneAPM 官方技術博客

本文轉自 OneAPM 官方博客

相關文章
相關標籤/搜索