$_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 真的安全吗?的主要内容,如果未能解决你的问题,请参考以下文章

你的登录接口真的安全吗?

HTTPS 为啥安全? 真的安全吗?

Tor真的匿名和安全吗?——如果是http数据,则在出口节点容易被嗅探明文流量,这就是根本问题

你所熟悉的网络真的安全吗?万字文

掌上折扣app是真的吗安全吗

私有方法真的安全吗?