我已经尝试 SQL 注入我的代码 'technically' 应该容易受到攻击但它不会工作
I've tried SQL injecting my code which 'technically' should be vulnerable but it wont work
我一直被告知我的代码容易受到 SQL 注入的攻击,但是我已经从 mysql 转换为 mysqli 扩展,并且我已经尝试 SQL 对我自己的注射攻击,但 none 似乎有效所以我的问题是...
我的代码真的安全吗?如果不安全,为什么 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 注射,其中 none 有效
如果我没记错的话,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
邪恶的注入还不止
防止 SQL 注入的最好方法是使用准备好的语句。转义字符串总比什么都不做要好,但也许有一些例子,即使是转义的字符串也会导致注入。准备好的语句单独交给数据库,所以它已经知道查询并且输入不能再改变查询。
另请注意,存储明文密码绝不是一个好主意。请使用 password_hash 或类似的东西散列密码。
破解密码的方法有多种; 不安全。不一定要执行 DROP
语句才能使您的代码不安全。
例如,函数 SignUp
是不安全的。如果$_POST[email]
的值为' OR 1=1 --
,则认证查询变为:
SELECT * FROM admin WHERE email = '' OR 1=1 --
(--
是攻击的常见指标;其目的是将后面的任何内容变成评论。)此查询将始终 return 结果,因为 1=1
总是正确的。因此,您的用户将始终 被认证为管理员。这意味着 newUser
被调用,攻击者数据被插入到 admin
table,而您刚刚失去了对站点的控制。
MORAL: 总是 使用准备好的语句。 从不 直接插入来自用户的值,可能来自用户,来自数据库,来自 API,等等,直接进入您的 SQL 语句。当涉及到 SQL 注入时,不要相信 任何人(包括你自己),并且每次都对每个参数或变量使用准备好的语句。
你应该阅读 OWASP's guide to SQL injection issues, their SQL Injection Prevention Cheat Sheet, and their PHP Security Cheat Sheet。
我一直被告知我的代码容易受到 SQL 注入的攻击,但是我已经从 mysql 转换为 mysqli 扩展,并且我已经尝试 SQL 对我自己的注射攻击,但 none 似乎有效所以我的问题是...
我的代码真的安全吗?如果不安全,为什么 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 注射,其中 none 有效
如果我没记错的话,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
邪恶的注入还不止
防止 SQL 注入的最好方法是使用准备好的语句。转义字符串总比什么都不做要好,但也许有一些例子,即使是转义的字符串也会导致注入。准备好的语句单独交给数据库,所以它已经知道查询并且输入不能再改变查询。
另请注意,存储明文密码绝不是一个好主意。请使用 password_hash 或类似的东西散列密码。
破解密码的方法有多种; 不安全。不一定要执行 DROP
语句才能使您的代码不安全。
例如,函数 SignUp
是不安全的。如果$_POST[email]
的值为' OR 1=1 --
,则认证查询变为:
SELECT * FROM admin WHERE email = '' OR 1=1 --
(--
是攻击的常见指标;其目的是将后面的任何内容变成评论。)此查询将始终 return 结果,因为 1=1
总是正确的。因此,您的用户将始终 被认证为管理员。这意味着 newUser
被调用,攻击者数据被插入到 admin
table,而您刚刚失去了对站点的控制。
MORAL: 总是 使用准备好的语句。 从不 直接插入来自用户的值,可能来自用户,来自数据库,来自 API,等等,直接进入您的 SQL 语句。当涉及到 SQL 注入时,不要相信 任何人(包括你自己),并且每次都对每个参数或变量使用准备好的语句。
你应该阅读 OWASP's guide to SQL injection issues, their SQL Injection Prevention Cheat Sheet, and their PHP Security Cheat Sheet。