0

そのため、変数 ID は URL から取得され、何かが通過しないように取り除かれます。

次に、$ok が数値であるかどうかを確認する IF ステートメントがあります。数値である場合は、以下の SQL クエリで使用される $id として参照されます。

アクセスを防止するためにコーディングする場合、他にどのような予防措置を講じる必要がありますか?

$ok=mysql_real_escape_string(htmlspecialchars(stripslashes(trim(strip_tags(strtoupper($_GET['id']))))));
if(is_numeric($ok)){$id=$ok;}
$sql=mysql_query("SELECT * FROM games WHERE ID = '$id'");
<...more code here...>
4

5 に答える 5

9

SQL インジェクションから保護する良い方法は、準備済みステートメントを使用することです: http://php.net/manual/de/mysqli.quickstart.prepared-statements.php

例えば:

$mysqli = new mysqli("example.com", "user", "password", "database");

// Note the '?', it's a placeholder
$stmt = $mysqli->prepare("SELECT * FROM games WHERE ID = ?"); 

// Providing an actual value for the placeholder
$stmt->bind_param("i", $_GET['id']);
$stmt->execute()

ステートメントは安全でないデータなしでデータベースに送信され、追加のステップで提供され、DB によって安全に挿入されるため、これは SQL インジェクションから保護されます。

于 2013-01-09T22:06:21.307 に答える
4

Mysql は推奨されておらず、サポートもメンテナンスもされていません。mysql_ 関数の実行は、SQL インジェクションなどの攻撃に対して脆弱です mysql に慣れている場合は、mysqli に簡単に移行できます。PDO も使用できます。

mysqli の i は「改善された」という意味です。いくつかの新しい機能がサポートされているため、改善されています。

2 つのインターフェース: http://php.net/manual/en/mysqli.quickstart.dual-interface.php

1)手続き型(mysqlを使用しているため、おそらく慣れているでしょう)

$mysqli = mysqli_connect("example.com", "user", "password", "database");
   if (mysqli_connect_errno($mysqli)) {
   echo "Failed to connect to MySQL: " . mysqli_connect_error();
}

2) オブジェクト指向。オブジェクトには呼び出し可能なメソッドとプロパティがあります。

(例はこちら... " new " mysqli は、新しい mysqli オブジェクトを作成しています。この特定のオブジェクトには、呼び出すことができる "connect_errno" メソッドがあります。)

$mysqli = new mysqli("example.com", "user", "password", "database");
  if ($mysqli->connect_errno) {
  echo "Failed to connect to MySQL: " . $mysqli->connect_error;
}

準備済みステートメント: http://php.net/manual/en/mysqli.quickstart.prepared-statements.php

ストアド プロシージャ: http://php.net/manual/en/mysqli.quickstart.stored-procedures.php

複数のステートメント: http://php.net/manual/en/mysqli.quickstart.multiple-statement.php

そして、他のいくつかの改善された機能。

于 2013-01-09T22:08:40.480 に答える
2

SQL インジェクションについてまったく心配したくない場合は、準備済みステートメントを使用してください。

PHP で mysqli API と準備済みステートメントを使用すると、コードは次の例のようになります。手続き型スタイルを使用していることに注意してください。オブジェクト指向のスタイルも利用できます。

<?php
$link = mysqli_connect("localhost", "user", "password", "dbname");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

// taken from your example
$id = trim(strip_tags(strtoupper($_GET['id'])));

if(!is_numeric($id)) {
    die('BAD id');
}

/* create a prepared statement */
if ($stmt = mysqli_prepare($link, "SELECT * FROM games WHERE ID =?")) {

    /* bind parameters for markers */
    mysqli_stmt_bind_param($stmt, "s", $id);

    /* execute query */
    $result = mysqli_stmt_execute($stmt);

    /* bind result variables */
    mysqli_stmt_bind_result($stmt, $col1, $col2, ...);


   /* fetch values */
   while (mysqli_stmt_fetch($stmt)) {
       printf("%s %s\n", $col1, $col2, ...);
   }

    /* close statement */
    mysqli_stmt_close($stmt);
}

/* close connection */
mysqli_close($link);

$idSQL 構文とは別に、例のようなクエリ データを保持する準備済みステートメント。したがって、データを SQL 構文として解析することはできません。これが推奨される方法です。

PHP と MySQL でプリペアド ステートメントを使用する場合は、mysqli API または PDO_MySQL API を使用する必要があります。いずれにせよ、PHP 用の「古き良き」mysql API は非推奨であり、開発されていないため、それらのいずれかに変更する必要があります。

于 2013-01-09T22:03:49.563 に答える
2

はい。

パラメーターをバインドしていない場合は、SQL インジェクションに対して無防備です。

信頼できないデータを使用して実行可能な SQL コードを作成している場合は、SQL インジェクションに対して無防備です。

PDO や mysqli を使用するだけでは十分ではありません。バインドされたパラメーターを使用する必要があります。SELECT * FROM games WHERE ID = '$id'を mysqli または PDO に渡すと、信頼できないデータからコードを構築しているため、SQL インジェクションに対して無防備になります。そのデータには、プレースホルダーとバインド パラメーターを使用する必要があります。

于 2013-01-09T22:11:33.970 に答える
1

理想的な答えは、PDO (推奨) または * からの準備済みステートメントを使用することmysqli_ですmysql_関数は PHP 5.5 で非推奨になりました。2013 年には、このようなコードを書くべきではありません。

mysql_ 関数に「行き詰まっている」可能性が低い場合 (たとえば、巨大なレガシー コードベースがあり、または PDO から変更するには費用やリスクが多すぎる場合などmysql_) mysqli_、正しい方向に進んでいます。入力に対して行っているすべての関数を使用する必要はありません。mysql_real_escape_string 実際、SQL 文字列でパラメーターを使用して引用したため、SQL インジェクション攻撃を防ぐには次の方法で十分です。

$id = mysql_real_escape_string($_GET['id']);
$sql = mysql_query("SELECT * FROM games WHERE ID = '$id'");
于 2013-01-09T22:20:57.113 に答える