阅读更多
本文转自OneAPM技术社区,系OneAPM架构师吕龙涛原创文章

普遍性和可检测性:
Xpath 注入是OWASP TOP10 安全威胁中 A1 Injection 中的一种,注入漏洞发生在应用程序将不可信的数据发送到解释器时。虽然注入漏洞很容易通过审查代码发现,但是却不容易在测试中发现。

影响严重:
注入能导致数据丢失或数据破坏、缺乏可审计性或者是拒绝服务。注入漏洞有时候甚至能导致完全主机接管。

从代码层次如何防御:
首先我们先来看一下在 Java 中引用 xpath 需要用的 lib 库:
  • javax.xml.xpath
  • org.jdom.xpath
  • org.jdom2.xpath等

那么xpath注入是从哪些途径进入到代码逻辑的呢?大家仔细思考一下无外乎三个途径:cookie、header、request parameters/input。如果我们能对这三个注入源头进行严格得入参检查是否就能够防御绝大部分的注入攻击了呢?

答案是可以防御大部分注入攻击,下面我们就一起来看一下如何进行有效得进行入参检查: 我们将入参都转化为 Map 对象,Map<K, Collection<V>> asMap();

然后通过CheckMap(finnal Map<String, String> params)方法,检查入参是否合法。
下面我们来实现这个CheckMap内部方法:
1. 通过遍历检查Map中key得合法性
 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对应“"”;所以有了检测条件
-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 查询失败了,并没有返回任何结果,攻击被拦截之后,前端页面没有渲染任何东西。由此可见入参检查在注入类得漏洞防御中可以起到立竿见影得作用。

参考文献:
  • 大小: 19.9 KB
  • 大小: 18.7 KB
  • 大小: 9 KB
来自: OneAPM
2
0
评论 共 0 条 请登录后发表评论

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • layui输入框只允许输入中文且判断长度的例子

    今天小编就为大家分享一篇layui输入框只允许输入中文且判断长度的例子,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

  • 可以限制中文输入的文本框

    根据网友提的意见,大家都需要限制中文输入,今天,我试验了一下,找了一个办法限制中文输入,测试已经通过,大家也自己试一下吧,有什么意见继续提,如果愿意加我的QQ:36745349 这个是在昨天的基础上做的更改,测试已经满足大家的要求,如果谁有更好的办法也请交流一下下面是代码:sunnyxing2004-04-01最后修改Public Class MyTextBox    Inher

  • 输入框限制不允许输入中文

    思路:在输入过程中 将中文替换为"", string.replace(/[\u4E00-\u9FA5]|[\uFE30-\uFFA0]/g, '');

  • JS 控制文本框只能输入中文、英文、数字与指定特殊符号(屏蔽表情输入)

    onkeyup:释放键盘事件 onpaste:粘贴事件 oncontextmenu :鼠标右击事件 控制这三种事件的输入 onkeyup="this.value=this.value.replace(/[^\u4e00-\u9fa5\w]/g,'')" 只能输入数字: onkeyup="value=value.replace(/[^\d]/g,'') " 只能输入数字和字母...

  • input文本框 限制输入中文&&input文本框 限制输入数字

    input输入框可以输入英文&数字,不能输入中文 input输入框不能输入数字

  • layui输入框只允许输入中文且判断长度

    今天写项目遇到一个问题,在输入老师昵称的时候需要控制input输入框不能为空,且字符的长度有限制,英文字符不能超过20,中文不能超过10。输入课程简介的时候,textarea只能输入中文和中文标点,且长度不超过100。使用框架为:Thymeleaf + layui + shiro。 搜了很多资料没找到全的,现将具体实现展示如下: [不为空的要求:] 这个...

  • LayUi之限制文本框输入

    比如下面的一个需求 通常用js判断:给输入框定义一个onChange事件 获取该文本框的值,然后通过正则表达式来判断是否符合要求。 然而LayUi则可以在html中直接写正则表达式 写法如下 &lt;div&gt; &lt;label class="layui-form-label"&gt;排序&lt;/label&gt; &lt;div class="layui-input-b...

  • Unity之路(二):输入事件管理Input

    在Unity中输入时间有Input类来管理输入事件,常用方法:// 键盘事件 public static bool GetKeyDwon(enum KeyCode); // 按键按下(触发一次) public static bool GetKeyDwon(enum KeyCode); // 按键放开(触发一次) public static bool GetKey(enum KeyCode); //

  • Input 输入中文 状态控制

    input 最常见的便是onChange方法,这个方法在input框内值(e.target.value)发生变化时,便会触发这个方法。 在输入中文的时候,拼音的过程中,onChange还是会不停的触发,这就带来了中文输入的bug,举一个栗子: 问题描述: input框中需要限制字符数量,比如限制成5个字符,再输入“成功”两个字的过程中,会出现还没有输入完成,体精警告字符太长,这样的情况。显然,...

  • 如何禁止在文本框中输入中文

    具体步骤: 方法一:用文本框的CSS属性ime-mode实现。       提示:设置ime-mode为disabled的意思是禁止在输入时禁止用户激活输入中文,韩文,日文等的输入法(IME)状态,因为这个只能检测到键盘的输入,对通过鼠标操作的粘贴和拖放无效。 方法二:在松开按键时用脚本检查文本框的值,只保留Unicode编码在0和255之间的字符。 function check(str){ v

  • EditControl 限制输入文本的l两种方法

    下边是两种限制编辑框输入内容的方法。在VS2003里建立基于对话框的应用程序CMyEdit,打开资源视图,删除对话框上自带的确定和取消按钮。然后添加一编辑框控件,将其ID修改为IDC_MY_EDIT,通过类向导给该编辑框添加控件变量m_edit_LimitInput。      比如,现在欲想在编辑框里只能输入十进制数,即“0123456789”这些字符。 方法一: BOO

  • 控制 input 输入框不能输入中文,即不能在输入框中使用输入法

    设置输入框的样式,代码如下

Global site tag (gtag.js) - Google Analytics