<?php // Checking whether a user with the same username exists $username = mysql_real_escape_string($_GET['username']); $password = mysql_real_escape_string($_GET['password']); $query = "SELECT * FROM users WHERE username='$username'"; $res = mysql_query($query, $database); if($res) { if(mysql_num_rows($res) > 0) { // User exists, exit gracefully } else { // If not, only then insert a new entry $query = "INSERT INTO users(username, password) VALUES ('$username','$password')"; } }
发生原因 1.mysql处于ANSI模式。如果是TRADITIONAL模式或者STRICT_TRANS_TABLES模式会报错data too long for column。 2.服务端没有对用户名长度进行限制。如果服务端限制了用户名长度就自然就不客能导致数据库截断,也就没有利用条件。 3.登陆验证的SQL语句必须是用户名和密码一起验证。如果是验证流程是先根据用户名查找出对应的密码然后再比对密码,当使用vampire为用户名来查询密码的话,数据库此时就会返回两条记录,而一般取第一条即目标用户的记录,那么传输的密码肯定和目标用户密码匹配不上的。 4.验证成功后返回的必须是用户传递进来的用户名,而不是从数据库取出的用户名。因为当我们以用户vampire和密码random_pass登陆时,其实数据库返回的是我们自己的用户信息,而我们的用户名其实是vampire+若干个空格,如果此后的业务逻辑以该用户名为准,那么就不能达到越权的目的了。 payload