5

私は新しいWebアプリ、LAMP環境を構築しています...すべてのテキストベースのフィールド(HTMLフィールドではなく、電話、名前)のユーザーの入力検証(もちろん+準備されたstmt)に対してpreg_matchが信頼できるかどうか疑問に思っています、姓など)。

たとえば、従来の「メール フィールド」の場合、入力を次のようにチェックすると、次のようになります。

$email_pattern = "/^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)" .
    "|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}" .
    "|[0-9]{1,3})(\]?)$/";

$email = $_POST['email'];
if(preg_match($email_pattern, $email)){
    //go on, prepare stmt, execute, etc...
}else{
    //email not valid! do nothing except warn the user
}

SQL/XXS インジェクションに対して安らかに眠ることができますか?

私は正規表現を可能な限り制限的に書いています。

編集:すでに述べたように、私はすでに準備済みのステートメントを使用しています。この動作はテキストベースのフィールド(電話、電子メール、名前、姓など)専用であるため、HTMLを含めることはできません(HTMLフィールドの場合) 、私は HTMLpurifier を使用します)。

実際、私の使命は、regexp-white-list と一致する場合にのみ入力値を渡すことです。それ以外の場合は、ユーザーに戻します。

ps :: mysql_real_escape_strings のないものを探しています。おそらくプロジェクトは次の将来に Postgresql に切り替わるので、クロスデータベースの検証方法が必要です ;)

4

7 に答える 7

8

正規表現でフィルタリングできるかどうかは、正規表現によって異なります。SQL ステートメントで値を使用する場合、正規表現は何らかの方法で and を許可'しない必要があり"ます。HTML 出力で値を使用したいが XSS を恐れている場合は、正規表現<で ,>および".

それでも、繰り返し言われているように、あなたは正規表現に頼りたくありませんSQL ステートメントにはmysql_real_escape_string()または準備済みステートメントを使用し、HTML コンテキストで出力する場合は値にhtmlspecialchars()を使用します。

コンテキストに応じてサニタイズ機能を選択します。一般的な経験則として、何が危険で何が危険でないかは、あなたよりもよく知っています。


編集、編集に対応するために:

データベース

プリペアド ステートメント == mysql_real_escape_string()すべての値に入力します。本質的にまったく同じことですが、プリペアド ステートメントのバリアントでパフォーマンスが向上し、値の 1 つで関数を誤って使用することを忘れることができません。ただし、準備されたステートメントは、正規表現ではなく、SQL インジェクションから保護するものです。正規表現は何でもかまいませんが、準備されたステートメントに違いはありません。

「クロスデータベース」アーキテクチャに対応するために正規表現を使用することはできませんし、試みるべきではありません。繰り返しますが、通常、システムは自分にとって何が危険で何が危険でないかを、あなたよりもよく知っています。準備されたステートメントは優れており、それらが変更と互換性がある場合は、安らかに眠ることができます. 正規表現なし。

そうでなく、そうしなければならない場合は、MySQL アーキテクチャではmysql_real_escape_string()にマップされ、PostgreSQL アーキテクチャでは PostgreSQL のそれぞれのメソッドにマップされる、カスタム$db-> e​​scape() のような抽象化レイヤーをデータベースに使用します。 (どれが手に負えないかわかりません。申し訳ありませんが、PostgreSQLを使用したことはありません)。

HTML

HTML Purifier は、HTML 出力をサニタイズするための優れた方法です (ホワイトリスト モードで使用する場合、これは付属の設定です) が、purify( )は非常にコストがかかります。これは、全体を解析し、完全性を目指して強力なルール セットを介して操作するためです。したがって、HTML を保持する必要がない場合は、htmlspecialchars()を使用することをお勧めします。しかし、繰り返しになりますが、この時点では、正規表現はエスケープとは何の関係もなく、何でもかまいません。

セキュリティに関する補足事項

実際、私の使命は、regexp-white-list と一致する場合にのみ入力値を渡すことです。それ以外の場合は、ユーザーに戻します。

これはあなたのシナリオには当てはまらないかもしれませんが、一般的な情報として: 「不正な入力をユーザーに返す」という哲学は、反射型 XSS攻撃にさらされる危険性があります。ユーザーは常に攻撃者であるとは限らないため、ユーザーに物を返すときは、すべて同じようにエスケープするようにしてください。心に留めておくべきことがあります。

于 2010-04-12T14:45:03.073 に答える
5

SQL インジェクションの場合、 のような適切なエスケープを常に使用する必要がありますmysql_real_escape_string。最良の方法は、省略を防ぐために準備済みステートメント(または ORM) を使用することです。 あなたはすでにそれらをしました。

残りは、アプリケーションのロジックによって異なります。正しい情報が必要なため、バリデーションとともに HTML をフィルタリングすることもできますが、私は XSS から保護するためのバリデーションは行っておらず、業務上のバリデーションのみを行っています*。

一般的なルールは、「入力をフィルター/検証し、出力をエスケープする」です。そのため、HTML タグを防ぐために、記録するものではなく、表示するもの (またはサードパーティに送信するもの) をエスケープします。

* それでも、人の名前やメール アドレスには、< >

于 2010-04-12T14:42:31.523 に答える
3

検証とは、入力データを特定のアプリケーションの期待値に適合させることです。

インジェクションは、生のテキスト文字列を取得し、適切なエスケープなしで別のコンテキストに配置することと関係があります。

これらは 2 つの完全に別個の問題であり、異なる段階で別々に検討する必要があります。入力が読み取られるとき (通常はスクリプトの開始時) に検証を行う必要があります。エスケープは、SQL 文字列リテラル、HTML ページ、または一部の文字が範囲外の意味を持つその他のコンテキストなどのコンテキストにテキストを挿入した瞬間に実行する必要があります。

これら 2 つのプロセスを混同してはなりません。また、2 つの問題を同時に処理することはできません。「サニタイゼーション」という言葉は、両方の混合を意味するため、それ自体がすぐに疑わしい. 入力は「サニタイズ」してはならず、アプリケーションの特定のニーズに適しているかどうかを検証する必要があります。後で、それらが HTML ページにダンプされる場合は、途中で HTML エスケープする必要があります。

スクリプトの開始時にすべてのユーザー入力に対して SQL または HTML エスケープを実行するのはよくある間違いです。「セキュリティ」に焦点を当てたチュートリアル (愚か者によって書かれたもの) でさえ、これを行うようにアドバイスすることがよくあります。結果は常に大きな混乱であり、時には依然として脆弱です.

電話番号フィールドの例では、文字列に数字のみが含まれていることを確認すると、HTML インジェクションに使用できないことも確実に保証されますが、これは依存すべきではない副作用です。入力段階では、電話番号についてのみ知る必要があり、HTML でどの文字が特殊であるかを知る必要はありません。HTML テンプレート出力ステージは、文字列があることのみを認識している必要があります (したがって、常にそれを呼び出す必要がありますhtmlspecialchars())。数値のみが含まれていることを認識している必要はありません。

ちなみに、これは非常に悪い電子メール検証正規表現です。とにかく、正規表現は電子メールの検証には優れたツールではありません。それを適切に行うのはとてつもなく難しいですが、これは非常に多くの完全に有効なアドレスを拒否し+ます。電子メール アドレスを自由に使用することが最善です。.museum.travel

于 2010-04-12T14:57:25.763 に答える
2

番号。

いいえ。

NOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO。

行う。いいえ。使用する。正規表現。為に。これ。これまで。

SQL インジェクションを検出する正規表現

Java - SQL インジェクションを防ぐためのエスケープ文字列

于 2010-04-12T14:42:11.317 に答える
1

正規表現が得意な場合: はい。しかし、あなたの電子メール検証正規表現を読むと、いいえと答えなければなりません。

最良の方法は、フィルター関数を使用してユーザー入力を比較的安全に取得し、これらの関数で何か壊れたものが見つかった場合に備えて PHP を最新の状態にすることです。生の入力がある場合、これらのデータの処理内容に応じて、いくつかのことを追加する必要があります: メールと http ヘッダーの \n と \r を削除し、html タグを削除してユーザーに表示し、パラメーター化されたクエリを使用してそれをデータベース。

于 2010-04-12T15:02:56.850 に答える
1

データベースにデータを挿入する前に、データをエスケープする必要があります。ユーザー入力の検証は、SQL インジェクションに対する最善の保護を行うための賢明な方法ですが、準備されたステートメント (データを自動的にエスケープする) か、データベースのネイティブのエスケープ機能を使用してエスケープします。

于 2010-04-12T14:39:53.787 に答える
1

PHP 関数 mysql_real_escape_string() があります。これは、安全のために mysql データベースに送信する前に使用する必要があると思います。(また、読みやすいです。)

于 2010-04-12T14:42:11.660 に答える