0

私はSQLインジェクションの問題で立ち往生しています。マイページには、テーブルのデータが次のように表示されます。

<input type="checkbox" name="id[]" value="<?php echo $row['id']; ?>" /><?php echo $row['data']; ?><br />

送信された値が、ページに「注入」された乱数ではなく、この特定の行の ID であることを確認するにはどうすればよいですか?

明らかに、IDがtrueを返すことを確認し始めますis_numeric()/それを通り抜けますmysql_real_escape_string().

次に、次の 2 つのオプションを考えました。

  • $row['data'] のコピーを使用して非表示の入力を追加して、ID とデータの対応を事前に確認できるようにします。mysql_query()

  • 行の ID を自動インクリメントされた数値から大きな乱数に変更して、ラッキー ヒットの可能性を下げることができました。

私はそれを間違っていますか?もっと良いアイデアはありますか?ご協力いただきありがとうございます!

4

1 に答える 1

2

できません。どちらのオプションにも根本的な欠陥があります。

  • チェックボックスの値を変更できるものは、非表示の入力の値を非常にうまく変更できます。
  • 「ランダム ID」は、 Dev Tools、Firebug、または同様のツールで引き続き表示できます。

ユーザーがどのようにデータを送信したかを心配する代わりに、データが有効かどうか、およびユーザーが特定のアクションに対する許可を持っているかどうかを心配する必要があります。


また、16進数と指数表記is_numericに戻るので、私のお気に入りではありません。キャストを確認するか、単にキャストtrueすることをお勧めします。ctype_digit(int)

if (!isset($_POST['id'])) die('invalid data');
$id = (int) $_POST['id'];
if ($id == 0) die('invalid id');

数値以外の文字列は変換され0、自動インクリメント フィールドは通常1、最初の値になります。が有効な値である場合0は、上記のコードを微調整する必要があります。

if (!isset($_POST['id']) || !ctype_digit($_POST['id'])) die('invalid data');
$id = (int) $_POST['id'];

その後、指定された ID が DB に存在するかどうかを確認します。適切な許可チェックを行うだけです。


サーバーがどのようにデータを取得したかは関係ありません。重要なのは、データが有効であり、ユーザーが特定の操作を実行する権限を持っていることです。フロントエンド/インターフェースで行うことはすべて、ハッカーや経験豊富な Web 開発者が簡単に変更および操作できます。

許可されていないアクセスのストリングを再設定し、DB の整合性を維持することに集中してください。リクエストが自分のページから行われているのか、改ざんされたページから行われているのか、端末から行われているのかは関係ありません。すべてのヘッダーと投稿されたデータを簡単に再現して、自分のページからリクエストが行われたように見せることができます。


結局のところ、これを「SQL インジェクション」と呼べるかどうかはわかりません。アプリケーションの関数には、整数値を含む入力が必要です。あとは、必要な入力が提供され、有効かどうかを確認するだけです。すべてのユーザー入力は、安全でないものとして扱い、適切に検証して、クエリにスローする前にエスケープする必要があります。

また、値のエスケープをうまく処理するPDOを調べてください。mysql_*拡張機能と関数は非推奨であり、mysql_real_escape_string人的ミスが非常に発生しやすいものです。

SQL インジェクションの防止に関しては、質問のコメントにあるリンクされたスレッドをよく読んでください。

于 2013-08-21T00:39:21.163 に答える