首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >清理/清理xpath属性

清理/清理xpath属性
EN

Stack Overflow用户
提问于 2008-10-09 19:32:27
回答 3查看 3.2K关注 0票数 6

我需要动态构造一个元素属性的XPath查询,其中属性值由用户提供。我不确定如何清理或清理此值以防止XPath等效于SQL注入攻击。例如(在PHP中):

代码语言:javascript
复制
<?php
function xPathQuery($attr) {
    $xml = simplexml_load_file('example.xml');
    return $xml->xpath("//myElement[@content='{$attr}']");
}

xPathQuery('This should work fine');
# //myElement[@content='This should work fine']

xPathQuery('As should "this"');
# //myElement[@content='As should "this"']

xPathQuery('This\'ll cause problems');
# //myElement[@content='This'll cause problems']

xPathQuery('\']/../privateElement[@content=\'private data');
# //myElement[@content='']/../privateElement[@content='private data']

最后一个特别让人回想起以前的SQL注入攻击。

现在,我知道将会有包含单引号的属性和包含双引号的属性。既然这些是作为函数的参数提供的,那么清理这些输入的理想方式是什么呢?

EN

回答 3

Stack Overflow用户

发布于 2008-10-11 13:31:58

XPath实际上包含了一种安全地执行此操作的方法,因为它允许在表达式中使用$varname形式的variable references。PHP的SimpleXML所基于的库是provides an interface to supply variables,但是示例中的这个is not exposed by the xpath function

作为一个演示,这确实可以是多么简单:

代码语言:javascript
复制
>>> from lxml import etree
>>> n = etree.fromstring('<n a=\'He said "I&apos;m here"\'/>')
>>> n.xpath("@a=$maybeunsafe", maybeunsafe='He said "I\'m here"')
True

这是在使用lxml,这是一个python包装器,用于与SimpleXML相同的底层库,并使用类似的xpath function。布尔值、数字和节点集也可以直接传递。

如果不能选择切换到功能更强大的XPath接口,那么当给定外部字符串时,一个变通方法可能是这样的(请随意适应PHP语言):

代码语言:javascript
复制
def safe_xpath_string(strvar):
    if "'" in strvar:
        return "',\"'\",'".join(strvar.split("'")).join(("concat('","')"))
    return strvar.join("''")

返回值可以直接插入到表达式字符串中。由于这实际上可读性不是很好,下面是它的行为:

代码语言:javascript
复制
>>> print safe_xpath_string("basic")
'basic'
>>> print safe_xpath_string('He said "I\'m here"')
concat('He said "I',"'",'m here"')

注意,您不能在XML文档外部使用&apos;形式的转义,通用的XML序列化例程也不适用。但是,XPath concat函数可用于在任何上下文中创建包含这两种类型的引号的字符串。

PHP变体:

代码语言:javascript
复制
function safe_xpath_string($value)
{
    $quote = "'";
    if (FALSE === strpos($value, $quote))
        return $quote.$value.$quote;
    else
        return sprintf("concat('%s')", implode("', \"'\", '", explode($quote, $value)));
}
票数 6
EN

Stack Overflow用户

发布于 2008-10-09 19:38:23

代码语言:javascript
复制
function xPathQuery($attr) {
    $xml = simplexml_load_file('example.xml');
    $to_encode = array('&', '"');
    $to_replace = array('&amp;','&quot;');
    $attr = replace($to_encode, $to_replace, $attr);
    return $xml->xpath("//myElement[@content=\"{$attr}\"]");
}

好的,它是做什么的?

它对字符串中所有出现的&和“as & and”进行编码,这将为您提供用于特定用途的安全选择器。请注意,我还将xpath中的内部‘替换为“.edit:后来有人指出’可以转义为',因此您可以使用您喜欢的任何字符串引用方法。

票数 -1
EN

Stack Overflow用户

发布于 2008-10-09 20:08:00

我将使用DOM创建一个单元素XML文档,使用DOM将元素的文本设置为提供的值,然后从DOM的XML字符串表示中获取文本。这将保证所有的字符转义都被正确地完成,而不仅仅是我正在考虑的字符转义。

编辑:我之所以在这样的情况下使用DOM,是因为编写DOM的人已经阅读过XML推荐标准,而我还没有(至少,没有像他们那样细心)。举个简单的例子,如果文本包含XML不允许的字符(如#x8),DOM将报告解析错误,因为DOM的作者已经实现了XML建议的第2.2节。

现在,我可能会说,“好吧,我将只从XML建议中获取无效字符的列表,并将它们从输入中剔除。”好的。让我们来看看XML推荐and...um,Unicode代理块到底是什么?我要写什么样的代码才能摆脱它们呢?他们能从一开始就进入我的文本吗?

让我们假设我解决了这个问题。关于XML recommendation如何指定字符表示,有没有我不知道的其他方面?可能吧。这些会对我正在尝试实现的东西产生影响吗?也许吧。

如果我让DOM为我做字符编码,我就不必担心这些事情了。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/188834

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档