33

PHP で $_GET 変数のデータをどのようにサニタイズしますか?

GET by で 1 つの変数のみをサニタイズしstrip_tagsます。すべてをサニタイズする必要があるかどうかはわかりません。なぜなら、前回 Postgres にデータを配置したとき、この問題は を使用することで最も簡単に解決されたからpg_prepareです。

4

5 に答える 5

86

PHP で $_GET 変数のデータをどのようにサニタイズしますか?

$_GET でデータをサニタイズしません。これは PHP スクリプトで一般的なアプローチですが、完全に間違っています*。

すべての変数は、別のタイプの文字列に埋め込む時点まで、プレーン テキスト形式のままにしておく必要があります。値を埋め込む可能性のある文字列のすべての可能なタイプをカバーできるエスケープまたは「サニタイズ」の形式はありません。

したがって、文字列を SQL クエリに埋め込む場合は、途中でエスケープする必要があります。

$sql= "SELECT * FROM accounts WHERE username='".pg_escape_string($_GET['username'])."'";

文字列を HTML に出力する場合は、次のようにエスケープする必要があります。

Cannot log in as <?php echo(htmlspecialchars($_GET['username'], ENT_QUOTES)) ?>.

最初に $_GET 配列でこれらのエスケープ手順の両方を実行した場合、何をしているのかわからない人が推奨するように:

$_GET['username']= htmlspecialchars(pg_escape_string($_GET['username']));

次に、「&」があったとき ユーザー名では、不思議なことに「&amp;」に変わります。ユーザー名にアポストロフィが含まれていると、ページ上では 2 つのアポストロフィに変わります。次に、これらの文字を含むフォームがある場合、それらを編集するときに簡単に二重エスケープを行うことになります。そのため、非常に多くの悪い PHP CMS が「O\\\\ からの新しい本」のような壊れた記事のタイトルになってしまいます。 \\\\\\\\\\\\\\\'ライリー」.

当然のことながら、変数を送信するたびに pg_escape_string または mysql_real_escape_string と htmlspecialchars を覚えておくのは少し面倒です。そのため、誰もが (誤って) スクリプトの最初の 1 か所でそれを実行したいと考えています。HTML 出力の場合、echo(htmlspecialchars(...)) を実行する短い名前の関数を定義することで、少なくとも入力を節約できます。

SQL の場合は、パラメーター化されたクエリを使用することをお勧めします。Postgres にはpg_query_paramsがあります。または、実際、あなたが言及したように準備されたステートメントです(個人的には扱いにくいと思いますが)。いずれにしても、「サニタイズ」または SQL のエスケープを忘れることができますが、HTML を含む他のタイプの文字列に埋め込む場合は、エスケープする必要があります。

strip_tags() は、HTML 表示の入力を処理する良い方法ではありません。これまで、ブラウザのパーサーは実際には、タグが何であるかを解釈する際に、思ったよりもはるかに複雑であるため、セキュリティ上の問題がありました。ほとんどの場合、代わりに htmlspecialchars() を使用するのが適切です。そのため、誰かが小なり記号を入力すると、実際には文字どおり小なり記号が表示され、テキストの半分が不思議なことに消えていることに気付くことはありません。

(*: インジェクションの問題を解決するための一般的なアプローチとして。もちろん、特定のフィールドで実行する価値のあるドメイン固有のチェックがあり、送信された値からすべての制御文字を削除するなど、実行できる便利なクリーンアップ タスクがあります。しかし、これはほとんどの PHP コーダーが意味するサニタイズではありません)。

于 2009-08-22T11:21:07.423 に答える
5

出力のサニタイズについて話している場合は、コンテンツを完全なエスケープされていない形式でデータベースに保存し、データをエコーアウトするときにエスケープすることをお勧めします( htmlspecialcharsなど)。これにより、出力のオプションが増えます。データベースコンテンツのサニタイズ/エスケープについては、この質問を参照してください。

postgres への格納に関しては、クエリの各変数でpg_escape_stringを使用して引用符をエスケープし、一般的に SQL インジェクションから保護します。

編集:

データベースにデータを保存してから取得するための私の通常の手順は次のとおりです。

  1. データベース データ エスケープ関数 (pg_escape_string、mysql_escape_string など) を呼び出して、クエリで使用される各着信 $_GET 変数をエスケープします。追加スラッシュの代わりにこれらの関数を使用すると、データベースに格納されるときにテキストに余分なスラッシュが含まれないことに注意してください。

  2. データベースからデータを取得したら、出力されたデータに対して htmlspecialchars を使用するだけで済みます。余分なスラッシュは必要ないため、ストリップスラッシュを使用する必要はありません。

于 2009-08-21T22:53:11.603 に答える
4

POST as GET だけでなく、すべてのリクエストをサニタイズする必要があります。

関数htmlentities()preg_replace()正規表現を使用した関数、またはキャストによるフィルターを使用できます。

<?
$id = (int)$_GET['id'];
?>
于 2009-08-21T23:07:59.233 に答える
2

フィルターで PHP ネイティブ関数filter_var()を使用します。FILTER_SANITIZE_STRING

例: https://www.w3schools.com/php/filter_sanitize_string.asp

于 2020-03-01T14:58:14.730 に答える