2011-05-21 57 views
4

我有一个设置,我从表中删除条目。这个PHP/MySQL删除函数是否安全?

正是基于这我想可能是一个糟糕的方式反正启动URL的查询字符串。

因此,如果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); 

有没有办法让这个更安全......或这确实在任何方面都是安全的?

编辑:

OK,所以基于反馈我已经采取了新的方法。

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

而且delete.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"); 

这是一个更好的办法去做吧?

+1

的[如何使$ _GET更secure.?](http://stackoverflow.com/questions/3682480/how-do-i-make-get-more-secure) – 2011-05-21 12:39:09

+0

可能重复@ Marcel Korpel:删除是一个幂等的操作。 – Gumbo 2011-05-21 12:49:20

+0

@Gumbo:我一直认为不应该在GET请求中改变数据库。 – 2011-05-21 12:50:36

回答

11
  1. 由于您没有清理您置入查询中的GET参数,因此存在SQL注入漏洞。攻击者可以使用它来删除表中的所有元素。
    干净的解决方案是使用prepared Statements
    快速和肮脏的解决方案是把它们放在引号中,并通过mysql_real_escape_string运行它们。
  2. 即使你解决这个问题的一部分,如果攻击者可以猜到一个有效id/ref对他可以删除该条目。
  3. 如果一个参数是一个整数,那么为什么不把它的类型整数呢?类似于$id=intval($_GET['id'])
+0

我认为可能是这种情况......但我不知道从哪里开始寻找解决此漏洞......任何提示? – Tom 2011-05-21 12:39:46

+1

使用准备好的语句。但是我对PHP不够熟悉,无法告诉你需要使用哪种API。 – CodesInChaos 2011-05-21 12:43:28

+2

可以使用[PDO](http://nl2.php.net/manual/en/book.pdo.php)准备好的语句。 – 2011-05-21 12:49:23

5

GET被认为是一个safe method,不应该有任何的副作用:

特别是,该公约已经确定,GET和 HEAD方法除检索以外,不应具有采取措施 的意义。这些方法应该被认为是“安全的”。

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

此外,由于您使用未经审核且未经修改的传递参数,因此您也容易受到SQL Injections的影响。

+2

+1不会产生副作用。 – CodesInChaos 2011-05-21 12:45:51

+3

请注意,使用POST不会消除CSRF漏洞,它只会让它稍微难以脱离。在表单中使用随机数可以更彻底地防止CSRF - http://stackoverflow.com/questions/2250263/csrf-protection-by-storing-nonce-in-session-variable-and-form – 2011-05-21 12:59:25

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