A php+mysql system, MySQL database has a user table, which has a code field, the type is int (11), this field is to save a random number, used to retrieve the password when the validation, the default value is 0.
Retrieve password when the step is, first fill in their own mailbox, receive reset password mail, click on the link, access the following code:
if (!empty($_GET[‘email‘]) && !empty($_GET[‘code‘]))
{
if (!$db->count(‘user‘,"email=‘{$_GET[‘email‘]}‘ AND code=‘{$_GET[‘code‘]}‘"))
die(‘error‘);
$_SESSION[‘email‘] = $_GET[‘email‘];
...
}
Find email=$_get[' email ' in the database and code=$_get[' code '], if the number of lines is 0 die out, otherwise set $_session[' email ' = $_get[' email '], and finally $_ Reset the password for the mailbox stored in session[' email '.
Seems to be no problem, only when email is your email, and you know his random code, can not die, to get $_session[' email '.
But the key question is: The default value of code is 0, that is, all users as long as the password is not reset, his code is 0, so it is equal to say I know all the user's code, then I can reset all the user's password?
No, wait, we see this line of code:
if (!empty ($_get[' email ') &&!empty ($_get[' Code '))
It is necessary to!empty ($_get[' code ') to enter this if statement. Everyone familiar with PHP knows that empty (0) is back to true. So, if $_get[' code ']=0, it doesn't get into this if statement. So what?
This involves MySQL a tip, it is easy to err on the point of--code this field is type int (11), and in MySQL, when the field type is integer and the value in the WHERE statement is not integer, it is converted to an integer to put into the query. That is, if the where code= ' xxx ' in XXX is not an integral type, then the XXX will be converted to an integer before it is put into the query.
That is, if we pass in a string of 0aaa, it will be converted to 0 and then executed.
Select COUNT (*) from ' user ' where ' id ' = ' 0 ';
Select COUNT (*) from ' user ' where ' id ' = ' 0a ';
All of the above results are 1.
So through this tip, you can bypass if (!empty ($_get[' email ')) &&!empty ($_get[' Code ')), as long as we pass in the $_get[' code ']=0xxx, you can enter the IF statement, And let the Select COUNT (*) statement return 1, and finally retrieve any user password, no need to burst.
A PHP validation vulnerability caused by MySQL feature