为了账号安全,请及时绑定邮箱和手机立即绑定

何时(以及为什么何时)以及我应该如何在 php 中清理来自 POST JSON 的数据

何时(以及为什么何时)以及我应该如何在 php 中清理来自 POST JSON 的数据

PHP
呼唤远方 2022-01-08 17:41:20
在过去的几天里,我阅读了很多关于使用 PHP 对输入和输出数据进行清理以防止(最突出)XSS 和 SQL 注入的资源,以及关于 SO 的一堆问题。然而,在这一点上,我觉得我对我应该做什么和不应该做什么感到更加困惑和不安全,部分原因是一些相反的信息,例如我读过很多次我没有读过mysqli_real_escape_string如果我使用准备好的语句,则需要使用或任何其他形式的输入净化,其他消息来源说我无论如何都应该使用它,甚至应该像这样净化它;苹果的这个页面相当粗略地(?)讨论了这个话题;等等。因此,我真的很感激我应该做的一些澄清 - 最好但不一定,由在该领域(服务器端安全)有一些经验的人,例如在这个领域工作,已经完成了对此进行了大量研究,甚至可能站在攻击者的一边(?)。为了更好地了解我的情况,我将尽可能简洁地回顾一下:我目前正在使用 Swift (iOS) 编写应用程序,并且需要将一些数据发送到我的服务器,并使用 SQL 将其保存在表中,并且可以被其他用户检索(例如博客)。为此,我通过 POST 将编码为 JSON 的数据发送到我的服务器(“myphp.php”;使用 Alamofire,不过这应该不是很重要)并在那里对其进行解码。这是我不确定是否应该以某种方式清理我的数据的第一个地方(参考我上面链接的问题)。无论如何,然后我继续使用准备好的语句将它插入到表中(MySQL,所以没有任何模拟)。此外,我还希望我输出的数据可以在 html 中使用,或者更确切地说,整个 PHP 也可以用于 AJAX。这是我的意思的一个例子:// SWIFT// set parameters for requestlet parameters: Parameters = [    “key”: “value”,    ...]// request with json encoded parametersAlamofire.request(“myphp.php”, method: .post, parameters: parameters, encoding: JSONEncoding.default).validate().responseJSON(completionHandler: { (response) in// do things with data (e.g. show blog post)// PHPheader('Content-Type: application/json');$decodedPost = json_decode(file_get_contents('php://input'), true);// what to do with input...?// PREPARED STATEMENTS: insert, select, etc.// what to do with output...?// echo response - json-encoded so that// json completion handler in swift can work with it echo json_encode($output, JSON_NUMERIC_CHECK);我已经向一位朋友征求了一些建议,他告诉我他总是做以下事情(xss_clean()也是他发给我的一个功能)——无论数据是输入还是输出:$key = xss_clean(mysqli_real_escape_string($db, trim(htmlspecialchars($data)))); // e.g. $data = decodedPost["key"]然而,不仅我的研究告诉我这可能没有必要,而且他还告诉我这有其局限性,最明显的是,当数据应该从服务器再次检索并再次显示给例如另一个用户时——尽可能接近尽可能使用原始输入。如您所见,我真的很困惑。我想尽我所能保护发送到服务器的用户数据,所以这对我来说是一个非常重要的话题。我希望这个问题不会太宽泛,但许多其他问题,就像我说的那样,至少部分是矛盾的或非常古老的,例如仍然使用简单的mysql扩展并且没有准备好的陈述。如果您需要更多信息,请随时询问。非常感谢参考官方文档(以支持答案)。谢谢!
查看完整描述

1 回答

?
汪汪一只猫

TA贡献1898条经验 获得超8个赞

输入清理是一个误导性术语,表示您可以对所有数据挥动魔杖并将其设为“安全数据”。问题是当数据被不同的软件解释为编码要求时,“安全”的定义会发生变化。同样,“有效”数据的概念因上下文而异——您的数据很可能需要特殊字符('、、&、<)——请注意,SO 允许所有这些作为数据。

可以安全嵌入到 SQL 查询中的输出可能不安全地嵌入到 HTML 中。或斯威夫特。或 JSON。或外壳命令。或 CSV。并且剥离(或彻底拒绝)值以便它们可以安全地嵌入所有这些上下文(以及许多其他上下文)中,限制性太强。

那么我们应该怎么做呢?确保数据永远不会造成损害。实现这一点的最佳方法是首先避免解释数据。参数化 SQL 查询就是一个很好的例子;参数永远不会被解释为 SQL,它们只是作为数据放入数据库中。

相同的数据可用于其他其他格式,例如 HTML。在这种情况下,数据应在嵌入时针对该特定语言进行编码/转义。因此,为了防止 XSS,数据在被放入输出时应该是 HTML 转义(或 javascript 或 URL 转义)。不是在输入时。这同样适用于其他嵌入情况。

那么,我们应该直接将我们得到的任何东西传递给数据库吗?

不 - 您肯定可以检查有关用户输入的内容,但这高度依赖于上下文。让我们称其为 - 验证。确保这是在服务器上完成的。一些例子:

  • 如果一个字段应该是一个整数,你当然可以验证这个字段以确保它包含一个整数(或者可能是 NULL)。

  • 您通常可以检查特定值是否是一组已知值中的一个(白名单验证)

  • 您可以要求大多数字段具有最小和最大长度。

  • 您通常应该验证任何字符串仅包含对其编码的有效字符(例如,没有无效的 UTF-8 序列)

如您所见,这些检查非常依赖于上下文。所有这些都是为了帮助增加您最终获得有意义数据的几率。它们不应该是保护您的应用程序免受恶意输入(SQL 注入、XSS、命令注入等)的唯一防御,因为这不是这样做的地方。


查看完整回答
反对 回复 2022-01-08
  • 1 回答
  • 0 关注
  • 198 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号