3

私はphpを使用しており、mysqlサーバーでSQLクエリを実行しています。SQLインジェクションを防ぐために、私はmysql_real_escape_stringを使用しています。

また、次のように、数値のキャストに(int)を使用しています。

$desired_age = 12;
$query = "select id from users where (age > ".(int)$desired_age.")";
$result = mysql_query($query);

その仕事。

ただし、変数に大きな数値が含まれている場合、それらはintよりも大きいため、キャストは失敗します。

$user_id = 5633847511239487;
$query = "select age from users where (id = ".(int)$user_id.")";
$result = mysql_query($query);
// this will not produce the desired result, 
// since the user_id is actually being cast to int

SQLインジェクションの防止に関しては、mysql_real_escape_stringの使用を除いて、多数をキャストする別の方法(BIGINTなど)はありますか?

4

6 に答える 6

11

ユーザーIDを自分で生成する場合は、SQLインジェクションやその他の文字列の問題が発生する可能性がないため、MySQL用にキャストする必要はありません。

ユーザーが送信した値の場合は、filter_var()(またはis_numeric())を使用して、文字列ではなく数値であることを確認します。

于 2010-07-08T13:50:02.177 に答える
3

次のようなものを使用できます。

preg_replace('/[^0-9]/','',$user_id);

文字列内のすべての非数値記号を置き換えます。ただし、実際にはそうする必要はありません。$ queryがビルドされると、とにかく整数値が文字列に変換されるため、mysql_real_escape_string()を使用するだけです。

于 2010-07-08T13:55:44.660 に答える
1

サーバー側で準備され、パラメーター化されたステートメントを使用する(したがって、xyz_real_escape_string()の必要性を排除する)か、IDを文字列として扱います。MySQLサーバーには文字列<->数値変換のルールが組み込まれており、idフィールドのタイプ/構造に変更する必要がある場合は、phpコードも変更する必要はありません。(マイクロ)最適化の具体的なニーズがない限り、通常、データベース内のidフィールドの構造と値の範囲についてコードにこの種の仮定をさせる必要はありません。

$pdo = new PDO('mysql:...');
$pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );

$stmt = $pdo->prepare('SELECT age FROM users WHERE id=?');
$stmt->execute(array('5633847511239487'));
于 2010-07-08T14:13:27.817 に答える
1

入力を検証します。単にエスケープするのではなく、数値の場合は検証してください。is_numeric()のようにトリックを実行するPHP関数がいくつかあります-変​​数が数値であるか数値文字列であるかを検索します

http://www.php.net/is_numeric

于 2010-07-08T13:48:43.600 に答える
0

いくつかの研究の後、私はそのような設定に来ました

private function escapeInt($value)
{
    if (is_float($value))
    {
        return number_format($value, 0, '.', ''); // may lose precision on big numbers
    }
    elseif(preg_match('/^-?[0-9]+$/', $value))
    {
        return (string)$value;
    }
    else
    {
        $this->error("Invalid value");
    }
}

$i = 184467440737095;32ビットシステムではフロートになり、文字列にキャストすると科学的記数法に崩れるため、フロートのケースを分けてください。
そして残りの単純な正規表現

于 2012-12-12T21:41:59.840 に答える
0

変数にを掛けることも*1できます。受け入れることができる最小値と最大値を確認できます(年齢のbigintはまったくオプションではありません...それで、なぜ準備された値よりも多くの数値を許可するのですか?また、PDOもありますクエリの準備をします。

于 2014-04-18T23:40:33.727 に答える