1

ユーザー アカウントを持つ Web サイトを作成しています。ユーザーアカウントごとに、ユーザーは個人情報の更新、ブログの作成などを行うことができます。ユーザーがブログを編集したい場合、次のフォームがあります (これは簡易版です)。

<form action="goToThisPage.php" method="get">
    <input type="hidden" name="blogID" value="4" />
    <input type="text" name="blogTitle" value="" />
    <textarea name="blogContent"></textarea>
    <input type="submit" name="submit" value="Update Blog" />
</form>

ご覧のとおり、このユーザーの blogID は 4 であるため、レコードを更新すると、ブログ テーブルが ID 4 で更新されます。firebug またはその他のスプーフィング手法を使用して、ユーザーはこの ID を 8 などに変更できます。レコード 8 を更新します。これは、他の誰かのエントリである可能性があります。

どうすればこれを防ぐことができますか? これまでに 2 つの方法を考えてきましたが、どの方法が最良のアイデアだと思いますか (または別の方法を提案しますか)。

  1. ID をランダムな文字列でエンコードし、送信された文字列をデコードして、正しい ID を取得します。
  2. 数値のままにしておき、データベースクエリで更新されたレコードを確認します。

私は明らかにデータベースクエリを制限したいと思っています.IDをエンコードすることで、より良いオプションだと思います. 皆さんはどう思いますか?

前もって感謝します

4

4 に答える 4

2

Web アプリケーションを構築するときは、次のことを前提としていると最も満足できます。

  1. クライアント (つまり、ブラウザー) は信頼されません。サーバーに送信されたデータが悪意のある人物によって送信されたと仮定します。

  2. アプリケーションはステートレスです。リクエスト X の前にリクエスト Y が発生することを意図したからといって、それらがそのように発生したと想定することはできません。

オプション 2 の方が適しています。認証されたユーザーがブログ投稿を更新する必要があり、ユーザーにその更新を承認する必要がある場合は、ブログ投稿を更新するコードでこれらの要件を確認してください。おそらく、データベース クエリが多すぎても問題は発生しません。

于 2010-06-27T22:24:12.297 に答える
0

Ned Batchelder の回答には、覚えておくべき非常に重要なことがいくつか含まれています。繰り返しません。

いくつかの実装の詳細について概説します。

仮定:

  • blog テーブルには、投稿を所有または作成したユーザーの userId を保持する ownerId という列があります。
  • ある種のユーザーログインシステムがあり、userId がセッションのどこかに保存されています。

ユーザーが自分の投稿のみを更新できるようにする最も簡単な方法は、事前に確認することです。

<?PHP
$blog = get_blog_by_id($_POST['blogId']);
if ($blog['ownerId'] != $_SESSION['userId']){
   die("You're a BAD MAN.  Cut it out!");
}
$blog['blogContent'] = $_POST['blogContent'];
$blog['blogTitle'] = $_POST['blogTitle'];

update_blog($blog); //escapes any strings, and runs an update.

なんらかの理由で、更新する前にブログ投稿をデータベースからプルしたくない場合は、いつでも次のようにすることができます。

<?PHP
$title = mysql_real_escape_string($_POST['blogTitle']);
$content = mysql_real_escape_string($_POST['blogContent']);
$id = mysql_real_escape_string($_POST['blogId']);
$userId = $_SESSION['userId'];

$sql = "UPDATE blog SET blogTitle='$title', blogContent='$content' WHERE blogId = '$id' AND ownerId = $user_id";

mysql_query($sql);

これにより、最初のルックアップを節約できますが、現在のユーザーがブログを所有していない場合、基本的に何も表示されずに失敗します。これは、WHERE 条件がゼロ レコードに一致するためです。

于 2010-06-27T23:31:27.377 に答える
0

HTMLレベルで何かをするのは時間の無駄です。PHP は単純にこれを許可すべきではありません。つまり、エントリが実際に変更を発行したユーザーに属しているかどうかを確認します。

于 2010-06-27T22:20:24.313 に答える
0

これには多くの方法がありますが、そのうちのいくつかは次のとおりです。

  1. ID とともに秘密の文字列をハッシュ (sha1 など) し、送信時にハッシュを検証します。一致しない場合は拒否します。

  2. ユーザーがアクセスできるすべてのブログをセッション変数に保存します。送信時に、送信されたブログがセッション配列にあるかどうかを確認し、そうでない場合は拒否します。

  3. データベースクエリを制限したいと言ったので、更新クエリに別の where 基準を追加するだけです。もちろん、実際のクエリは db スキーマに依存します。

    UPDATE blogs SET ... snip ... WHERE BLOG id = FORM_SUBMITTED_ID AND blog.owner = CURRENT_USER

    これにより、ユーザーが実際の所有者である場合にのみ更新が行われるようになります。

于 2010-06-27T22:59:23.143 に答える