【问题标题】:Passing base64_encoded serialized data between form submissions在表单提交之间传递 base64_encoded 序列化数据
【发布时间】:2023-03-22 15:39:01
【问题描述】:

我正在创建一系列基于向导的表单来接受用户输入。该向导的要求之一是脚本(PHP)在用户单击“保存”按钮之前无法将输入保存到数据库(MySQL)中,因此我必须设计一种机制以将用户输入以一种形式传输到另一种形式当用户单击“上一个”或“下一个”按钮时。我研究了使用各种方法,包括 cookie、会话、临时文件等,但我决定将 base64_encoded 序列化数据嵌入到系列中所有表单中存在的隐藏字段中。此字段中的值将在表单提交时解码,并在插入当前表单中的其他值后重新编码以放入下一个表单。

以下是隐藏字段的外观示例:

<input type="hidden" name="wizard:presave" value="YTo2OntzOjU6InRpdGxlIjtzOjEwOiJRdWVzdGlvbiAyIjtzOjQ6InRleHQiO3M6MTk6IlllcyBpdCdzIGEgcXVlc3Rpb24iO3M6NDoidHlwZSI7czo2OiJjaG9pY2UiO3M6NzoiY2hvaWNlcyI7YTowOnt9czo1OiJwb2ludCI7aToxO3M6Mjoib3AiO3M6MTM6ImVkaXRfZXhlcmNpc2UiO30=" />

所以问题是:

  1. 这是一种好/坏的做法吗?

  2. HTMLform中隐藏字段有长度限制吗?

  3. 可能存在哪些安全问题?

  4. 还有更好的选择吗? (有解释,最好不使用javascript)

提前致谢!

【问题讨论】:

    标签: php webforms user-input base64 wizard


    【解决方案1】:
    1. 在我的职业生涯中,我从未见过这种特殊的参数传递方法,所以我不能说它是好是坏。这当然不是“标准”。标准方法要么使用隐藏输入(未编码/正常)传递提交的方法,要么存储在会话中。我认为您可能正在为自己工作,所以从这个意义上说,它会倾向于“不理想”。

    2. 只要您在表单中使用 POST,就没有我在 HTTP 规范中知道的数据大小的定义限制。较旧的服务器可能存在实际限制,但除非您正在做一些极端的事情,例如媒体文件上传,否则不必担心。

    3. 可能的安全问题是正常的 Web 安全漏洞。您从用户那里获取并重新输出到页面的任何内容都可能包含跨站点脚本漏洞,并且必须进行适当的清理(如果您正在对所有内容进行编码,这有点没有实际意义)。用户可以制作自己的数据并根据需要提交。基本上,假设您处理的所有数据都是不安全和受污染的。

    4. 会话在这里会工作得更好。用户提交的数据不必经过冗长的编码过程。同样,您只需验证一次。提交并验证后,您可以简单地将其存储在服务器上的 $_SESSION 中,然后不理会它,直到单击最后一个按钮。否则,您必须担心在每个步骤中重新输出、重新接收和重新验证。恶意用户可以提交一组数据,对其进行检查并作为编码数据重新输出,然后通过取消编码、更改数据和重新编码来制作下一个表单提交。

    我强烈建议您重新考虑会话,因为它会将您的所有数据操作简化为“一次性”场景。

    【讨论】:

    • 我重新考虑了使用会话并且它可以工作,尽管我仍然需要在提交之间传递一个随机的“实例 ID”,以便用户可以在同一会话上运行多个向导实例而不会干扰每个其他。但它是否会引入其他安全问题,例如用户弄乱了实例 ID 等?
    • 我不这么认为。只要您在会话中正确存储随机值,那么唯一可用于操作的参数就是会话令牌本身。
    • 已实施并且运行良好。这里的所有答案都很好,但这个给出了最好的解释。谢谢。
    【解决方案2】:

    这被认为是一种好/坏的做法吗?

    取决于目的。到目前为止,我只看到了诸如客户端 URL 哈希之类的构造,以记住大型基于 ajax 的应用程序中的选择状态(以便它们可以添加书签),然后通常还进行 Gzip 压缩以使其更短。在您的特定情况下,我会说:利用 HTTP 会话并仅在隐藏字段中传递基于请求的标识符(也称为 token),以便您可以从会话中获取相关信息。

    HTMLform中隐藏字段有长度限制吗?

    在 GET 中,完整的查询字符串(所有参数名称和值以及分隔符一起)通常限制为 2048 个字符,但您最好遵守 256 个字符的官方限制。在 POST 中,它取决于服务器配置。这通常默认为 2GB 左右。

    可能存在哪些安全问题?

    嗯,它显然是可以解码的。

    还有更好的选择吗? (有解释,最好不使用javascript)

    您可以压缩它以使其更短且不那么明显。或者,如前所述,将会话与基于请求的标识符结合使用。

    【讨论】:

    • 在 base64_encode 之后尝试了 gzip,但它破坏了 html 结构。 base64_encode 之前的 gzip 给出了几乎相同长度的字符串。无论如何+1 ;)
    【解决方案3】:

    好吧,您可以通过序列化将其存储到会话中,也可以简单地将其存储为每个步骤的方式。当用户单击“保存”时,您会抓取并验证会话中所有步骤的数据。

    【讨论】:

      【解决方案4】:

      啧啧啧:)

      1. 这是一种好/坏的做法吗? 主观上 - 不好的做法..你在工作中使用了错误的锤子。

      2. HTMLform 中隐藏字段的长度是否有限制? - 不确定是否有限制。

      3. 可能存在哪些安全问题? - 可能有很多,但您可以清理收到的每个请求的数据。此外,数据很容易解码,并且可以在客户端轻松修改(我可以看到您正在使用它的某种 json :))

      4. 还有更好的选择吗? (有解释,最好不使用 javascript) - 使用正确的工具 .. sessions 也许?

      是的...您很可能会面临性能和可扩展性问题(如果您有大量的用户负载),需要为每个请求运行所有的清理、解析、格式化和安全代码。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-04-05
        • 1970-01-01
        • 2012-06-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多