WP_ERROR中的消息应该已经是html转义的吗?

时间:2019-01-13 作者:Jason Viers

这不是关于什么是html转义或如何转义,而是关于何时转义是否有既定的最佳实践。

我的插件中有一些实用程序代码,可以生成WP_Error 基于用户输入和其他显示代码WP_Error. 当然,在显示时需要对用户输入进行html转义,但我不确定什么时候是最好的时机。

我可以选择是否:

在我构建WP_Error, 显示代码按原样显示。

构建WP_Error, 并在显示代码中完全退出所有WP_Error 消息。

任何一个都可以,但如果我的插件最终与其他插件交互并可能显示它们的WP_Error 反之亦然,我想与Wordpress世界中存在的任何先例相匹配。

我希望文档能够解决这个问题,但我没有看到任何https://codex.wordpress.org/Class_Reference/WP_Error

4 个回复
最合适的回答,由SO网友:Tom J Nowell 整理而成

No, escaping should happen at the moment of output (延迟逃逸)以便我们知道它只发生一次。双重转义可以允许巧尽心思构建的输出中断。

通过转义,我们讨论的是如下函数esc_html, wp_kses_post, esc_url, 等

清理功能和验证功能不同,例如:。sanitize_textfield. 清理清理数据,验证测试数据,转义强制执行一种类型的数据。

对于三角工厂,可以这样想:

  • The validator tests the item is a triangle , 并向上或向下竖起大拇指,它只是观察。如果它是三角形的,是的!如果不是,则不会。验证器是拒绝输入的好方法,应该在输入时发生
  • The sanitizer cleans the item, 在输入时删除不属于三角形的内容。其他示例可能是删除尾随空格。如果项目是一个数字,它可能会去掉任何字母和符号。最终的结果只是一个更干净、更易于管理的版本
  • The escaper enforces the triangle shape, 这就像一个在三角形工厂里有一个三角形孔的饼干切割器。进去什么并不重要,一个三角形出来了,即使是一个正方形进去了。当然,你最终可能会得到一个三角形形状的破碎的东西,但三角形是我们想要的,三角形是我们得到的,双重逃逸是不好的,因为如果我们把形状像三角形的破碎正方形拿出来,把它翻过来,再把它穿过饼干切割器,我们得到的不是三角形,而是六边形。我们不要六边形!

    我们可以根据需要进行多次清理和验证,但我们只能逃避一次,而且应该在输出时发生,如果不是尽可能靠近输出的话。

    所以since WP_Error does not output, and is not responsible for outputting, it should not perform any escaping internally, nor should its inputs be escaped. 可能已验证/消毒,但未逃脱。

    如果我们对输入进行了转义,我们要么必须加倍转义,要么信任所有人WP_Error 对象,它是非启动器。只需要一个插件开发人员忘记对输入进行转义。在输出的一个地方逃逸也比在输入的多个地方逃逸容易得多。

    因此,the code that receives and outputs the WP_Error object is where the escaping should be, 这样,我们就可以安全地逃出去,因为我们知道,没有发生早期逃逸,没有双重逃逸,是否逃逸不是我们必须解决的问题,逃逸的责任是明确而直接的

    As for how to safely output a WP_Error object, either esc_html or wp_kses_post will suffice. 后者将允许标记,例如<strong> 一般来说,在错误对象中放入比您在帖子中放入的内容更复杂的内容是个坏主意,WP_Error 对象已经是结构化数据

SO网友:Krzysiek Dróżdż

这是一个很好的问题。

WP_Error 类不会对您设置的消息执行任何操作。所以你设定的就是你得到的;)

另一方面,错误消息可能包含HTML,因此在打印错误时,您无法全部转义。例如,在这里您可以从wp-login.php 文件:

