Xpath 注入是 OWASP TOP10 安全威脅中 A1 Injection 中的一種,注入漏洞發生在應用程序將不可信的數據發送到解釋器時。雖然注入漏洞很容易經過審查代碼發現,可是卻不容易在測試中發現。html
注入能致使數據丟失或數據破壞、缺少可審計性或者是拒絕服務。注入漏洞有時候甚至能致使徹底主機接管。前端
首先咱們先來看一下在 Java 中引用 xpath 須要用的 lib 庫:java
那麼xpath注入是從哪些途徑進入到代碼邏輯的呢?你們仔細思考一下無外乎三個途徑:cookie
、header
、request parameters/input
。若是咱們能對這三個注入源頭進行嚴格得入參檢查是否就可以防護絕大部分的注入攻擊了呢?git
答案是能夠防護大部分注入攻擊,下面咱們就一塊兒來看一下如何進行有效得進行入參檢查: 咱們將入參都轉化爲 Map 對象,Map<K, Collection<V>> asMap()
;github
而後經過CheckMap(finnal Map<String, String> params
)方法,檢查入參是否合法。安全
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("\"", "\"\""))
上述檢測條件中用到兩個關鍵方法IsOutBoundary
和IsQuoteUnbalance
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,以下圖:
hints提示咱們攻擊的入參:
Try username: Smith' or 1=1 or 'a'='a and a password: anything
點擊 Submit 以後神奇得事情出現了!
面對這樣得一種攻擊那麼咱們該如何防護呢?若是對代碼感興趣得同窗能夠把 WebGoat 得源碼 down 下來;而後將上面得入參檢測得方法封裝一下嵌入到 WebGoat 得源碼中,而後咱們再攻擊一下,那麼接下來會發生什麼樣的事情呢?
Xpath 查詢失敗了,並無返回任何結果,攻擊被攔截以後,前端頁面沒有渲染任何東西。因而可知入參檢查在注入類得漏洞防護中能夠起到立竿見影得做用。
Xpath 查詢失敗了,並無返回任何結果,攻擊被攔截以後,前端頁面沒有渲染任何東西。因而可知入參檢查在注入類得漏洞防護中能夠起到立竿見影得做用。
參考文獻:
[1] OWASP TOP10-2013 release
[2] ASCII(wikipedia)
[3] WebGoat
本文系 OneAPM 架構師呂龍濤原創文章。現在,多樣化的攻擊手段層出不窮,傳統安全解決方案愈來愈難以應對網絡安全攻擊。OneASP 自適應安全平臺集成了預測、預防、檢測和響應的能力,爲您提供精準、持續、可視化的安全防禦。想閱讀更多技術文章,請訪問 OneAPM 官方技術博客
本文轉自 OneAPM 官方博客