我一直被告知我的代码容易受到SQL注入,但是我已经从mysql转换到mysqli扩展,我已经尝试过对自己进行SQL注入攻击,但它们似乎都不起作用,所以我的问题是…
我的代码实际上是安全的,如果不是,为什么SQL注入工作?
<?php
session_start();
if (!isset($_SESSION["email"])){
header ("location: logout.php");
die();
}
include('connect-db.php');
if (mysqli_connect_errno())
{
echo "Failed to connect to mysqli: " . mysqli_connect_error();
}
else
{
}
function newUser()
{
$forename = $_POST['forename'];
$surname = $_POST['surname'];
$email = $_POST['email'];
$securityq = $_POST['securityq'];
$securitya = $_POST['securitya'];
$password = ($_POST['password']);
$query = "INSERT INTO admin (forename,surname,email,securityq, securitya,password) VALUES ('$forename','$surname','$email','$securityq','$securitya','$password')";
include('connect-db.php');
$data = mysqli_query ($db, $query)or die(mysqli_error($db));
if($data)
{
}
}
function SignUp()
{
if(!empty($_POST['email']))
{
include('connect-db.php');
$query = mysqli_query ($db, "SELECT * FROM admin WHERE email = '$_POST[email]'")
or die(mysqli_error());
if(!$row = mysqli_fetch_array($query) or die(mysqli_error()))
{
newuser();
echo ("<SCRIPT LANGUAGE='JavaScript'>
window.alert('Admin Registration Successful')
window.location.href='adminhome.php';
</SCRIPT>");
}
else
{
echo ("<SCRIPT LANGUAGE='JavaScript'>
window.alert('Sorry You are already a registered user!')
window.location.href='adminhome.php';
</SCRIPT>");
}
}
}
if(isset($_POST['submit']))
{
SignUp();
}
?>
我在尝试SQL注入时得到的错误都类似于这个:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DROP table pdf',','lll','pppppp')' at line 1
我也尝试了很多不同类型的SQL注入,他们都没有工作
有多种方法可以破坏你的代码;它不是安全的。你的代码不一定要执行DROP
语句才不安全。
例如,SignUp
是不安全的。如果"$_POST[email]
"的值为"' OR 1=1 --
",则认证查询变为:
SELECT * FROM admin WHERE email = '' OR 1=1 --
(--
是攻击的常见指标;它的目的是把后面的内容变成评论。)这个查询总是会返回一个结果,因为1=1
总是为真。因此,您的用户将始终被认证为管理员。这意味着newUser
被调用,攻击者的数据被插入到admin
表中,你就失去了对你的网站的控制。
MORAL: 总是使用预处理语句。永远不要直接在SQL语句中插入来自用户、可能来自用户、来自数据库、来自API等的值。当涉及到SQL注入时,不要相信任何人(包括你自己),并且每次都为每个参数或变量使用准备好的语句。
你应该阅读OWASP的SQL注入问题指南,他们的SQL注入预防备忘单和他们的PHP安全备忘单。
如果我没记错的话,mysqli_query
一次只能执行一个查询。这意味着,您不能通过注入将查询扩展为更多的查询,如
$query = "INSERT INTO admin (forename,surname,email,securityq, securitya,password)
VALUES ('$forename','$surname','$email','$securityq','$securitya','$password')";
使用$password = "'); DROP TABLE admins; --";
但是也许你可以改变它来覆盖其他一些数据。如使用
$password = "newPasswort') ON DUPLICATE KEY UPDATE password = VALUES(password); --";
我还没有测试过这个。这只是为了了解大意。DROP
不是唯一的邪恶注射。
还要注意,存储纯密码从来都不是一个好主意。请使用password_hash或类似的散列密码