2013-09-05 2 views
2

Я храню хеш-файл md5 как в файле cookie, так и в базе данных. У меня есть функция, validate_cookie(), которая читает этот файл cookie и запрашивает базу данных, чтобы найти пользователя, связанного с этим хэшем.SQL-запрос последовательно выбирает несоответствующую строку

validate_cookie() вызывает другую функцию get_user_data(), чтобы выполнить фактический запрос. get_user_data() вызывается несколькими другими функциями и скриптами, поэтому отправляемый запрос довольно общий. Вот функция:

function get_user_data($info,$password=Null,$source=Null) 
{ 
    if(!$source) 
    { 
     $query = "SELECT * FROM `users` WHERE `id` = '".mysql_real_escape_string($info)."' OR `email` = '".mysql_real_escape_string($info)."' OR `cookie`='".mysql_real_escape_string($info)."'"; //Check to see if $info matches any column 
    } 
    else { $query = "SELECT * FROM `users` WHERE `".mysql_real_escape_string($source)."_token` ='".mysql_real_escape_string($info)."'";} //we got a social token 
    $result = mysql_query($query); 

    if($result) 
    { 
     $row = mysql_fetch_array($result); 
     if($password) 
    { 
     if(crypt($password, $row['password']) == $row['password']) //password matching 
     { 
      return $row; 
     } else {return "Password does not match!";} 
    } 
     else { return $row; } 
    } 
    else { return "Could not get result from database!";} 
} 

Важный вопрос в данном случае находится внутри if(!source){} блока. С образом validate_cookie() вызывает get_user_data() этот запрос становится (и я проверил, что он стал таким):

SELECT * FROM `users` WHERE `id` = '8sd8sdvsasdliwerhnbzo823' OR `email`='8sd8sdvsasdliwerhnbzo823' OR `cookie`='8sd8sdvsasdliwerhnbzo823' 

Поскольку id это поле ИНТ и все email проходит проверки, единственный ряд, который должен быть выбран из этот запрос - это те, у которых есть соответствующее поле cookie.

Однако, если вы вызываете этот запрос из PHP-скрипта или вручную из PHPMyAdmin, он всегда будет выбирать как целевую строку, так и другую: тестовый пример, который имеет только NULL в поле cookie. Изменение хэша слегка (так, чтобы оно не должно было ничего сопоставлять) по-прежнему выбирает этот же тестовый пример.

Является ли мой запрос искаженным способом, который я не понимаю? Есть ли какие-то тайные использования OR, которые позволяют сопоставлять поля NULL? Любая помощь будет оценена по достоинству.

P.S. Прежде чем мне расскажут, что я действительно должен использовать mysqli, да, я это знаю. mysql - это приказы босса.

+1

Испытание случае имеет 'NULL' для всех трех из этих полей или только для поля cookie? Учитывая, что любой результат ввода в одном и том же тестовом случае, должно выполняться условие, которое выполняется. 'OR' требует выполнения одного из трех условий, которые вы указали. –

+0

Используйте ограничение 1, молодой. – Hackerman

+0

вы сказали, что у него есть «cookie = null», но что находится в поле «id» и «email» неправильно подобранной строки? –

ответ

2

http://sqlfiddle.com/#!2/0b0832/10/0

Это преобразование вашего хэша к целому. Ваш тестовый идентификатор равен 3. Ваш хэш начинается с 3. Он делает их равными.

select cast('3b38f280e0203d7998a0d0898095ed56' as unsigned) as x 

выходы 3

исправить это следующим образом:

SELECT id, email, password, cookie, 

case when `email` = '3b38f280e0203d7998a0d0898095ed56' then 'email' 
    when `id`  = '3b38f280e0203d7998a0d0898095ed56' then 'id' 
    when `cookie` = '3b38f280e0203d7998a0d0898095ed56' then 'cookie' 
    else 'else' end as wtf 
FROM `users` 
WHERE 
    cast(`id` as char) = '3b38f280e0203d7998a0d0898095ed56' or 
    `email` = '3b38f280e0203d7998a0d0898095ed56' or 
    `cookie` = '3b38f280e0203d7998a0d0898095ed56' 

И это будет по-прежнему работать, если вы передадите в ID = 3

+0

wow, I overread «... id - это int int ...», и все другие db-системы, которые я знаю, дадут sql-ошибку, например, «cant convert» 3b .. 'to integer »или так далее. Мне повезло, что у меня никогда не было такой проблемы. с моими mySql-скриптами. Это происходит из-за моего «запоминания странного списка», thx для этого – halfbit

+0

Мне понадобилось минутку, чтобы понять это ... если вы посмотрите на комментарии по этому вопросу, я не верю, что это было Проблема с БД вообще, потому что это было так странно. Я даже не спрашивал, что конкретно означает «id». sqlfiddle решил это. –

1

Если и только, если вы уверены, что ваш SQL заявление эволюционирует к чему-то вроде:

select a,b,[c ...] from mytable where a='something' or b='something' [or ...] 

с а, б [...] не NULL

вы только должны получить строку с «a» ИЛИ «b» не является нулевым и «чем-то». если нет, то у вас есть проблемы с базой данных/системы/diriver или что еще

иногда «остальные неправы»
СРЮ сказать, что, но то expieriance я сделал (в моем случае php_db2 я только что получил никакого результата иногда).

особенно - и снова - если вы уверены, что ваше заявление эволюционирует во время выполнения, если «родной» инструмент, здесь MySQL администратор дает один и тот же - неправильно - результат, возникает проблема, а не в диапазоне

, если (и это похоже) там есть собственная ошибка в вашей базе данных/драйвера/установки, вы можете попробовать использовать workarround как

select from ... where (a='som' and a is not null) or (b='som' and b is not null...) and so on 

думать о маркировке, что с «TODO: ожидание правильного дб установки» или так

кстати:

Смежные вопросы