如何清理和存储用户输入,其中包含WordPress中的HTML正则表达式模式



我正在开发一些WordPress插件,它的功能之一是能够将用户输入的HTML正则表达式模式存储到数据库中,然后将其显示在设置页面上。

我的方法实际上有效,但我想知道该代码是否足够安全:

这是用户输入的模式:

<div(.+?)class='sharedaddy sd-sharing-enabled'(.*?)>(.+?)<div><div><div>

这就是我在数据库中存储HTML模式的方式:

$print_options['custom_exclude_pattern'] = htmlentities(stripslashes($_POST['custom_exclude_pattern']),ENT_QUOTES,"UTF-8"); 

这就是它实际存储在WordPress DB中的方式:

s:22:"custom_exclude_pattern";s:109:"&lt;div(.+?)class=&quot;sharedaddy sd-sharing-enabled&quot;(.*?)&gt;(.+?)&lt;div&gt;&lt;div&gt;&lt;div&gt;";

这就是输出在设置页面上的显示方式:

<input type="text" name="custom_exclude_pattern" value="<?php echo str_replace('"',"'",html_entity_decode($print_options['custom_exclude_pattern'])); ?>" size="30" />

感谢您的帮助:)

从评论中,听起来您关心两个单独的问题(并且可能不知道我将在一分钟内提到的第三个问题),并为两者寻找一种解决方案:SQL注入跨站点脚本。你必须分别对待每一个。我恳请您阅读Defuse Security的这篇文章。

如何防止 SQL 注入

这在StackOverflow上已经回答过,关于一般的PHP应用程序。WordPress的$wpdb支持准备好的语句,所以你也不一定要弄清楚如何使用PDO或MySQLi。(但是,其驱动程序中的任何漏洞都会影响您的插件。确保您彻底阅读了$wpdb文档。

在将参数传递给预准备语句之前,不应对其进行转义。你最终只会得到被破坏的数据。

跨站点脚本

在撰写本文时(2015 年 6 月),您需要考虑两种一般情况:

  1. 不应允许用户向此输入提交任何 HTML、CSS 等。
  2. 允许用户向此输入提交一些 HTML、CSS 等,但我们不希望他们能够通过这样做来破解我们。

第一个问题很简单,可以解决:

echo htmlentities($dbresult['field'], ENT_QUOTES | ENT_HTML5, 'UTF-8');

第二个问题有点棘手。它涉及只允许某些标记,而不意外地允许其他标记,这些标记可以用来让Javascript在用户的浏览器中运行。目前XSS防御的黄金标准,同时允许一些HTML是HTML净化器。

重要!

无论您的要求是什么,您都应该始终在输出上应用 XSS 防御,而不是在将内容插入数据库之前。最近,Wordpress 核心存在一个存储的跨站点脚本漏洞,该漏洞是由于决定在存储之前进行转义而不是在渲染前转义而导致的。通过提供足够长的注释,攻击者可以在转义文本上触发MySQL截断错误,从而绕过防御。

奖励:来自unserialize()的PHP对象注入

这就是它实际存储在WordPress DB中的方式:

s:22:"custom_exclude_pattern";s:109:"&lt;div(.+?)class=&quot;sharedaddy sd-sharing-enabled&quot;(.*?)&gt;(.+?)&lt;div&gt;&lt;div&gt;&lt;div&gt;";

看起来您在存储此数据时使用serialize(),并且在检索数据时可能使用unserialize()小心unserialize();如果您允许用户对字符串进行任何控制,他们可以将 PHP 对象注入到您的代码中,这也可能导致远程代码执行。

根据记录,远程代码执行意味着他们可以接管您的整个网站,并可能接管托管您博客的服务器。如果用户有可能直接更改此记录,我强烈建议改用json_encode()json_decode()

我希望

我明白了重点,如果没有,请纠正我:您正在尝试根据存储在数据库中的相同模式为输入字段动态插入模式,对吗?好吧,我个人认为模式对可用性很有帮助,因为用户知道他的输入格式不正确,而无需每次提交和刷新。模式的最大问题是,HTML代码可以在客户端修改。我相信唯一安全的解决方案是检查服务器端输入的正确性......客户端过程不可能比服务器端过程更安全!

好吧,如果你要让你的用户输入正则表达式,你可以做一些类似 ready 语句 + htmlentities($input, ENT_COMPAT, "UTF-I"); 来清理输入,然后做相反的事情,那就是html_entity_decode($dataFromDb, ENT_COMPAT, " UTF-8");。必须的是准备好的语句,所有其他解决恶意输入的方法都可以以许多不同的方式组合在一起!

最新更新