1

ユーザーには親切にしたいのですが、誤って悪意のあるコードを入手したくありません。非常に多くの質問を見て、ホワイトリストに登録することにしたので、承認したキャラクターのみを取得します。

ユーザーに親切にして、ユーザーに多くの文字を入力させながら、悪意のあるコードから入力を安全に保つにはどうすればよいでしょうか?
私は PHP 5.3.8 で Apache を使用していますが、PDO を聞いたときはプロジェクトに深く関わっていて、変更が大きすぎるのではないかと恐れていたため、PDO を組み込んでいませんでした。

どんなアイデアでも役に立ちます!

4

2 に答える 2

3

ユーザーに出力できる場合は、悪意のある可能性のあるユーザーがコードに HTML タグを含めないようにする必要があります。たとえば、その投稿にscriptタグを含めることができた場合、投稿を読んでいるユーザーにとって非常に危険になる可能性があります. これを防ぐには、次を使用しますhtmlentities

$clean_data = htmlentities($_POST['data']);

そうすれば、<script>タグが翻訳&lt;script&gt;されて、ブラウザで表示されたときにユーザーに害が及ぶことはありません。

さて、私の投稿をデータベースに保存したい場合は、SQL インジェクションに注意する必要があります。そのクエリで私の投稿を保存しているとしましょう(はい、mysql_*関数は非推奨であるため使用しないでください。ただし、それはアイデアを説明するためだけです):

mysql_query($db, "INSERT INTO posts(data) values('$clean_data');");

いいですね ?まあ、私が嫌なら、その投稿を含めようとします:

test'); DELETE FROM posts; SELECT * FROM posts WHERE data = '

あなたのMySQLが得るものは

INSERT INTO posts(data) values('test'); DELETE FROM posts; SELECT * FROM posts WHERE data = '');

ああ。したがって、基本的に、ユーザーが投稿に引用符や二重引用符を含めないようにする必要があります。より正確には、それらをエスケープする必要があります。それは実際に使用しているライブラリに依存しますが、私が使用した廃止されたライブラリでは、次のように記述されます。

$really_clean_data = mysql_real_escape_string($db, $clean_data);
mysql_query($db, "INSERT INTO posts(data) values('$really_clean_data');");

したがって、上記の悪意のある投稿により、MySQL は受信するようになります。

INSERT INTO posts(data) values('test\'); DELETE FROM posts; SELECT * FROM posts WHERE data = \'');

さて、MySQL にとっては、そのINSERT INTO posts(data) values('test'); DELETE FROM posts; SELECT * FROM posts WHERE data = '');部分全体が正しい文字列であるため、何が起こるかはあなたが望んでいることです。

基本的に、ほとんどすべての場合にこれで十分です。ユーザー データをインタープリター (Web ブラウザー、SQL エンジン、またはその他多くのもの) にフィードするときは、そのデータをクリーニングする必要があることを覚えておいてください。使用しているライブラリに付属しています。

于 2013-02-01T16:04:27.107 に答える
2

Fabienがすでに与えた答えに追加するだけで、テキストデータ型だけがあなたが気にする必要のある項目ではありません。数字も同様に重要です。変数を型キャストすることは、それを処理する1つの方法です。例えば、

$really_clean_data = mysql_real_escape_string($db, $clean_data);
$query = "UPDATE posts SET post = '".$really_clean_data."' WHERE id = '".(int)$_POST['id']."'";

更新しようとしている投稿のID番号を含め、送信されたすべてのデータは、テキストエリアやテキスト入力エントリと同じように疑わしく、悪意のある操作に対してオープンです。整数(数値)であることがわかっている場合は、そのようにキャストできます。数値でない場合、その(int)は0としてキャストします。行0を更新できないため、SQLクエリは失敗します。

クエリを実行する前にその失敗をチェックするには、投稿されたデータをチェックして、is_numeric()関数を使用してそれが数値であるかどうかを確認できます。

if(!is_numeric($_POST['id'])){
    die("Post id is not a number.");
}

入力フィールド、特にユーザー名とパスワードのフィールドでは、最大長を設定して確認できます。例えば、

if(strlen($_POST['username']) > 24){
    $error = "username is too long";
}

あなたがそれについて創造的になることができれば、SQlインジェクションを防ぐことは実際に楽しいです!今から1年後、このページのすべてが完全に古くなり、無関係になる可能性があることに注意してください。セキュリティはプロセスであり、ステップではないので、その上にとどまります。

于 2013-02-01T16:23:21.597 に答える