MySQL php 查询缺陷
MySQL php query flaws
我要做一个关于 SQL 注入的演示,还有什么比我自己的 php 查询并向 class 展示更好的方法呢?
问题是我的数据库和 php 代码 运行 完美无缺,但似乎无法在我创建的编辑表单中找到对我的 UPDATE 查询的利用。
如果有人可以看一下它并告诉我如何插入 'DROP TABLE' 命令或类似的东西,那将非常有帮助!
<?php
session_start();
require_once 'config.php';
error_reporting(E_ALL);
ini_set('display_errors', 1);
$userid = $_SESSION["userid"];
$fname = $_SESSION["fname"];
$lname = $_SESSION["lname"];
$gender = $_SESSION["gender"];
$email = $_SESSION["email"];
if($_SERVER["REQUEST_METHOD"] == "POST") {
$userid = trim($_POST["userid"]);
$fname = trim($_POST["fname"]);
$lname = trim($_POST["lname"]);
$gender = trim($_POST["gender"]);
$email = trim($_POST["email"]);
$query = "UPDATE user_details SET fname = '$fname', lname = '$lname', gender = '$gender', email = '$email' WHERE userid = '$userid' ";
if (mysqli_query($link, $query)) {
echo 'Update complete!';
}
echo mysqli_error($link);
// else {
// echo '<p>' . 'Woah something went really wrong dude' . '</p>' ;
// echo mysqli_error($link);
// }
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Edit</title>
<link rel="stylesheet" href="bootstrap.css">
<style type="text/css">
body{ font: 14px sans-serif; }
.wrapper{ width: 350px; padding: 20px; }
</style>
</head>
<body>
<div class="container">
<form class= "form-inline" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="post">
<label>First Name</label>
<input type="text" name="fname" class="form-control" value="<?php echo $_SESSION["fname"]; ?>">
<label>Last Name</label>
<input type="text" name="lname" class="form-control" value="<?php echo $_SESSION["lname"]; ?>">
<label>Gender</label>
<input type="text" name="gender" class="form-control" value="<?php echo $_SESSION["gender"]; ?>">
<label>Email</label>
<input type="text" name="email" class="form-control" value="<?php echo $_SESSION["email"]; ?>">
</div>
<div class = "wrapper">
<label>UserID</label>
<input type="text" name="userid" class="form-control" value="<?php echo $_SESSION["userid"]; ?>">
<button type="submit">Submit</button>
</form>
<form action="action.php"><button type="submit">Back</button></form>
</div>
</body>
</html>
不确定我是否完全理解您的意思,但我会尝试告诉您为什么这似乎是个坏主意...
如果我post到userid
$userid="';DROP TABLE XY;SELECT * FROM USER_DETAILS WHERE fname = '"
您的代码可以...
$query = "UPDATE user_details SET fname = '$fname', lname = '$lname', gender
= '$gender', email = '$email' WHERE userid = '$userid' ";
查询结果:
$query = "UPDATE user_details SET fname = '$fname', lname = '$lname', gender
= '$gender', email = '$email' WHERE userid = '';DROP TABLE XY;SELECT * FROM
USER_DETAILS WHERE fname = '' ";
查询将是
UPDATE user_details SET fname = '$fname', lname = '$lname', gender
= '$gender', email = '$email' WHERE userid = ''
DROP TABLE XY
SELECT * FROM USER_DETAILS WHERE fname = ''
它们中的每一个都是有效的...现在使用此 posted 注入创建一个 table XY 和 运行 您示例的原始查询...
我错过了什么?
编辑:正如@RaymondNijland 指出的那样,示例中使用的 mysql 函数似乎可以阻止这种攻击。我仍然认为它是一种危险的代码风格,只有驱动程序才能确保安全。也许将来会有更新允许批处理 sql,我会睡得更好,因为我的代码不会打开这种门...
在大多数情况下,mysqli 会阻止多次查询,并且 MySQL 本身有一定的 in-built 安全措施来防止意外删除 table 和数据库。所以你的 DROP TABLE
不会工作。
但是您可以使用 MySQL 注入来演示成功的登录尝试。
创建一个登录表单并将数据传递到验证页面。将您的查询写为,
query = "SELECT * FROM `user`
WHERE `username` = '." username ".' AND `password` = '." password ".'";
现在,在登录表单中输入用户名 ' OR '1'='1
和密码 ' OR '1'='1
。所以最后完整的查询看起来像这样,
SELECT * FROM `user` WHERE `username`='' OR '1'='1' AND `password`='' OR '1'='1';
这将 return user
table 中的所有用户记录,应用程序将使用第一条记录登录。
我要做一个关于 SQL 注入的演示,还有什么比我自己的 php 查询并向 class 展示更好的方法呢? 问题是我的数据库和 php 代码 运行 完美无缺,但似乎无法在我创建的编辑表单中找到对我的 UPDATE 查询的利用。 如果有人可以看一下它并告诉我如何插入 'DROP TABLE' 命令或类似的东西,那将非常有帮助!
<?php
session_start();
require_once 'config.php';
error_reporting(E_ALL);
ini_set('display_errors', 1);
$userid = $_SESSION["userid"];
$fname = $_SESSION["fname"];
$lname = $_SESSION["lname"];
$gender = $_SESSION["gender"];
$email = $_SESSION["email"];
if($_SERVER["REQUEST_METHOD"] == "POST") {
$userid = trim($_POST["userid"]);
$fname = trim($_POST["fname"]);
$lname = trim($_POST["lname"]);
$gender = trim($_POST["gender"]);
$email = trim($_POST["email"]);
$query = "UPDATE user_details SET fname = '$fname', lname = '$lname', gender = '$gender', email = '$email' WHERE userid = '$userid' ";
if (mysqli_query($link, $query)) {
echo 'Update complete!';
}
echo mysqli_error($link);
// else {
// echo '<p>' . 'Woah something went really wrong dude' . '</p>' ;
// echo mysqli_error($link);
// }
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Edit</title>
<link rel="stylesheet" href="bootstrap.css">
<style type="text/css">
body{ font: 14px sans-serif; }
.wrapper{ width: 350px; padding: 20px; }
</style>
</head>
<body>
<div class="container">
<form class= "form-inline" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="post">
<label>First Name</label>
<input type="text" name="fname" class="form-control" value="<?php echo $_SESSION["fname"]; ?>">
<label>Last Name</label>
<input type="text" name="lname" class="form-control" value="<?php echo $_SESSION["lname"]; ?>">
<label>Gender</label>
<input type="text" name="gender" class="form-control" value="<?php echo $_SESSION["gender"]; ?>">
<label>Email</label>
<input type="text" name="email" class="form-control" value="<?php echo $_SESSION["email"]; ?>">
</div>
<div class = "wrapper">
<label>UserID</label>
<input type="text" name="userid" class="form-control" value="<?php echo $_SESSION["userid"]; ?>">
<button type="submit">Submit</button>
</form>
<form action="action.php"><button type="submit">Back</button></form>
</div>
</body>
</html>
不确定我是否完全理解您的意思,但我会尝试告诉您为什么这似乎是个坏主意...
如果我post到userid
$userid="';DROP TABLE XY;SELECT * FROM USER_DETAILS WHERE fname = '"
您的代码可以...
$query = "UPDATE user_details SET fname = '$fname', lname = '$lname', gender
= '$gender', email = '$email' WHERE userid = '$userid' ";
查询结果:
$query = "UPDATE user_details SET fname = '$fname', lname = '$lname', gender
= '$gender', email = '$email' WHERE userid = '';DROP TABLE XY;SELECT * FROM
USER_DETAILS WHERE fname = '' ";
查询将是
UPDATE user_details SET fname = '$fname', lname = '$lname', gender
= '$gender', email = '$email' WHERE userid = ''
DROP TABLE XY
SELECT * FROM USER_DETAILS WHERE fname = ''
它们中的每一个都是有效的...现在使用此 posted 注入创建一个 table XY 和 运行 您示例的原始查询...
我错过了什么?
编辑:正如@RaymondNijland 指出的那样,示例中使用的 mysql 函数似乎可以阻止这种攻击。我仍然认为它是一种危险的代码风格,只有驱动程序才能确保安全。也许将来会有更新允许批处理 sql,我会睡得更好,因为我的代码不会打开这种门...
在大多数情况下,mysqli 会阻止多次查询,并且 MySQL 本身有一定的 in-built 安全措施来防止意外删除 table 和数据库。所以你的 DROP TABLE
不会工作。
但是您可以使用 MySQL 注入来演示成功的登录尝试。
创建一个登录表单并将数据传递到验证页面。将您的查询写为,
query = "SELECT * FROM `user`
WHERE `username` = '." username ".' AND `password` = '." password ".'";
现在,在登录表单中输入用户名 ' OR '1'='1
和密码 ' OR '1'='1
。所以最后完整的查询看起来像这样,
SELECT * FROM `user` WHERE `username`='' OR '1'='1' AND `password`='' OR '1'='1';
这将 return user
table 中的所有用户记录,应用程序将使用第一条记录登录。