我在mysql中有一条表消息
id(bigint) sender(int) receiver(int) message(varchar)
1 42 420 Hi
2 80 32 Hello
3 61 32 I love you
我的delete.php代码
if(isset($_POST['id']))mysql_query("Delete from message where id=".$_POST['id']."");
用户使用ajax请求删除邮件的页面
<div>sender:Romeo
receiver:Juliet
message:I love you</div>
<span id="3">delete</span>//delete message with id 3
<script>
$("span").click(function(){$.post("delete.php",{"id",$("span").attr("id")});
});</script>
现在据我所知,任何人都可以知道我正在向哪个页面发出此请求,并使用方法发布和操作delete.php和删除消息轻松开发假表单。 谁能告诉我如何防止这种情况?
答案 0 :(得分:5)
您需要验证/验证传入数据(即当前用户是否有权删除指定的邮件?)。您还需要使用prepared statements来阻止SQL注入,而不是直接将用户数据插入查询。
答案 1 :(得分:1)
mysql_real_escape_string()来清理MySQL查询的用户输入。
EG。
$id = mysql_real_escape_string( $_POST['id'] );
mysql_query( "SELECT * FROM blah WHERE id='$id'" );
答案 2 :(得分:1)
请注意,如果您过滤并转义数据,则不会阻止用户通过猜测ID来学习Ajax调用的端点并删除所有消息。
与Ed Daniel指出的一样,您应该使用身份验证,以便只有授权用户才能删除帖子,并且只有在他们是作者或有权限的情况下才能删除帖子。
答案 3 :(得分:0)
这是一个修复:
$id = array_key_exists('id', $_POST) ? (int) $_POST['id'] : null;
if ($id)
{
mysql_query("DELETE FROM message WHERE id={$id}");
}
我首先检查了$_POST
数组中存在的项目,以避免PHP通知,并且在使用之前我已经使用(int)
对其进行了清理。
一些建议:始终在if
语句中使用大括号 - 这样可以为您节省很多麻烦。此外,如果可以,请迁移到PDO或mysqli,以便您可以使用预准备语句。最后有一个SQL案例约定很好 - 如果你愿意的话你可以用标题大小写它,但我倾向于在关键字中使用upper,在实体名称中使用更低。
答案 4 :(得分:0)
我希望Juliet必须首先登录才能看到这条消息!基本上,这是你的答案 - 用户身份验证。如果POST的提交者无法说服您有权删除该消息,那么请不要让他们。
正如Olli Charlesworth指出的那样,SQL正在寻找麻烦。
答案 5 :(得分:0)
只有已登录用户才能访问该页面。您可以通过检查$ _SESSION中的user_id或类似内容来查看天气用户登录。即使有人可以将数据从他的m / c发布到您的服务器,也不会添加它,因为您已经在上面进行了身份验证检查。最好使用prepare语句,mysql_escape或addSlashes,regexp等来清理输入。
答案 6 :(得分:0)
示例中的代码包含一个很大的MySQL注入问题。 无论你使用$ _POST,$ _GET,$ _COOKIE,$ _FILES,$ _SERVER的值是由用户控制的(包括USER_AGENT,上传文件的文件名等等),你都必须保护它。
正如建议的那样,最好的方法是使用PDO(PHP数据对象,数据库访问的抽象层)。
mysql_real_escape_string()
会删除任何类似“and”的引号,但不会对每种注入都有所帮助。
如果有人使用-1 OR 1=1
,您的整个牌桌将被清除。 mysql_real_escape_string
无法提供任何安全保障。
此外,您应该实现某种登录,现在每个人都可以删除表中的任何记录。
查看PDO的PHP手册:http://de.php.net/manual/en/pdo.prepare.php了解更多信息。
答案 7 :(得分:0)
检查记录的用户ID是否等于接收者ID。
如果没有,就死了