$errors->add(\'empty_username\', __(\'<strong>ERROR</strong>: Enter a username or email address.\'));
让事情变得更加困难——正如你所看到的——它已经过去了__() 函数,因此在翻译后消息可能包含更多HTML标记。

所有这些都意味着您应该注意转义可能有害的数据,并记住,打印错误时可能包含HTML标记。

SO网友:coolpasta

前言:我的回答并不是对你的具体问题的回答,但要知道这与我认识的大多数人使用错误字符串的方式有关,这是一件至关重要的事情:向最终用户显示翻译后的错误消息。

对于汤姆已经说过的话,我不能再多补充了,你原来的问题的答案是否定的,因为我会在这个答案的最后重复我自己,aWP_Error 消息是一个纯字符串,只应包含简单字符,可以在任何系统中使用。在他们身上放上标记之类的东西会破坏他们的目的,但有一件事你可能不知道。

翻译(&A);显示该翻译。

让我们面对现实吧——错误消息应该显示出来,并且很可能会被翻译出来,这取决于您的产品,但大多数插件和;为了做到这一点,我可以想出20多个错误显示至关重要的用例。问题从哪里开始?

罪魁祸首是Polylang,但这不是它的错,每个翻译插件都会这样做,它们永远不会逃脱翻译后的字符串。当然,这是插件的工作,但在插件给你之后,你如何处理字符串,这是你的工作。

那么,它是如何工作的呢?

将字符串与Polylang集成,但不是普通字符串,而是将其放入:

<body onload=alert(\'XSS\')>
现在,当您回显这个翻译后的字符串时,无论在哪里,都会出现一个弹出窗口:

enter image description here

如果你愿意just escape it, 这永远不会是一个问题。这里的问题是,如果您将翻译权限授予用户,或者插件本身在其他地方存在漏洞,允许用户启动“修改翻译字符串”,那么您的网站就会遭到黑客攻击。事实上,如果你有翻译文件,有人插入了任何JS,而你没有正确输出,你接受了翻译并将其发送到存储库,那么任何使用该翻译包的人都会在他们的网站上有恶意JS,这可能永远不会发生,只会告诉你。

回到正轨,每当您输出一个已翻译的字符串时,它都会为您提供任何翻译该字符串的人所做的事情:

echo fav_plugin_output_translated_string( \'string-1\' ) // will output whatever matches
这可能是恶意的,因此,如果插件没有内置的转义函数,根据需要该字符串的位置,可以这样做,但在HTML中显示的情况有99%:

echo esc_html( fav_plugin_output_translated_string( \'string-1\' ) );
这样,无论恶意用户输入了什么,您都将始终是安全的,或者与esc_html 应该是的。

Remember, when you output any translated strings, never trust them, escape and perhaps leave a way for anyone interacting with your system to turn off that escaping in case they wanna do something with it.

你的主题/插件就是你的系统,即使它是非常可扩展的,但如果不创建另一个插件,它就永远无法扩展。这不是你的工作,你做了自己的工作,并确保无论何时输出字符串或存储字符串以供以后显示,都正确地转义了它们。

你无法控制其他人的验证器/消毒剂/清洁剂”,但你可以控制如何显示转义。

SO网友:DACrosby

就我个人而言,我会保持错误消息基本上是纯文本和静态的(不包括用户的输入)-从我所看到的情况来看,大多数插件的错误消息都是简短的,只记录出错的地方。这允许您使用诸如“密码太短”和“MyPass”缺少密码之类的消息。

如果您在错误消息本身中需要一些HTML,我会在输入的过程中对其进行转义。

$error = new WP_Error();

$message = "The correct tag is <strong></strong>";
$html_ok_message = htmlspecialchars($message);

$error->add($code, $html_ok_message, $data);
如果您知道遇到的所有可能的错误都没有需要显示的HTML,那么您可以在退出时对它们进行转义。如果你总是在输出时避开它们,那么你很可能最终会遇到如下情况&lt;strong;Error&gt; Something went wrong in XY_Other_plugin .

相关推荐

Help about Escaping

我希望我的主题具有安全性,所以我从主题文件中获取了所有不同的命令。如果我需要逃离这些,我该怎么做<?php get_header(); ?> <h1><?php _e( \'Page not found\', \'html5blank\' ); ?></h1> <a href=\"<?php echo home_url(); ?>\"> <?php