我正在尝试PHP和MySQL,但现在我找到了一个我想要使用的PHP代码,但它很容易被SQL注入。有谁知道注射是什么以及什么代码可以修复它?
<?
// both the username and password must be specified
if(!isset($_GET["username"]) || !isset($_GET["password"])) {
print "NO username and/or password";
die;
}
$username = $_GET["username"];
$password = $_GET["password"];
// prepare database connection
mysql_connect("host", "user", "password");
mysql_select_db("dbase");
// validate the specified username
$res = mysql_query("SELECT id FROM users WHERE username = '$username'");
if(!$res || !($row = mysql_fetch_row($res))) {
print "Unknown username";
die;
}
// validate the password
$res = mysql_query("SELECT password FROM users WHERE id = ".$row[0]);
if(!$res || !($row = mysql_fetch_row($res))) {
print "Illegal userid record";
die;
}
if($password != $row[0]) {
print "Invalid password";
die;
}
// Access Granted
?>
代码是额外代码的一部分,但是没有必要,可以使用/somecode.php?username='OD'1'='1&amp; password = something'选择用户名但是'或者不使用密码,任何人都可以帮助我吗?
此致
答案 0 :(得分:2)
不要动态构建SQL代码 - 将用户输入作为参数传递。
请参阅PHP文档中的this example。
如果您像这样动态构建SQL:
$res = mysql_query("SELECT id FROM users WHERE username = '$username'");
其中$username
可能包含由用户直接提供的内容,那么您就有风险。使用诸如预准备语句之类的解决方案,用户无法直接影响正在执行的SQL查询,这是一种更安全的替代方案。
答案 1 :(得分:1)
问题在于这一行:
// validate the specified username
$res = mysql_query("SELECT id FROM users WHERE username = '$username'");
由于$ username直接来自用户,因此有人可以传递test' OR id='1
的用户名,这将产生以下sql:
SELECT id FROM users WHERE username ='test'或id ='1';
攻击者现在已经成为id为1的用户。糟糕!
您需要使用$_GET['username']
或类似的内容转义addslashes()
变量。
答案 2 :(得分:1)
该代码存在几个问题:
mysql_
函数。相反,您的代码看起来应该是这样的:
$connection = new PDO('mysql:dbname=dbase;host=127.0.0.1', 'user' , 'password' );
$connection->setAttribute( PDO::ATTR_EMULATE_PREPARES, false );
$stmt = $connection->prepare('SELECT id FROM users WHERE username = :user');
$stmt->bindParam( ':user', $_POST['username'], PDO::PARAM_STR, 128);
if ( $stmt->execute() )
{
var_dump( $stmt->fetchAll(PDO::FETCH_ASSOC ));
}
补充阅读: