$_POST 真的安全吗?
Posted
技术标签:
【中文标题】$_POST 真的安全吗?【英文标题】:is $_POST really safe? 【发布时间】:2012-06-12 10:38:45 【问题描述】:我在 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>
现在据我所知,任何人都可以知道我正在向哪个页面发出此请求,并使用方法 post 和 action delete.php 轻松开发一个假表单并删除消息。 谁能告诉我如何防止这种情况发生?
【问题讨论】:
使用访问令牌或类似的东西? 欢迎来到 Stack Overflow!请停止使用古老的mysql_*
函数编写新代码。它们不再维护,社区已经开始deprecation process。相反,您应该了解准备好的语句并使用PDO 或MySQLi。如果你想学习,here is a quite good PDO-related tutorial.
$_POST
并不比$_GET
更安全,如果你是这个意思的话
使用参数插入数据,而不是直接
【参考方案1】:
检查记录的用户 ID 是否等于接收者 ID。
如果没有,就死
【讨论】:
【参考方案2】:您示例中的代码包含一个大的 MySQL 注入问题。 无论您是否使用由用户控制的来自 $_POST、$_GET、$_COOKIE、$_FILES、$_SERVER 的值(包括 USER_AGENT、上传文件的文件名等),您都必须对其进行保护。
按照建议,最好的方法是使用 PDO(PHP 数据对象,一种用于数据库访问的抽象层)。
mysql_real_escape_string()
会转义任何引号,例如 " 和 ',但对每种类型的注入都没有帮助。
如果有人使用-1 OR 1=1
,您的整个表格将被清除。而mysql_real_escape_string
无法提供任何安全保障。
另外你应该实现某种登录,现在每个人都可以删除表中的任何记录。
查看 PDO 的 PHP 手册:http://de.php.net/manual/en/pdo.prepare.php 了解更多信息。
【讨论】:
【参考方案3】:这里有一个修复:
$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 的大小写约定——如果你愿意,你可以用标题大小写,但我更喜欢大写的关键字,小写的实体名称。
【讨论】:
这对 SQL 注入安全吗?你没有逃避 post 变量 这并将其与某种基于会话/cookie 的用户身份验证相结合,以确保用户有权首先删除此记录。 @Johan 它被转换为int
,除了数字以外的任何东西都会返回0
。对于字符串等,您显然需要正确转义。
@Johan - 是的,我已将其强制为整数;够了。
@Dunhamzzz - 绝对是的身份验证。【参考方案4】:
您需要验证/验证传入的数据(即当前用户是否有权删除指定的消息?)。您还需要通过使用prepared statements 来防止SQL 注入,而不是直接将用户数据插入到查询中。
【讨论】:
【参考方案5】:请注意,如果您过滤和转义数据,则不会阻止用户通过猜测 ID 了解 Ajax 调用的端点并删除所有消息。
就像 Ed Daniel 指出的那样,您应该使用身份验证,以便只有授权用户才能删除帖子,并且只有他们是作者或有权这样做。
【讨论】:
老兄,我停止从猜测和删除中删除消息【参考方案6】:该页面必须仅供登录用户访问。您可以通过检查他的 user_id 或 $_SESSION 中的任何类似内容来简单地检查天气用户是否已登录。即使有人可以将数据从他的 m/c 发布到您的服务器,它也不会被添加,因为您已经在上面进行了身份验证检查。你最好使用 prepare 语句、mysql_escape 或 addSlashes、regexp 等来清理你的输入。
【讨论】:
【参考方案7】:我希望 Juliet 必须先登录才能看到消息!基本上,这就是您的答案 - 用户身份验证。如果 POST 的提交者无法说服您他们有权删除该邮件,请不要让他们这样做。
正如 Olli Charlesworth 所指出的,SQL 在自找麻烦。
【讨论】:
【参考方案8】:mysql_real_escape_string() 应该用于清理 MySQL 查询的用户输入。
EG。
$id = mysql_real_escape_string( $_POST['id'] );
mysql_query( "SELECT * FROM blah WHERE id='$id'" );
【讨论】:
正如您链接到的手册页上所说,现在不鼓励使用mysql_
函数以支持 PDO 等。
真相告诉我不要使用 mysql_* 函数,所以现在我很困惑
@OliCharlesworth:是的,但这是一个 MySQL 问题,而不是 PDO_MySQL 或 MySQLi。
顺便说一句,谁能告诉我这个函数是做什么的
+1,虽然我会在使用之前检查数组中是否存在id
,因为如果你不这样做,它会引发 PHP 警告。以上是关于$_POST 真的安全吗?的主要内容,如果未能解决你的问题,请参考以下文章