2

ユーザーがEvernoteのSDKforPHPを使用してEvernoteアカウントにログインできるようにする簡単なPHPアプリケーション(MyApp)を作成しました。ただし、私のアプリケーションでは、これを実行したいと思います。

  1. ユーザーがEvernoteログインを承認する
  2. MyAppは、#1のrequestToken、requestTokenSecretなどを受け取ります。
  3. MyAppは#2をCookieに保存します$_SESSION
  4. ユーザーが後で私のサイトに戻ったとき、MyAppはCookieを介してユーザーにログインします

はい、そのようなCookieベースのログインは安全ではないことを私は知っています。ただし、私のアプリケーションは機密データを保存しません。続行する最も簡単な方法は何ですか?これが私の試みです:

//if cookie
if (isset($_COOKIE['requestToken'])) {
    $m = new mysqli(MYSQL_SERVER, MYSQL_USER, MYSQL_PASS, MYSQL_DB);
    $q = "SELECT uid FROM users WHERE token={$_COOKIE['requestToken']} and secret={$_COOKIE['requestTokenSecret']}";

   // cookie matches db?
   if ($result = $m->query($q)) { 
      $_SESSION['login']=TRUE;
      $result->close();
}
   else // no match
      $_SESSION['login']=FALSE; 
}
else { //no cookie - create
    if (EverNoteLogin()) {
       $year=time()+86400*365; //86400 = 1 day
       setcookie('requestToken',$_SESSION['requestToken'],$year); 
       setcookie('requestTokenSecret',$_SESSION['requestTokenSecret'],$year);
    }
}

推奨される改善バージョン

//if cookie
if (isset($_COOKIE['requestToken'])) {
    //check db
    $m = new mysqli(MYSQL_SERVER, MYSQL_USER, MYSQL_PASS, MYSQL_DB);
    $s=$m->prepare("SELECT uid FROM user WHERE token=? AND secret=?");
    $s->bind_param('ss',$rt, $rs);
    $rt=$_COOKIE['requestToken'];
    $rs=$_COOKIE['requestTokenSecret'];
    $s->execute();
    $s->store_result(); 
    $n=$s->num_rows;
    //match db?
    if ($n) {
        if ($n==1) { // 1 match
                $s->bind_result($uid);
                $_SESSION['uid']=$uid;
                $_SESSION['login']=TRUE;
            }
        else
            $_SESSION['login']=FALSE; // >1 match not good
    }else
        $_SESSION['login']=FALSE;
}
else { //no cookie - create
    if (EverNoteLogin()) {
       $year=time()+86400*365; //86400 = 1 day
       setcookie('requestToken',$_SESSION['requestToken'],$year); 
       setcookie('requestTokenSecret',$_SESSION['requestTokenSecret'],$year);
    }
}
4

2 に答える 2

0

使用するbind_paramことは、あなたが示す場合のSQLインジェクションに対する効果的な防御です。これで、Cookieの値は関係ありません。SQLステートメントのセマンティクスを変更することはできません。

SQLクエリのパラメータプレースホルダーは、常に単一のスカラー値として機能します。値にSQL構文が含まれている場合、それは問題ではありません。すべての特殊文字が完全にエスケープされた状態で、引用符で囲まれた文字列をクエリに挿入したかのように機能します。SQLインジェクションの脆弱性を回避するために完全に安全です。

SQLインジェクションの詳細については、私のプレゼンテーション「SQLインジェクションの神話と誤謬」、または私の著書「SQLアンチパターン:データベースプログラミングの落とし穴の回避」を参照してください。

ただし、安全ではないのは、認証資格情報をプレーンテキストでCookieに保存することです。 そうしないでください。パスワードをCookieに保存するのは安全ですか?
も参照してください。または機密データを含むCookieをPHPに安全に保存する方法は?

于 2012-11-02T16:29:01.690 に答える
0

準備されたステートメントを使用するスクリプトのバージョンは、SQL インジェクションの観点から適切に見えると思います。

また、Cookie を安全な Cookie (https 接続が必要) として設定し、http のみの Cookie (JavaScript などへのアクセスを防止する) として設定することをお勧めします。

于 2012-11-02T16:05:27.710 に答える