【问题标题】:PHP $_GET security, $_POST security best practicePHP $_GET 安全、$_POST 安全最佳实践
【发布时间】:2012-03-31 13:12:56
【问题描述】:

这是一个很好的话题,但我想确认一下在几种不同情况下使用来自用户变量的数据的方法。

  1. 该变量从不在数据库中使用,从不存储,仅在屏幕上为用户显示。使用哪个函数来确保没有 html 或 javascript 可以搞砸?

  2. 变量被带入数据库,并在 SQL 查询中使用。

  3. 变量兼而有之。

目前我 xss_clean 和 strip_tags。我一直这样做,只是通过自动驾驶仪。有没有更好的技术?抱歉,如果那里有相同的问题。我有点假设有,虽然我找不到像这样彻底的。

干杯。

【问题讨论】:

标签: php security variables post get


【解决方案1】:
  1. 在输出时使用适当的函数,在 HTML 上下文中,这是htmlspecialchars
  2. 使用准备好的语句
  3. 参见 1. 和 2. – 取决于您是显示变量还是在查询中使用它。

【讨论】:

  • 目前在 PHP 5.4 htmlspecialchars,htmlentities 中存在缓冲区溢出。 fortiguard.com/encyclopedia/vulnerability/…
  • @LawrenceCherone 应该采取什么措施来对抗这个漏洞?
  • 可能只允许最多 40 个字节,所以拆分字符串。
  • 如果您在输入 value 属性中输出字符串并且使用单引号,则使用 ENT_QUOTES 作为 htmlspecialchars() 的第二个参数。
  • 这方面的 htmlspecialchars 知识很棒。谢谢。您能否进一步详细说明“使用过的准备好的语句”?我主要是用mysql,那么mysql_real_escape_string够用吗?
【解决方案2】:

PHP 世界中最糟糕的错觉之一是 $_GET$_POST 与安全有关。

重要的不是来源而是目的地

  • 如果你必须处理数据库,规则总是相同的,无论数据来自$_POST、SOAP 请求还是数据库。它必须始终相同:数据的占位符,其他所有内容的白名单。
  • 如果您必须将一些数据输出到浏览器中,您必须做好准备,无论数据来自$_POST、SOAP 请求还是数据库。
  • 如果您必须从文件中读取 - 您必须保护文件名,无论它来自何处,等等

【讨论】:

  • -1 无用。您还不如说“确保您的数据安全”。
  • 呃,是的。我明确要求为这两种输入类型提供解决方案,这意味着没有区别。
  • @Michael 请仔细阅读我的回答。 POST 不需要特殊的安全性。数据库需要它。你不明白吗?
  • 感谢您的回答。你是乐于助人和愤怒的致命组合,就像一个正在离婚的大学教授。我明白来源是无关紧要的,如果我没有说清楚,我很抱歉。您在这个问题中的其他观点都很好,我已经清楚了很多。我主要使用 CI 和活动记录课程,所以这对我来说主要是教育,只要确保我完全了解我的应用程序中发生的事情。再次感谢。
【解决方案3】:
  1. 在第一种情况下,htmlspecialchars() 可能是最佳选择,它允许用户使用所有字符,如 、& 等。
  2. 在第二种情况下,您需要使用一些数据库转义函数,如 mysql_real_escape_string 或带有 PDO 或 mysqli 的准备好的语句。准备好的语句是最好的选择,但如果你只熟悉 mysql,那么 mysql_real_escape_string 也可以。如果您不使用 mysql,那么大多数 SQL API 中都有类似的功能。
  3. 在第三种情况下,两者都单独执行,with 会为您提供两种不同的结果,一种用于输出,另一种用于数据库。

参考资料:

http://php.net/manual/en/function.htmlspecialchars.php

http://php.net/manual/en/function.mysql-real-escape-string.php

http://php.net/manual/en/book.pdo.php

http://php.net/manual/en/book.mysqli.php

【讨论】:

  • 转义与安全无关。 mysql_real_escape_string 不能正常工作。 -1。对投票的人感到羞耻。
  • 是的,确实如此,如果您没有正确地转义发送到 MySQL 等数据库的数据,那么您将使其容易受到 SQL 注入的攻击。对于以 HTML 格式输出的数据也是如此,如果您没有正确转义/编码输出,这些数据将容易受到 XSS 攻击。
  • $id="1;drop table users;"; $id=mysql_real_escape_string($id); $sql="SELECT * FROM table WHERE id=$id";吃吧
  • 我明白你的意思,但你犯了一个错误,即转义了一些不是作为字符串发送的东西。但是,如果您将其作为字符串发送,它将起作用。这是一种粗略的方法,当然应该始终使用 is_numeric 和 intval 验证整数,但是如果您改为使用 mysql_real_escape_string 并将您的 id 用引号括起来,从而将其作为字符串发送,MySQL 将忽略 id 中的额外数据(;drop table users;) 并获取 id 为 1 的行。SELECT * FROM table WHERE id="1;drop table users;"
  • 这不是我的错,而是你的。您的答案中没有关于字符串的内容。即使有,请将查询更改为 $sql="SELECT * FROM table LIMIT $id"; 并尝试再次为自己辩解。
【解决方案4】:
$id="1;drop table users;"; $id=mysql_real_escape_string($id); $sql="SELECT * FROM table

WHERE id=$id";

【讨论】:

    猜你喜欢
    • 2010-09-28
    • 1970-01-01
    • 2012-01-07
    • 2013-06-19
    • 2014-01-17
    • 2011-01-26
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多