2012-10-05 132 views
0

我得到這個錯誤,我不明白爲什麼。我已經花了好幾個小時了,試着通過調查研究它,但沒有運氣。SQL查詢錯誤?

在我的PHP登錄系統,我檢查是否選擇該行:

//Start session 
    session_start(); 

    //Include database connection details 
    require_once('config.php'); 

    //Array to store validation errors 
    $errmsg_arr = array(); 

    //Validation error flag 
    $errflag = false; 

    //Connect to mysql server 
    $link = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD); 
    if(!$link) { 
     die('Failed to connect to server: ' . mysql_error()); 
    } 

    //Select database 
    $db = mysql_select_db(DB_DATABASE); 
    if(!$db) { 
     die("Unable to select database"); 
    } 

    //Prevent SQL injection. 
    function clean($str) { 
     $str = @trim($str); 
     if(get_magic_quotes_gpc()) { 
      $str = stripslashes($str); 
     } 
     return mysql_real_escape_string($str); 
    } 

    //Sanitize the POST values 
    $login = clean($_POST['login']); 
    $password = clean($_POST['password']); 

    //Input Validations 
    if($login == '') { 
     $errmsg_arr[] = 'Login ID missing'; 
     $errflag = true; 
    } 
    if($password == '') { 
     $errmsg_arr[] = 'Password missing'; 
     $errflag = true; 
    } 

    //If there are input validations, redirect back to the login form 
    if($errflag) { 
     $_SESSION['ERRMSG_ARR'] = $errmsg_arr; 
     session_write_close(); 
     echo "input validation"; 
     exit(); 
    } 

    //Create query 
    $qry="SELECT * FROM details WHERE USERNAME='$login' AND PASSWORD='".md5($_POST['password'])."'"; 
    $result=mysql_query($qry); 

    //Check whether the query was successful or not 
    if($result) { 
     if(mysql_num_rows($result) == 1) { 
      //Login Successful 
      session_regenerate_id(); 
      $member = mysql_fetch_assoc($result); 
      $_SESSION['MEMBER_ID'] = $member['USERNAME']; 


      session_write_close(); 
      header("location: client-index.php"); 
      exit(); 
     }else { 
      //Login failed 
      echo "login failed?"; 
      exit(); 
     } 
    }else { 
     die("Query failed"); 
    } 
?> 

它回聲「失敗」,無論出於何種原因。

+0

我們可以看到html部分嗎?我的第一個猜測是,你的文章不是submited –

+0

整個頁面只是PHP。 –

+0

$ _POST變量來自哪裏? –

回答

1

如果您告訴我們錯誤是什麼,它可能會幫助我們更好地回答您的問題。

但無論如何,這是強調這種錯誤的方式。這個系統有很多嚴重的問題。

首先,你不是在消毒你的輸入。由於您將數據和命令混合在一起,所有用戶必須輸入用戶名「x」或1 = 1「 - 」才能進入系統。原因如下:SQL服務器將獲得的唯一命令是「SELECT * FROM details WHERE USERNAME ='x'or 1 = 1」。換句話說,如果用戶名是x或者1 = 1(它是),那麼SQL服務器會響應一個肯定的結果。 (「用戶名」末尾的兩個破折號表示SQL中的註釋,因此查詢中的所有內容都將被忽略)。

一個真正的惡意攻擊者甚至可以通過輸入用戶名「X肆虐你的系統‘ - ;刪除表;’,和你的整個數據庫就會消失(參見this comic因爲我得到了這個地方。)

事實上,你甚至不應該真正使用的mysql_query都按照PHP documentation:。

這個擴展的使用氣餒相反,庫MySQLi或PDO_MYSQL擴展應使用

如果我是你,我會對這個主題做更多的閱讀。即使這只是爲了練習,第一次把事情做好也是最好的。看看PDO:這不是很難學,但很有用。它的主要優點是它不會混合數據和命令,所以你不會遇到混淆數據庫的未經處理的輸入的問題。

此外,儘管很高興看到您在密碼中進行哈希處理,並且您會驚訝於有多少公司應該更好地瞭解密碼 - MD5不再被認爲是密碼安全的。獲得所謂的「散列衝突」相對容易,其中兩個不同的明文產生相同的散列。現在,SHA-256應該是你使用的最小值。

此外,關於散列問題,您應該添加一些名爲salt的東西。鹽是某種隨機文本,您添加到您的明文爲了進一步混淆它。這是因爲那裏有所謂的彩虹表。彩虹表是所有常用密碼的預先計算的哈希列表。如果有人想要保存你的數據庫,他們可以將所有密碼與彩虹表進行比較以找到它們的明文。

最後,爲了減緩蠻力攻擊 - 攻擊者嘗試所有字母數字組合直到他們獲得密碼 - 您還應該使用循環,其中哈希算法重新計算x次,通常在1000到10000次之間。 PHP的crypt做得非常好。

而且BTW:不要感覺不好。我以前也做過所有這些事情。這就是爲什麼我知道你不應該這樣做。別擔心 - 你很快就會到達那裏。堅持下去!

+0

作爲(較短的)評論,這會更合適。此外,不久前更新了這個問題,以表明投入實際上正在被消毒。 – 2012-10-05 00:30:29

+0

我想象他在我編輯帖子之前打字。我非常欣賞那種信息,所以我會牢記它。謝謝。 –

+0

我確實在編輯代碼時輸入了我的答案。另外,我還沒有足夠的聲望將評論留在任何其他人的帖子中。 – blainarmstrong

1

我是新來的網站,這樣可以不加評論,也許這不會幫助很多,但生病給它一個去反正

在SQL查詢看起來你傳遞變量$登錄文本不變量值

$qry="SELECT * FROM details WHERE USERNAME='$login' AND PASSWORD='".md5($_POST['password'])."'"; 

,它應該是

$qry="SELECT * FROM details WHERE USERNAME=".$login." AND PASSWORD='".md5($_POST['password'])."'"; 
+0

這並沒有改變任何東西:s –

+0

我剛剛編輯的代碼,試試這個...如果它仍然失敗,我放棄 – Veljko89

+0

有趣。這使得它啓動了「死亡(」查詢失敗「);」線? –

1

是失敗或登錄失敗的查詢?

無論如何,如果查詢失敗: 嘗試改變您的查詢在此: 包圍與反引號的字段(不是單引號)

$qry="SELECT * FROM details WHERE `USERNAME`='$login' AND `PASSWORD`='".md5($_POST['password'])."'"; 

如果登錄失敗:

if(mysql_num_rows($result) == 1) { 
    //Login successful 
}else { 
    //Login failed 
} 

你確定查詢只會有1個結果?因爲在這種情況下,如果結果大於1,它也將無法登錄。

+0

Well ..yeah ?我會這樣想的。該行對用戶是唯一的。 –