6

属性値がユーザーによって提供される要素属性の XPath クエリを動的に構築する必要があります。SQL インジェクション攻撃に相当する XPath を防ぐために、この値をクリーニングまたはサニタイズする方法がわかりません。例 (PHP の場合):

<?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 インジェクション攻撃を思い起こさせます。

さて、一重引用符を含む属性と二重引用符を含む属性があるという事実を知っています。これらは関数への引数として提供されるため、これらの入力をサニタイズする理想的な方法は何でしょうか?

4

3 に答える 3

6

XPath には、これを安全に行うための方法が実際に含まれています。つまり、式の形式で変数参照$varnameが許可されます。PHP の SimpleXML が基づいているライブラリは、変数を提供するためのインターフェイスを提供しますが、これは例の xpath 関数によって公開されていません

これがいかに簡単かを示すデモとして:

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

これは、SimpleXML と同じ基本ライブラリの Python ラッパーであるlxmlを、同様のxpath 関数とともに使用しています。ブール値、数値、およびノー​​ド セットも直接渡すことができます。

より有能な XPath インターフェースへの切り替えがオプションではない場合、外部文字列が与えられたときの回避策は、次の行に沿ったものになります (PHP に自由に適応してください)。

def safe_xpath_string(strvar):
    if "'" in strvar:
        return "',\"'\",'".join(strvar.split("'")).join(("concat('","')"))
    return strvar.join("''")

戻り値は、式の文字列に直接挿入できます。これは実際にはあまり読みにくいため、次のように動作します。

>>> print safe_xpath_string("basic")
'basic'
>>> print safe_xpath_string('He said "I\'m here"')
concat('He said "I',"'",'m here"')

&apos;XML ドキュメントの外部のフォームでエスケープを使用することはできず、一般的な XML シリアライゼーション ルーチンも適用できないことに注意してください。ただし、XPath concat 関数を使用して、任意のコンテキストで両方のタイプの引用符を含む文字列を作成できます。

PHP バリアント:

function safe_xpath_string($value)
{
    $quote = "'";
    if (FALSE === strpos($value, $quote))
        return $quote.$value.$quote;
    else
        return sprintf("concat('%s')", implode("', \"'\", '", explode($quote, $value)));
}
于 2008-10-11T13:31:57.813 に答える
-1
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}\"]");
}

わかりました、それは何をしますか?

文字列内の&と "のすべての出現箇所を&amp;と&quot;としてエンコードします。これにより、その特定の用途に安全なセレクターが提供されます。xpathの内側の'も"に置き換えたことに注意してください。編集:それ以来、'は&apos;としてエスケープできることが指摘されているため、任意の文字列引用方法を使用できます。

于 2008-10-09T19:38:23.407 に答える
-1

DOM を使用して単一要素の XML ドキュメントを作成し、DOM を使用して要素のテキストを指定された値に設定し、DOM の XML の文字列表現からテキストを取得します。これにより、すべての文字のエスケープが適切に行われることが保証されます。また、私が偶然に考えている文字のエスケープだけではありません。

編集: このような状況で DOM を使用する理由は、DOM を作成した人々が XML の推奨事項を読んでいて、私が読んでいない (少なくとも、彼らが持っている注意のレベルでは) からです。簡単な例を挙げると、DOM の作成者が XML 勧告のセクション 2.2 を実装しているため、テキストに XML で許可されていない文字 (#x8 など) が含まれている場合、DOM は解析エラーを報告します。

ここで、「まあ、XML 推奨事項から無効な文字のリストを取得し、それらを入力から削除します」と言うかもしれません。もちろん。XML の推奨事項を見てみましょう...ええと、Unicode サロゲート ブロックとは一体何なのでしょうか? それらを取り除くには、どのようなコードを書かなければなりませんか? そもそも彼らは私のテキストに入ることができますか?

私がそれを理解したとしましょう。XML 勧告が文字表現を指定する方法について、私が知らない他の側面はありますか? おそらく。これらは、私が実装しようとしているものに影響を与えますか? 多分。

DOM に文字エンコーディングを任せれば、そのようなことを心配する必要はありません。

于 2008-10-09T20:07:59.603 に答える