PHP での mysql インジェクションを回避するには、ユーザーから取得したすべての Cookie を mysql_real_escape_string にする必要がありますか?

StackOverflow https://stackoverflow.com/questions/90517

  •  01-07-2019
  •  | 
  •  

質問

ユーザーが私のサイトにアクセスすると、スクリプトはユーザー ID とパスワードの一部を保存する 2 つの Cookie をチェックし、自動的にログインします。

Cookie エディターを使用して Cookie の内容を編集することができるため、書き込まれた Cookie に悪意のあるコンテンツを追加することは可能でしょうか。

付け加えるべきか mysql_real_escape_string (または他のもの) すべての cookie 呼び出しに影響を及ぼしますか、それともこれを許可しない何らかの組み込みプロシージャがあるのでしょうか?

役に立ちましたか?

解決

あなたは何ですか 本当に 必要なのは、そもそもハッキング可能なこれらの Cookie 値を送信しないことです。代わりに、ユーザー名とパスワード、および (秘密の) ソルトをハッシュして、それを Cookie 値として設定してはどうでしょうか?つまり:

define('COOKIE_SALT', 'secretblahblahlkdsfklj');
$cookie_value = sha1($username.$password.COOKIE_SALT);

そうすれば、Cookie の値は常に 40 文字の 16 進文字列であることがわかり、ユーザーが送り返した値をデータベース内の値と比較して、それらが有効かどうかを判断できます。

if ($user_cookie_value == sha1($username_from_db.$password_drom_db.COOKIE_SALT)) {
  # valid
} else {
  #not valid
}

mysql_real_escape_string ところで、データベースに追加のヒットが発生します (多くの人は、DB 接続と MySQL へのクエリが必要であることに気づいていません)。

アプリを変更できず、ハッキング可能な Cookie 値を使用する必要がある場合に、必要なことを行うための最良の方法は、次の方法です。 バインドされたパラメータを持つ準備されたステートメント.

他のヒント

mysql_real_escape_string の目的は、インジェクション攻撃から保護することではなく、データがデータベースに正確に保存されるようにすることです。したがって、ソースに関係なく、データベースに入る任意の文字列に対して呼び出す必要があります。

ただし、次のようにする必要があります。 また SQL インジェクションから身を守るために (mysqli または PDO 経由で) パラメーター化されたクエリを使用している。そうしないと、次のような結果になる危険があります 小さなボビー・テーブルズの学校.

mysql_real_escape_string は、SQL ステートメントに変数を挿入する前にのみ使用します。変数の一部が間違っていると、混乱するだけです。 すでに 逃げた、そしてまた逃げる。これは、初心者のブログ Web アプリでよく見られる典型的なバグです。

誰かがアポストロフィを書くと、スラッシュが追加され続け、ブログ\\\\\\\ のページが台無しになります。

変数の値自体は危険ではありません。紐やそれに似たものに紐を付けて初めて、危険な水域に迷い込み始めるのです。

ただし、クライアント側からのものは決して信用しないでください。

プリペアド ステートメントとパラメータ バインディングは常に良い方法です。

PEAR::MDB2 は、次のような準備済みステートメントをサポートしています。

$db = MDB2::factory( $dsn );

$types = array( 'integer', 'text' );
$sth = $db->prepare( "INSERT INTO table (ID,Text) (?,?)", $types );
if( PEAR::isError( $sth ) ) die( $sth->getMessage() );

$data = array( 5, 'some text' );
$result = $sth->execute( $data );
$sth->free();
if( PEAR::isError( $result ) ) die( $result->getMessage() );

これにより、適切なデータと事前に設定された量の変数のみがデータベースに取り込まれるようになります。

もちろん、ここまで作業を進める前にデータを検証する必要がありますが、ステートメントの準備は最後に行うべき検証です。

mysql_real_escape_string を実行する必要があります 何でも それは潜在的に有害である可能性があります。ユーザーが変更できるタイプの入力は決して信頼しないでください。

私はあなたに同意します。Cookie を変更して悪意のあるデータを送信する可能性があります。

Cookie を使用する前に、Cookie から取得した値をフィルタリングすることをお勧めします。経験則として、私は改ざんされる可能性のあるその他の入力をすべてフィルタリングします。

そうですね、ユーザー アカウントの作成/更新時にハッシュを保存し、ログインが開始されるたびに、サーバーに投稿されたデータをハッシュし、そのユーザー名のデータベースに保存されているデータと比較します。

(ゆるいphpで思いつきました - 疑似コードとして扱います):

$usernameFromPostDbsafe = LimitToAlphaNumUnderscore($usernameFromPost);
$result = Query("SELECT hash FROM userTable WHERE username='$usernameFromPostDbsafe' LIMIT 1;");
$hashFromDb = $result['hash'];
if( (sha1($usernameFromPost.$passwordFromPost.SALT)) == $hashFromDb ){
    //Auth Success
}else{
   //Auth Failure
}

認証が成功した後、ハッシュを $_SESSION またはキャッシュされた認証されたユーザー名/ハッシュのデータベース テーブルに保存できます。次に、ハッシュをブラウザー (Cookie などで) に送り返します。これにより、後続のページの読み込み時にハッシュがサーバーに送り返され、選択したセッション ストレージに保持されているハッシュと比較されます。

mysql_real_escape_string は時代遅れです...最近では、代わりにパラメーター バインディングを使用する必要があります。

私が言及していたことを言及して詳しく説明します 準備されたステートメント そして、mysl_real_escape_string だけでは不十分な場合があることを示す記事へのリンクを提供します。 http://www.webappsec.org/projects/articles/091007.txt

実際の HTML コードが誤って出力されることも防ぐため、mysql_real_escape_string の代わりに htmlentities($input, ENT_QUOTES) を使用することをお勧めします。もちろん、mysql_real_escape_string と htmlentities を使用することもできますが、なぜ使用するのでしょうか?

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top