这个PHP / MySQL删除功能是否安全?

时间:2011-05-21 12:36:21

标签: php mysql security sql-delete

我有一个设置,我从表中删除条目。

它基于URL的查询字符串,我认为这可能是一个不好的开始方式。

所以如果网址是:

http://www.example.com/delete.php?id=123&ref=abc

delete.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包含表格中每个条目的一组radiobuttons - 如下所示:

$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);

而del​​ete.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");

这是一个更好的方法吗?

4 个答案:

答案 0 :(得分:11)

  1. 您有一个SQL注入漏洞,因为您没有清理放入查询中的GET参数。攻击者可以使用它删除表中的所有元素 对此的干净解决方案是使用prepared Statements 快速而肮脏的解决方案是将它们放在引号中并通过mysql_real_escape_string运行它们。
  2. 即使您修复了该部分,如果攻击者可以猜出有效的id / ref对,他也可以删除该条目。
  3. 如果参数是一个整数,那你为什么不把它的类型变成整数呢?像$id=intval($_GET['id'])
  4. 之类的东西

答案 1 :(得分:5)

GET被视为safe method,不应有任何副作用:

  

特别是,已经建立了GET和GET的惯例      HEAD方法不应该具有采取行动的意义      除了检索。这些方法应该被认为是“安全的”。

在您的情况下,您的脚本可能容易受到Cross-Site Request Forgery的攻击。您应该更好地使用POST,并在删除之前考虑某种身份验证和授权检查。

此外,由于您使用未经审核且未经修改的传递参数,因此您也容易受到SQL Injections的攻击。<​​/ p>

答案 2 :(得分:2)

至少,您应该将这些值放入参数中,而不是将它们直接粘贴到SQL语句中。现在您很容易受到SQL注入攻击。这是一篇关于如何参数化查询,使用存储过程或验证传入语句的好文章。这应该会极大地帮助您的安全:

https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet

答案 3 :(得分:1)

mysql_query(sprintf("DELETE FROM mytable WHERE id='%s' AND ref='%s'", mysql_real_escape_string($id),mysql_real_escape_string($res)));