我有一个设置,我要从表中删除条目。
它基于 URL 的查询字符串,我认为无论如何这可能是一个糟糕的开始方式。
因此,如果网址是:
http://www.example.com/delete.php?id=123&ref=abc
删除.php中的 php 如下:
$id=$_GET['id'];
$ref=$_GET['ref'];
$con = mysql_connect("blahblah","user","password");
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db("test", $con);
mysql_query("DELETE FROM mytable WHERE id=" . $id . " AND ref='" . $ref . "'");
mysql_close($con);
有没有办法使它更安全...或者这确实
以任何方式安全??编辑:
好的,根据反馈,我采取了一种新的方法。
list.php 包含表中每个条目的一组单选按钮 - 如下所示:
$con = mysql_connect("localhost","username","password");
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db("db", $con);
$result = mysql_query("SELECT * FROM myTable");
echo "<form name='wer' id='wer' action='delete.php' method='post' >";
echo "<table border='1'>";
while($row = mysql_fetch_array($result))
{
echo "<tr>";
echo "<td>" . $row['title'] . "</td>";
echo "<td><input type='radio' name='test1' value='" . $row['id'] . "' /></td>";
echo "</tr>";
}
echo "</table>";
echo "<input type='submit' name='submit' value='Submit' />";
echo "</form>";
mysql_close($con);
删除.php看起来像这样:
function check_input($value) {
if (get_magic_quotes_gpc()) {
$value = stripslashes($value);
}
if (!is_numeric($value)) {
$value = "'" . mysql_real_escape_string($value) . "'";
}
return $value;
}
$con = mysql_connect("localhost","user","password");
if (!$con) {
die('Could not connect: ' . mysql_error());
}
$varID = check_input($_POST["id"]);
mysql_select_db("db", $con);
$sql="DELETE FROM myTable WHERE id IN (" . $varID . ")";
if (!mysql_query($sql,$con)) {
die('Error: ' . mysql_error());
}
mysql_close($con);
header("Location: list.php");
这是更好的方法吗?
- 您有一个 SQL 注入漏洞,因为您没有清理放入查询的 GET 参数。攻击者可以使用它来删除表中的所有元素。
对此的干净解决方案是使用prepared Statements
.
快速而肮脏的解决方案是将它们放在引号中并将它们贯穿mysql_real_escape_string
。 - 即使您修复了该部分,如果攻击者可以猜出有效的
id
/ref
对,他也可以删除该条目。 - 如果参数是整数,那为什么不将其类型也设为整数呢?类似
$id=intval($_GET['id'])
GET 被认为是一种安全的方法,应该没有任何副作用:
特别是,该公约已经确立了GET和HEAD 方法不应具有采取行动的意义除了检索。这些方法应该被认为是"安全的"。
在您的情况下,您的脚本可能容易受到跨站点请求伪造的攻击。您最好改用 POST,并在删除之前考虑某种身份验证和授权检查。
此外,由于您使用未经审核和修改的传递参数,因此您也容易受到 SQL 注入的影响。
至少,您应该将这些值放入参数中,而不是将它们直接粘贴到 SQL 语句中。 现在,您容易受到SQL注入攻击。 下面是一篇有关如何参数化查询、使用存储过程或验证传入语句的好文章。 这应该对您的安全性有很大帮助:
https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet
mysql_query(sprintf("DELETE FROM mytable WHERE id='%s' AND ref='%s'", mysql_real_escape_string($id),mysql_real_escape_string($res)));