简体   繁体   English

注册表格中避免使用SQL注入

[英]Avoid SQL injection in registration form php

I've a simple registration form on my localhost (still testing), and I am wondering if it can be attacked by SQL injection? 我在localhost上有一个简单的注册表单(仍在测试),我想知道它是否可以被SQL注入攻击?

Code: 码:

$name = mysql_real_escape_string($_POST['name']);
$password = mysql_real_escape_string($_POST['password']);
$password = md5($password);
$email = mysql_real_escape_string($_POST['email']);
$refId = $_GET['refid'];
$ip = $_SERVER['REMOTE_ADDR'];


$add = mysql_query("INSERT INTO `users` (`name`, `password`, `email`, `refId`, `ip`)
VALUES('$name','$password','$email','$refId', '$ip')") or die(mysql_error());

Is that safe or can someone use SQL injection (I'd like to know how)? 这样安全还是有人可以使用SQL注入(我想知道如何)? How can I avoid injection? 我怎样才能避免注射?

The best way to avoid injections is to use Prepared Statements . 避免注射的最佳方法是使用Prepared Statements
For prepared Statements I prefer to use PDO to handle all my DB stuff. 对于准备好的语句,我更喜欢使用PDO来处理我的所有数据库内容。 here is some PDO sample code I wrote to retrieve some basic login information: 这里是我写的一些PDO示例代码,用于检索一些基本的登录信息:

$sql=new PDO("mysql:host=127.0.0.1;dbname=name","user","password");
        $user=$_POST[user];

        $query="select Salt,Passwd from User
                where Name=:user";
        $stmt=$sql->prepare($query);
        $stmt->bindParam(':user',$user);
        $stmt->execute();
        $dr=$stmt->fetch();        
        $sql=null; 
        $password=$_POST[pass];
        $salt=$dr['Salt'];

... etc ......等

Read this page for more information on PDO. 有关PDO的更多信息,请阅读页面。 If you want to know what each line of code here is doing, read this answer I gave to another post. 如果你想知道的每一行代码这里是干什么的,看这个答案我给了另一篇文章。

It is indeed vulnerable; 它确实很脆弱; you haven't escaped $_GET['refid'] . 你没有逃过$_GET['refid'] Take this URL for example: 以此URL为例:

yourpage.php?refid='%2C'')%3B%20DROP%20TABLE%20users%3B--

Avoiding SQL injection is easy. 避免SQL注入很容易。 Use prepared statements and PDO. 使用预准备语句和PDO。 For example: 例如:

$query = $dbh->prepare("INSERT INTO `users`(`name`, `password`, `email`, `refId`, `ip`)
VALUES(:name, :password, :email, :refId, :ip)");
$query->bindValue(':name', $_POST['name']);
$query->bindValue(':password', md5($_POST['password'])); # Do not use MD5 for password hashing, and especially not without salt.
$query->bindValue(':email', $_POST['email']);
$query->bindValue(':refid', $_GET['refid']);
$query->bindValue(':ip', $_SERVER['REMOTE_ADDR']);
$query->execute();

You didn't mysql_real_escape_string the $refId , even though that's grabbed from $_GET . 你没有mysql_real_escape_string $refId ,即使这是从$_GET That basically makes all your other injection prevention measures moot. 这基本上使你所有其他注射预防措施都没有实际意义。 On a tangent, if you escape string the password before md5-ing, it changes the hash. 在切线上,如果在md5之前转义字符串密码,则会更改散列。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM