29

特定のマルチバイト文字セットが与えられた場合、以下が意図したとおりに動作しないと仮定して正しいでしょうか?

$string = str_replace('"', '\\"', $string);

特に、入力が 0xbf5c のような有効な文字を含む可能性のある文字セットにあった場合、攻撃者は 0xbf22 を挿入して 0xbf5c22 を取得し、有効な文字の後に引用符で囲まれていない二重引用符 (") を残します。

この問題を軽減する簡単な方法はありますか、それともそもそも問題を誤解していますか?

(私の場合、文字列は HTML 入力タグの値属性に入ります: echo 'input type="text" value="' . $string . '">';)

編集: さらに言えば、preg_quote() のような関数はどうですか? charset 引数がないため、このシナリオではまったく役に立たないようです。文字セットを UTF-8 に制限するオプションがない場合 (はい、それはいいことです)、本当にハンディキャップを負っているように見えます。その場合、どのような置換および引用機能を使用できますか?

4

3 に答える 3

30

いいえ、その通りです。マルチバイト文字列に対してシングルバイト文字列関数を使用すると、予期しない結果が生じる可能性があります。代わりにマルチバイト文字列関数を使用してください。たとえばmb_ereg_replace、またはmb_split:

$string = mb_ereg_replace('"', '\\"', $string);
$string = implode('\\"', mb_split('"', $string));

編集分割結合バリアントを使用し    たmb_replace実装は次のとおりです。

function mb_replace($search, $replace, $subject, &$count=0) {
    if (!is_array($search) && is_array($replace)) {
        return false;
    }
    if (is_array($subject)) {
        // call mb_replace for each single string in $subject
        foreach ($subject as &$string) {
            $string = &mb_replace($search, $replace, $string, $c);
            $count += $c;
        }
    } elseif (is_array($search)) {
        if (!is_array($replace)) {
            foreach ($search as &$string) {
                $subject = mb_replace($string, $replace, $subject, $c);
                $count += $c;
            }
        } else {
            $n = max(count($search), count($replace));
            while ($n--) {
                $subject = mb_replace(current($search), current($replace), $subject, $c);
                $count += $c;
                next($search);
                next($replace);
            }
        }
    } else {
        $parts = mb_split(preg_quote($search), $subject);
        $count = count($parts)-1;
        $subject = implode($replace, $parts);
    }
    return $subject;
}

パラメータの組み合わせに関しては、この関数は singlebyte のように動作する必要がありますstr_replace

于 2010-09-24T10:06:46.783 に答える
8

このコードは、UTF-8 や EUC-TW などの正常なマルチバイト エンコーディングでは完全に安全ですが、Shift_JISやGB* などの壊れたエンコーディングでは危険です。 UTF-8 のみをサポートすることをお勧めします。

于 2011-01-17T05:29:04.080 に答える
3

mb_ereg_replace最初に で文字セットを指定することにより、どちらかを使用できますmb_regex_encoding()。または、UTF-8 を使用する場合preg_replaceは、u修飾子を使用できます。

于 2010-09-24T10:09:17.900 に答える