web-dev-qa-db-ja.com

PHPでコードインジェクション攻撃を防ぐ方法は?

私は少し混乱していますが、PHPには非常に多くの関数があり、一部はこれを使用し、一部はそれを使用しています。使用する人:htmlspecialchars()htmlentities()strip_tags()など

正しいものはどれですか、あなたは普段何を使っていますか?

これは正しいですか(もしあれば、より良いものを教えてください):

_$var = mysql_real_escape_string(htmlentities($_POST['username']));
_

この行は、MySQLインジェクションとXSS攻撃を防ぐことができますか?

ところで、XSS攻撃とMySQLインジェクション以外に注意する必要がある他のものはありますか?

[〜#〜] edit [〜#〜]

結論:

データベースに文字列を挿入する場合、htmlentitiesを使用する必要はなく、_mysql_real_escape_string_を使用するだけです。データを表示するとき、htmlentities()を使用します。それはあなたがすべて意味するものですか??

要約:

  • _mysql_real_escape_string_は、データベースへの挿入時に使用されます
  • htmlentities()は、Webページにデータを出力するときに使用されます
  • htmlspecialchars()はいつ使用されますか?
  • strip_tags()はいつ使用されますか?
  • addslashes()はいつ使用されますか?

誰かが疑問符を記入できますか?

52
bbtang
  • _mysql_real_escape_string_は、データベースへの挿入時に使用されます
  • htmlentities()は、Webページにデータを出力するときに使用されます
  • htmlspecialchars()はいつ使用されますか?
  • strip_tags()はいつ使用されますか?
  • addslashes()はいつ使用されますか?

htmlspecialchars()はいつ使用されますか?

htmlspecialcharsは、htmlentitiesとほぼ同じです。違い:文字エンコーディング。

両方とも、タグを開くために使用される_<_、_>_、_&_などの制御文字をエンコードします。htmlentitiesは、ウムラウト、ユーロ記号、そのような。 WebサイトがUTFの場合はhtmlspecialchars()を使用し、そうでない場合はhtmlentities()を使用します。

strip_tags()はいつ使用されますか?

htmlspecialchars/entitiesは特殊文字をエンコードするため、表示されますが、解釈されません。 _strip_tags_それらを削除します。

実際には、何をする必要があるかによって異なります。

例:フォーラムをコーディングし、ユーザーがコンテンツを投稿できるようにテキストフィールドを提供します。悪意のある人は試してみてください:

_pictures of <a href="javascript:void(window.setInterval(function () {window.open('http://evil.com');}, 1000));">kittens</a> here
_

何もしなければ、リンクが表示され、リンクをクリックした被害者は多くのポップアップを取得します。

出力をhtmlentity/htmlspecialcharにすると、テキストはそのまま存在します。 strip_tagする場合、タグを削除して表示するだけです:

_pictures of kittens here
_

場合によっては、_<b>_(_strip_tags_は特定のタグをそこに残すことができます)のように、いくつかのタグをそこに残して混合物が必要になる場合があります。これも安全ではないため、XSSに対して完全に拡張されたライブラリを使用することをお勧めします。

まつげを追加する

PHPマニュアル)の古いバージョン を引用するには:

