web-dev-qa-db-ja.com

HTML入力値のサニタイズ

次の中で、引用符(_"_)以外の何かを(_"_)に変換する必要がありますか?

_<input type="text" value="$var">_

個人的には、_" on*=..._を使用せずに、どうやってそれを打破できるかはわかりません。

これは正しいです?

編集:どうやら私の質問は曖昧すぎると考える人もいます。

<input type="text" value="<script>alert(0)</script>">は実行されません。したがって、_"_を使用せずに使用を中止することは不可能です。

これは正しいです?

15
KaekeaSchmear

あなたが尋ねている質問は本当に2つあります(または少なくとも解釈できます)。

  1. 引用符が許可されていない場合、_input[type="text"]_の引用符付きのvalue属性を挿入できますか?

  2. 引用が禁止されている場合、要素の任意の引用属性を挿入できますか?.

2番目は、次のように簡単に示されます。

_<a href="javascript:alert(1234);">Foo</a>
_

または

_<div onmousemove="alert(123);">...
_

最初はもう少し複雑です。

HTML5

HTML5仕様 によると:

属性値は、テキストと文字参照の混合ですが、あいまいなアンパサンドをテキストに含めることはできないという追加の制限があります。

これは、引用符で囲まれた属性でさらに洗練されています。

属性名、0個以上のスペース文字、単一のU + 003D EQUALS SIGN文字、0個以上のスペース文字、単一の "" "(U + 0022)文字、属性値上記の属性値の要件に加えて、リテラルのU + 0022 QUOTATION MARK文字( ")を含めてはならず、最後に2番目の単一の" ""(U + 0022)文字を続けてください。

つまり、「あいまいなアンパサンド」(結果が有効な文字参照でない場合は_&[a-zA-Z0-9]+;_)と引用符文字を除くすべての文字は、属性内で有効です。

HTML 4.01

HTML 4.01は、構文に関してHTML5よりも記述的ではありません(HTML5が最初に作成された理由の1つ)。しかし、それは これを言う を行います:

スクリプトまたはスタイルデータが属性(スタイルまたは組み込みイベント属性)の値である場合、作成者は、スクリプトまたはスタイル言語の規則に従って、値内の区切りの単一引用符または二重引用符の出現をエスケープする必要があります。また、「&」が文字参照の開始を意味しない場合は、「&」の出現をエスケープする必要があります。

これは、パーサーがすべきことではなく、作者がすべきことを言っていることに注意してください。したがって、パーサーは技術的に無効な入力を受け入れたり拒否したりすることができます(または有効になるように変更することができます)。

XML 1.0

XML 1.0 Spec は、属性を次のように定義します。

属性:: =名前Eq AttValue

ここで、AttValueは次のように定義されています。

