我有一个使用CodeIgniter 4框架用PHP编程的简单应用程序,作为一个Web应用程序,它有一些HTML表单供用户输入。
我在做两件事:
1.在我的视图中,来自数据库的所有变量(来自用户输入)都使用CodeIgniter 4的esc()
函数进行了清理。
1.在我的控制器中,当阅读HTTP POST
数据时,我使用PHP过滤器:$data = trim($this->request->getPost('field', FILTER_SANITIZE_SPECIAL_CHARS));
我不确定在从POST阅读数据和打印/显示到HTML时进行消毒是否是一种好的做法,或者是否应该 * 只消毒一次 *。
另外,FILTER_SANITIZE_SPECIAL_CHARS
不能正常工作。我希望HTML表单文本输入能防止用户使用HTML进行攻击,但我希望保留一些数据库在以前的应用程序中使用的“换行符”。FILTER_SANITIZE_SPECIAL_CHARS
不会删除HTML标记,它只会将它们存储在数据库中,而不是作为HTML存储,但它也会更改我的 “换行符”。是否有一个过滤器不会删除HTML标记(只存储带有适当条件的标记),但会考虑\n
“换行符”?
4条答案
按热度按时间xxls0lw81#
您不需要清理用户输入数据,如以下问题所述:
How can I sanitize user input with PHP?
用户输入可以被过滤是一个常见的误解。PHP甚至有一个(现在已经弃用的)“特性”,叫做magic-quotes,它建立在这个想法之上。这是无稽之谈。忘记过滤(或者清理,或者其他人们叫它的东西)吧。
此外,对于 * 大多数使用情形 *,您不需要使用
FILTER_SANITIZE_SPECIAL_CHARS
、htmlspecialchars(...)
、htmlentities(...)
或esc(...)
:我肯定我不需要净化用户输入的数据,因为我不是直接写SQL,而是使用CodeIgniter 4的函数来创建SQL安全的查询。另一方面,我肯定需要在显示时
esc()
相同的信息,以避免在只需要文本的地方显示html。esc()
方法的原因是:*应用程序中的大多数用户表单输入 * 不 * 期望用户提交/发布您计划稍后显示/运行的HTML、CSS或JavaScript。
如果预期的用户输入仅为纯文本(
username
、age
、birth date
等)、图像或文件,请改用form validation以禁止意外数据。即:可用规则和创建自定义规则
通过使用Query Builder进行数据库查询并使用验证规则(
alpha
、alpha_numeric_punct
、numeric
、exact_length
、min_length[8]
、valid_date
、regex_match[/regex/]
、uploaded
等)拒绝意外的用户输入数据,您可以避免大多数潜在的安全漏洞,即:SQL injections和XSS attacks中的一个。x6yk4ghg2#
据我了解,
FILTER_SANITIZE_SPECIAL_CHARS用于在处理或存储用户输入之前对其进行净化。
而esc用于转义字符串中的HTML等,这样它们就不会干扰正常的html、css等。它用于查看数据。
因此,您需要两者,一个用于输入,另一个用于输出。
以下是codeigniter.com。注意,它使用了层压板Escaper库。
esc($数据[,$上下文= 'html'[,$编码]])
参数
$数据(字符串|array)-要转义的信息。
$context(string)-转义上下文。默认值为“html”。
$encoding(string)-字符串的字符编码。
返回转义数据。
返回类型混合
将数据包含在网页中,以帮助防止XSS攻击。这使用Laminas Escaper库来处理数据的实际过滤。
如果$data是一个字符串,那么它就简单地转义并返回它;如果$data是一个数组,那么它就循环遍历它,转义键/值对中的每个“值”。
有效上下文值:html,js,css,网址,属性,原始
从docs.laminas.dev开始
什么是laminas-Escaper不是
laminas-escaper只用于转义输出数据,因此不应该被误用来过滤输入数据。对于这样的任务,请使用laminas-filter,应该使用HTMLPurifier或PHP的Filter功能。
它们所做的一些功能是相似的。比如它们都可以/将要把
<
转换成<
。然而,你存储的数据可能不仅仅来自用户输入,它可能包含<
。这样存储它是非常安全的,但是它需要被转义以用于输出,否则浏览器可能会混淆,认为它是html。xmjla07d3#
steven7mwesigwa的回答得到了我的投票,但这里是你应该如何思考它。
规则摘要
输入:
您应该去除所有不可信的输入(用户表单、您没有写入的数据库、您不控制的XML提要等)
这意味着不需要许多"传统"清理功能(例如,魔术引号、strip_tags等):但是你需要知道你可以处理代码。如果你知道在那个字段中有那些数据是没有意义的,你应该只使用strip_tags或者escape等等。
注:对于用户输入,我倾向于在用户输入时保留数据并拒绝表单,以允许他们重试。例如,如果我需要一个数字,但我得到了"hello",则我将使用"hello"重新加载表单,并告诉用户重试。steven7mwesigwa具有CI中验证函数的链接,可实现此操作。
输出:
为输出选择正确的转换:别把他们搞混了。
为什么?
如果您在输入时执行输出转换,则可以轻松地对输入进行双重转换,或者在输出前忘记是否需要确保安全,或者丢失用户想要输入的数据。错误会发生,但遵循干净的规则可以防止错误。
这也意味着没有必要拒绝特殊字符(例如,拒绝引号的表单会带来糟糕的用户体验,任何限制密码字段中可以使用哪些字符的人只会削弱安全性)
在您的特定情况下:
基本上,您将清理每个输出(您似乎希望避免),但这比意外错过输出清理更安全,比丢失输入的内容更好的用户体验。
n3ipq98p4#
我认为在这种情况下使用esc就足够了。FILTER_SANITIZE_SPECIAL_CHARS是一个PHP过滤器,它可以对“"〈〉&进行编码,并且可以根据标志对其他特殊字符进行剥离或编码。为此,您需要设置标志。它是getPost()方法中的第三个参数。下面是一个示例
这个标志可以根据你的要求改变。你可以使用任何带有标志的PHP过滤器。请参考php documentation了解更多信息。