-1

ログインフォームのSQLインジェクションに問題があるので、それを停止する方法を教えてください。

使ってるmysql_real_escape_stringけど何も変わらない

if(isset($_POST['submit-login'])) { 

    $user = $_POST['username'];
    $pass = $_POST['password'];

    $username = mysql_real_escape_string($user);
    $password = mysql_real_escape_string($pass);

    $usertool = new Usertool();
    if($usertool->login($username, $password)){
        //successful login, redirect them to a page
        header("Location: index.php");
    }else{
        $error = "Incorrect username or password. Please try again.";
    }
}

ここにユーザーツールがあります

class usertool {
    public function login($username, $password) {
        $hashedPassword = md5($password);
        $result = mysql_query("SELECT * FROM tbl_user WHERE uname = '$username' OR eemail = '$username' AND password = '$hashedPassword'");
        if (mysql_num_rows($result) == 1) {
            $_SESSION["user"] = serialize(new User(mysql_fetch_assoc($result)));
            $_SESSION["login_time"] = time();
            $_SESSION["logged_in"] = 1;     
            return true;
        } else {
            return false;
        }
}
4

1 に答える 1

4

あなたの場合は古典的なSQLインジェクションではなく、間違ったSQLロジックです。

クエリに中かっこを追加する必要があります。

SELECT * FROM tbl_user 
   WHERE (uname = '$username' OR eemail = '$username') 
      AND password = '$hashedPassword'"

元のクエリでは、入力されたユーザー名または電子メールが一致し、パスワードがチェックされていない場合、ステートメント全体が true と評価されます

また、一般的な SQL インジェクションに関しては、クエリを安全にするために、これらのルールに従ってクエリ部分をフォーマットする必要があります

  1. フォーマットが完了している必要があります。mysql_real_escape_string だけでは、不完全な書式設定が行われます。この関数を使用してエスケープしたデータの前後にアポストロフィを追加する必要があります。
  2. フォーマットは適切である必要があります。つまり、文字列フォーマットで数値または識別子をフォーマットすることはできません。すべての SQL リテラルには、独自の個別の書式設定が必要です。
  3. 書式設定は、クエリの実行にできるだけ近い場所で行う必要があります。

これらのルールに従えば、注射からかなり安全になります. そして、準備されたステートメントを使用することは、それらに従うための最も簡単な方法です。

ただし、ネイティブの準備済みステートメントを使用するために mysqli も PDO も必要ありません。独自のバリアントを作成できます。それでもなお、mysql_real_escape_string をクエリ実行のできるだけ近くに移動し、常に結果の前後にアポストロフィを追加する必要があります。

于 2013-05-20T08:12:19.233 に答える