AttValue :: = '"'([^ <&"] |リファレンス)* '"' |" '"([^ <&'] |リファレンス)*" '"

_&_はHTML5の「あいまいなアンパサンド」の概念に似ていますが、基本的には「エンコードされていないアンパサンド」を意味しています。

ただし、属性値から_<_を明示的に拒否していることに注意してください。

したがって、HTML5では許可されていますが、XML1.0では明示的に拒否されています。

どういう意味ですか

つまり、準拠でバグのないパーサーの場合、HTML5は属性の_<_文字を無視し、XMLはエラーになります。

また、準拠していてバグのないパーサーの場合、HTML 4.01は不特定の動作をする可能性があります(仕様には動作の詳細が記載されていないため)。

そして、これは問題の核心にまで及びます。以前は、HTMLは非常に緩い仕様だったため、すべてのブラウザには、不正なHTMLを処理する方法についてわずかに異なるルールがありました。それぞれがそれを「修正」しようとするか、あなたが意味したことを「解釈」しようとします。つまり、HTML5準拠のブラウザは<input type="text" value="<script>alert(0)</script>">でJSを実行しませんが、HTML 4.01準拠のブラウザが実行しないことは言うまでもありません。また、XMLまたはHTML5パーサーにバグが存在しないために実行されないことは言うまでもありません(ただし、これはかなり重大な問題になります)。

[〜#〜] that [〜#〜]が、OWASP(およびほとんどのセキュリティ専門家)が英数字以外のすべての文字または_&<"_属性値の内部。そうするのに費用はかかりません。ブラウザのパーサーが値を解釈する方法を知るの追加のセキュリティのみです。

あなたは持っていますか?番号。しかし、多層防御はそうするための費用がないので、潜在的な利益はそれだけの価値があることを示唆しています。

24
ircmaxell

ユーザーがデータを送信するときは、期待どおりのものが提供されていることを確認する必要があります。

たとえば、数値が必要な場合は、 送信されたデータが数値であることを確認してください です。 ユーザーデータを他のタイプにキャストする もできます。送信されたものはすべて最初は文字列のように扱われるため、既知の数値データを整数または浮動小数点数に強制すると、サニタイズが迅速かつ簡単になります。

HTMLコンテンツがないはずのフィールドに実際にはHTMLが含まれていないことを確認する必要があります。この問題に対処する方法はいくつかあります。

htmlspecialchars でHTML入力のエスケープを試すことができます。 HTMLを無効にするために htmlentities を使用しないでください。これは、エンコードする必要があると思われるアクセント付きおよびその他の文字のエンコードも実行するためです。

可能なHTMLを削除してみてください。 strip_tags はすばやく簡単ですが、ずさんな動作もします。 HTML Purifier は、すべてのHTMLを取り除き、タグと属性の選択的なホワイトリストを通過させるという、より徹底的な作業を行います。

OWASP PHP Filters を使用できます。使用方法は非常に簡単で効果的です。

filter extension を使用できます。これは、ユーザー入力をサニタイズする包括的な方法を提供します。

以下のコードは、文字列からすべてのHTMLタグを削除します:

$string = "<h1>Hello, World!</h1>";
$new_string = filter_var($string, FILTER_SANITIZE_STRING);
// $new_string is now "Hello, World!"

以下のコードは、変数の値が有効なIPアドレスであることを確認します:

$ip = "127.0.0.1";
$valid_ip = filter_var($ip, FILTER_VALIDATE_IP);
// $valid_ip is TRUE

$ip = "127.0.1.1.1.1";
$valid_ip = filter_var($ip, FILTER_VALIDATE_IP);
// $valid_ip is FALSE

電子メールアドレスのサニタイズと検証:

<?php
$a = '[email protected]';
$b = 'bogus - at - example dot org';
$c = '([email protected])';

$sanitized_a = filter_var($a, FILTER_SANITIZE_EMAIL);
if (filter_var($sanitized_a, FILTER_VALIDATE_EMAIL)) {
    echo "This (a) sanitized email address is considered valid.\n";
}

$sanitized_b = filter_var($b, FILTER_SANITIZE_EMAIL);
if (filter_var($sanitized_b, FILTER_VALIDATE_EMAIL)) {
    echo "This sanitized email address is considered valid.";
} else {
    echo "This (b) sanitized email address is considered invalid.\n";
}

$sanitized_c = filter_var($c, FILTER_SANITIZE_EMAIL);
if (filter_var($sanitized_c, FILTER_VALIDATE_EMAIL)) {
    echo "This (c) sanitized email address is considered valid.\n";
    echo "Before: $c\n";
    echo "After:  $sanitized_c\n";    
}
?>

参照:

最良のものは何ですかPHP入力サニタイジング関数?

http://code.tutsplus.com/tutorials/sanitize-and-validate-data-with-php-filters--net-2595

https://security.stackexchange.com/q/42498/71827

http://php.net/manual/en/filter.examples.sanitization.php

6

その人はクロスサイトスクリプティング攻撃について言及していると思います。彼らはこれをphp、security、xssとしてタグ付けしました

例をとる

<input type="text" value=""><script>alert(0)</script><"">

上記のコードは警告ボックスのコードを実行します。

<?php $var= "\"><script>alert(0)</script><\""; ?>
<input type="text" value="<?php echo $var ?>">

これにより、警告ボックスも実行されます。これを解決するには、 "、<>、および安全のためにさらにいくつかをエスケープする必要があります。PHPには調べる価値のあるいくつかの関数があり、それぞれに浮き沈みがあります。

htmlentities() - Convert all applicable characters to HTML entities
htmlspecialchars() - Convert special characters to HTML entities
get_html_translation_table() - Returns the translation table used by  htmlspecialchars and htmlentities
urldecode() - Decodes URL-encoded string

注意する必要があるのは、変数を渡していて、エラーを発生させてそれを発生させる方法があることです。エラーが発生した場合に実行可能な方法でデータがフォーマットされていないことを確認することをお勧めします。しかし、あなたが引用できない引用符がない場合はあなたは正しいですが、あなたや私が現時点でそれを実現する方法を理解できない方法があります。

3
webternals

あなたの質問が「どんなタイプのxss攻撃が可能か」であるなら、あなたはそれをよりググる。入力をサニタイズする必要がある理由の例をいくつか残しておきます

  • 入力がecho '<input type="text" value="$var">'によって生成された場合、単純な'がそれを壊します。

  • PHP=ページの入力がプレーンHTMLの場合、value=<?php deadly_php_script ?>はそれを壊します

  • これがHTMLファイルのプレーンHTML入力である場合、二重引用符の変換で十分です。

ただし、他の特殊記号(<>など)を変換することをお勧めします。入力は、サーバーに保存される情報を入力するために行われ、別のページに転送されるため、これらのファイルを破壊する可能性があるものを確認する必要があります。次の設定があるとします。

index.html:

<form method=post action=getinput.php> <input type="text" name="xss"> <input type="submit"></form>

getinput.php:

echo $_POST['xss'];

入力値;your_deadly_php_scriptはそれを完全に壊します(その場合、サーバー側をサニタイズすることもできます)

それでも不十分な場合は、質問に関する詳細情報を提供して、コードの例をさらに追加してください。

3
bigbobr

$ var = "><script>alert(0);</script>は機能します...引用符を閉じることができる場合は、タグを閉じて別のタグを開くことができます...しかし、私は正しいと思います。引用符を閉じないと、注入は不可能です。 ..

0
mathieu