在回复previous question I had posted时,有一个回复我正在打开我的数据库到SQL注入。代码如下:
<?php
$firstname = stripslashes(strip_tags($_POST['firstname']));
$lastname = stripslashes(strip_tags($_POST['lastname']));
$email = stripslashes(strip_tags($_POST['email']));
$title = stripslashes(strip_tags($_POST['title']));
$organization = stripslashes(strip_tags($_POST['organization']));
$pdbHost = "localhost";
$pdbUserName = "******";
$pdbPassword = "******";
$pdbName = "db1080824_emails";
// Connect to mySQL
$conlink = mysql_connect($pdbHost, $pdbUserName, $pdbPassword);
if(!$conlink) {die('Unable to connect to '.$pdbHost);}
if (!mysql_select_db($pdbName, $conlink)){die('Cannot find database '.$pdbName);}
//SQL query
$SQL2="INSERT INTO `db1080824_emails`.`emails` (`record_id` ,`firstname`,`lastname`,`email`,`title`,`organization`)VALUES (NULL , '".$firstname."', '".$lastname."', '".$email."', '".$title."', '".$organization."')";
mysql_query($SQL2);
// Connect to Closing the connection
mysql_close($conlink);
?>
有人建议我可以对'/ ^ [A-Za-z0-9] /'进行服务器端验证检查,以确保不会发生sql注入,但这是否足够或是否有最佳实践我应该遵循以确保数据清理?
答案 0 :(得分:3)
使用准备好的陈述。认真。一种简单的方法是使用PHP的数据库包装器PDO。
$firstname = $_POST['firstname'];
$lastname = …;
…
$db = new PDO('mysql:host=hostname;dbname=dbname', 'username', 'password');
$stmt = $db->prepare('INSERT INTO `db1080824_emails`.`emails` (`firstname`,`lastname`,`email`,`title`,`organization`)
VALUES (:firstname, :lastname, :email, :title, :organization)');
$stmt->execute(array(
':firstname' => $firstname,
':lastname' => $lastname,
':email' => $email,
':title' => $title,
':organization' => $organization));
答案 1 :(得分:1)
使用mysql_real_escape_string()
来阻止SQL注入。只有这个功能就足够了。
而且,@ knittl所说的,使用预准备语句也是防止它的一种非常好的方法。但正常的mysql_ * libary不支持这一点。你需要一个像PDO或MySQLi这样的库。我建议你切换到PDO或MySQLi,因为在更高的PHP版本中,mysql_ * libary会被弃用。
其他一些改进代码的提示:
die()
。如果你犯了一个错误,你就不会死,为什么要一台电脑呢?最好处理错误并将它们放在你想要的位置。mysql_close()
不需要。 PHP在执行结束时关闭每个连接。mysql_affected_rows()
或mysql_num_rows
核对。我要回答有关此答案的评论。您应该仅对字符串使用mysql_real_escape_ string 。如果您使用mysql_real_escape_string()
,请确保在查询中的字符串周围加上引号('
):
$query = "SELECT foo FROM bar WHERE name = '".mysql_real_escape_string($_POST['name'])."'";
如果你使用整数或任何其他数字,你应该使用typecasting而不是转义函数:
$query = "SELECT foo FROM bar WHERE id = ".(int) $_POST['id'];
答案 2 :(得分:0)
我一直在使用PDO,我相信这可以防止注射:
$db_user = "****";
$db_pass= "****";
$dsn = "mysql:dbname=yourdatabasename; host=localhost";
$dbh = new PDO($dsn, $db_user, $db_pass);
$sql = 'INSERT INTO
emails(firstname, lastname, email, title, organization)
VALUES(:firstname,:lastname,:email,:title,:organization)';
$data = array(':firstname'=>$firstname,
':lastname'=>$lastname,
':email'=>$email,
':title'=>$title,
':organization'=>$organization);
$sth = $dbh->prepare($sql);
$sth->execute($data);