データベースクエリなどで引用する必要がある文字の前にバックスラッシュを含む文字列を返します。これらの文字は、一重引用符( ')、二重引用符( ")、バックスラッシュ()、NUL([〜 #〜] null [〜#〜]バイト)。

addslashes()の使用例は、データベースにデータを入力する場合です。たとえば、名前O'reillyをデータベースに挿入するには、エスケープする必要があります。 DBMS固有のエスケープ関数(MySQLの場合はmysqli_real_escape_string()、PostgreSQLの場合はpg_escape_string()など)を使用することを強くお勧めしますが、使用しているDBMSにエスケープ関数がなく、DBMSが\を使用して特殊文字をエスケープする場合、この機能を使用できます。

現在のバージョン は異なる表現です。

64
stefs

この簡単なチェックリストについて考えました。

  • 常にHTTPSを使用します。HTTPSを使用しない場合、サイトは完全に暗号化されません。いいえ、クライアント側の暗号化と送信は機能しません。考えてみてください。 無効なHTTPS証明書は、 [〜#〜] mitm [〜#〜] attackに対して脆弱になります。証明書を購入する余裕がない場合は、Let's Encryptを使用してください。
  • PHPコードからの出力、つまりユーザー入力が含まれている、またはユーザー入力が含まれている場合は、常に htmlspecialchars() を使用するほとんどのテンプレートエンジンは、これを簡単に行うのに役立ちます。
  • _php.ini_でHTTP専用フラグを使用して、スクリプトがCookieにアクセスしないようにします
  • セッション関連の問題を防止する
    • ユーザーのPHPSESSID(セッションID)をcookieの外部に決して公開しないでください。誰かが他の誰かのセッションIDを知るようになれば、簡単にできます。アカウントにログインするために使用します
    • _Remember me_関数には細心の注意を払い、多分少し警告を表示します。
    • ユーザーがサインインするときにセッションIDを更新します(または適切な場合)
    • 非アクティブなセッションのタイムアウト
  • NeverCookieを信頼しない。スクリプト/ユーザーがいつでも変更、削除、変更、作成できます。
  • SQL関連の問題を防ぐ
    • 常に準備されたステートメントを使用します。準備されたステートメントにより、ユーザー入力が個別に渡され、 SQLインジェクション が防止されます。
    • コードが失敗したときに例外をスローするようにします。何らかの理由でSQLサーバーがダウンしている場合があり、PDOなどのライブラリはデフォルトでそのエラーを無視し、ログに警告を記録します。これにより、DBから取得する変数がnullになります。コードによっては、セキュリティの問題が発生する可能性があります。
    • PDOemulateプリペアドステートメントなどのライブラリ。オフにします。
    • データベースで_UTF-8_エンコードを使用すると、事実上すべての文字を保存し、エンコード関連の攻撃を回避できます
    • クエリに何も連結しないでください$myquery = "INSERT INTO mydb.mytable (title) VALUES(" . $user_input . ")"のようなことは、SQLインジェクションの大きなセキュリティリスクがあることを意味します。
  • アップロードしたファイルを、拡張子のないランダムなファイル名で保存します。ユーザーが_.php_ファイル拡張子を持つファイルをアップロードすると、コードがそのファイルをロードするたびに実行され、ユーザーがバックエンドコードを実行できるようになります。
  • CSRF攻撃 に対して脆弱でないことを確認してください。
  • PHPコピーを常に更新して、最新のセキュリティパッチとパフォーマンスの向上を確保する
10
OverCoder

データをエンコードする必要があるシステムに入力するポイントでのみデータをエンコードします。そうしないと、実際のデータを操作したい状況に陥ります。

SQLインジェクションの場合- PHPでSQLインジェクションを防止するにはどうすればよいですか? で説明されているようにバインドされた変数を使用します(準備されたステートメントについて説明しますが、準備ではなく保護を提供するのはバインディングです)。

XSSの場合-HTMLまたはテキストのいずれかが指定された時点でHTMLに書き込む場合。ドキュメントを生成するポイントでhtmlentitiesを使用します。データベースにその形式でデータを保存することは避けます(CPUのパフォーマンス/ディスクアクセス時間が増えて問題になる書き込み/まれ/読み取りが多いシステムで可能な場合を除き、列のraw_バージョンとhtml_バージョンがあります) …またはmemcachedなどを使用します)。

ユーザーにURLの入力を許可する場合は、javascript:do_evil()が実行される有効なURIであるため、注意が必要です(たとえば、クリックされたリンクのhrefまたは(一部のブラウザーでは)srcのsrc読み込まれたばかりの画像)。

6
Quentin

htmlspecialchars()は_&_、_'_、_"_、_<_、および_>_をHTMLエンティティ形式に変換します(_&amp;_、_&quot;_など)

htmlentities()は、該当するすべての文字をHTMLエンティティ形式に変換します。

strip_tags()はすべてのHTMLおよびPHPタグを削除します。

htmlspecialchars()htmlentities()は両方とも、引用符の処理方法を示すオプションのパラメーターを取ります。詳細については、PHPマニュアルを参照してください。

strip_tags()関数は、どのタグを削除しないかを示すオプションのパラメーターを取ります。

_ $var = strip_tags ($var, '<p><br />');
_

strip_tags()関数は、問題を引き起こす可能性のある無効なHTMLタグも削除します。たとえば、strip_tags()は、次のように不適切に形成されていても、HTMLタグであると考えられるすべてのコードを削除します。

_<b I forgot to close the tag.
_
4
Faraz Kelhini

データベースに挿入するときはmysql_escape_string()を使用し、HTMLを表示するときにはhtmlentitesを使用するだけです。単純なインジェクション攻撃を防ぎたい場合はこれで十分ですが、Webアプリを開発する際に注意すべき他の多くのセキュリティ問題は間違いありません。

3
Sam152

データベースにデータを挿入するとき、またはデータベースを照会するときに、htmlentities()を使用しません。データベース内のデータがエンティティとして保存されている場合、そのデータはHTMLエンティティを理解するものにのみ役立ちます。

出力の種類ごとに異なるエスケープメカニズムを使用する必要があります。 SQL- mysql_real_escape_string() 、HTML- htmlentities() または htmlspecialchars() 、Shell- escapeshellarg() これは、「危険」な文字がそれぞれ異なるためです。出力媒体に対して安全なデータを作成する魔法の方法はありません。

2
Tom Haigh

これは古い質問だと思いますが、最近では最も多くの投票が寄せられた回答が初心者にとって誤解を招く可能性があります。

2017年現在

  1. Mysql_real_escape_stringを使用しないでください。 mysqli_real_escape_stringでさえ、データベースをSQLインジェクションから保護するには弱すぎます。これの代わりに、PDO、および同様の手法を使用する必要があります。 ( そのガイド を参照)

  2. XSS(ここで私が意味するもの:strip_tags()addslashes()htmlspecialchars()htmlentities())-ここで最も投票された答えはまだ正しいですが、私は読むことをお勧めします この記事

1
Tomasz Durda

このサイトをご覧ください PHP Security Consortium 。 PHPセキュリティ(SQLインジェクションとXSSを含む)の全体的な概要に適したサイトであることがわかりました。

1