-1

このPHPページを取得しました。問題は、アカウントまたはキャラクター名が有効かどうかをチェックしていないことです。

PS.: アカウントはテーブル アカウントの列です キャラクター名はテーブル プレイヤーの列です

どうすれば確認できますか?

<?php
    function anti_injection($sql)
    {
        $sql = preg_replace(sql_regcase("/(from|select|insert|delete|where|drop table|show tables|#|\*|--|\\\\)/"),"",$sql);
        $sql = trim($sql);
        $sql = strip_tags($sql);
        $sql = addslashes($sql);
        return $sql;
    }

    $accountorname = anti_injection($_POST['accountorname']);
    $gamecode = $_POST['gamecode'];
    $category = $_POST['category'];
    $premiumpoints = anti_injection($_POST['premiumpoints']);

    switch ($category) {
        case 'accountname':
            $insertquery = "INSERT INTO gamecodes (gamecode, accountname, premium_points, alreadyused) VALUES ('$gamecode','$accountorname',$premiumpoints,'N')";
            break;
        case 'charactername':
            $insertquery = "INSERT INTO gamecodes (gamecode, accountname, premium_points, alreadyused) 
                    SELECT '$gamecode',accounts.name,$premiumpoints,'N' 
                    FROM accounts 
                    JOIN players
                    ON accounts.id = players.account_id 
                    WHERE players.name = '$accountorname'";
            break;
    }

    $result = mysql_query($insertquery);
?>

あなたの助けが必要です :)

4

3 に答える 3

1

ここで正しい線に沿って考えていることは素晴らしいことです。Web サイトがハッキングされる最大の原因は、おそらく SQL インジェクションです。シンプルなものから非常にシンプルなものまで、物事が適切であることを確認するには、実際にはいくつかの手順があります。それらは次のようになります。

簡単な事

ユーザーが提供する変数 (例: $_GET、$_POST、$_COOKIE、$_SERVER など) は信頼されるべきではありません。

mysql_* を使用している場合、次のいずれかを確実に実行すると、90% のケースで有効になります。

 $safe_number = (int)$_GET['number']; // forces safe_number to be an integer

 $safe_string = mysql_real_escape_string($_GET['string']); // ensure that the string doesn't have any characters in that will trip up mysql.

もう少し複雑なこと

SQL には準備済みステートメントを使用します。mysql_* 関数 ( http://www.php.net/manual/en/function.mysql-query.php ) は多くの人に使用されていますが、プリペアド ステートメントをサポートしていないため、実際には適切ではありません。

http://www.php.net/manual/en/mysqli.prepare.phpを読み、代わりにこれを使用する必要があります。つまり、mysql に「この変数は整数です」と伝えると、mysql がそれを処理してくれます。

多くの人が PDO ( http://php.net/manual/en/book.pdo.php ) の使用を推奨しています。これは、必要に応じて mysql とは異なるデータベースを簡単に操作できるためです。

何でも – mysqli または PDO、mysql_* ではありません。

于 2013-06-18T21:29:10.967 に答える
1

アカウントとキャラクターの確認

アカウントまたはキャラクター名が有効かどうかはチェックしていません。

キャラクター名

switch ($category)が であるか であるか$category'accountname'すでに確認してい'charactername'ます。残っている唯一のことは、これらのいずれでもない場合にエラー メッセージを出力することです。

アカウント名

1) アカウント名は挿入する値であり、実際にはテーブル内の外部キーであり、gamecodesテーブルなどにマップされると思いますaccounts

最も簡単なreferential integrity方法は、テーブルの作成に使用することです。テーブル間の関係を定義しaccount nameます。無効な場合、クエリは失敗します。

2) もう 1 つのオプションは、 を使用して select ステートメントを実行し、が別のテーブル内account nameに存在することを確認することです。accountさらに、PHP を使用してさらにチェックを行うこともできます。

API関連

MySQL_*関数は非推奨です。Mysqli や PDO などの代替手段を確認する必要があります。参照: http://www.php.net/manual/en/mysqlinfo.api.choosing.php

于 2013-06-18T21:18:55.423 に答える
0

accountnamecharacternameは、スイッチがこれらのリテラルと一致する場合にのみ大文字と小文字が区別されるという意味で、既に「検証済み」です。

SQL インジェクションを防御する必要があることを知っているのは良いことですが、実際に実装されたソリューションはそうではありません。たとえば、入力ゲームコードは大きな穴です。理想的には、準備済みステートメントを使用する必要があります。mysqli_real_escape_stringまたは同等のものも同様に機能しますが、デフォルトのサーバー文字セットに関して注意が必要です。

最後に、可能な限り、取得する入力がpreg_matchなどで期待する入力であることを確認してください。たとえば、ゲームコードが 6 桁の整数にしかできない場合次のようにすることができます。

if (preg_match('/^[0-9]{6}$/', $gamecode) === 0){
    // fail
}
于 2013-06-18T21:31:42.793 に答える