WordPress前端安全入门:转义那些东西

Avatar of Andy Adams
Andy Adams 发布

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200 美元的免费积分!

如果您是编写 HTML/CSS/JS 的 WordPress 开发人员(这包括 100% 的主题开发者和 99% 的插件开发者),那么您需要了解 WordPress 前端安全的基础知识。WordPress 提供了所有必要的工具,让您可以 使您的主题或插件安全。您只需要知道如何以及何时使用每个工具。

例如,作为前端开发人员,您的一项重大责任是防止未转义的内容打印到页面上

安全是您的责任

在我们讨论具体细节之前,我想消除一个我(以前)用来为“不太严格”的前端安全观点辩护的想法。

“如果黑客已经能够更改代码/数据库/内容,那么我的前端代码是否安全有什么区别?难道他们不能造成更大的损害吗?”

是的,如果黑客已经控制了代码或数据库,那么他们可能并不在乎输出的安全程度(他们可能无论如何都可以更改它)。

即便如此,您仍然有责任使前端代码安全。以下是一些原因:

  • 适当的前端安全还可以防止用户错误导致重大问题。如果用户意外地在不应输入的字段中输入了特殊字符,页面就不会崩溃。
  • 某些攻击是有限的。也许黑客的控制权很小,只能更改数据库中的单个内容片段。您可以防止这种狭窄的攻击变得更大。
  • 安全就像洋葱。最外层(通常不可食用)是前端显示。良好的安全实践使黑客稍微难以利用网站。

打鸡血的话就说到这里了。让我们来谈谈如何保护我们的 WordPress 主题和插件。

我们担心什么?

前端开发人员的一个主要关注点是避免跨站点脚本(简称 XSS,因为“CSS”会导致各种问题。双关语和妙语欢迎。)。

XSS 漏洞允许坏人(“黑客”)窃取信息。通常这意味着窃取 cookie 和会话信息。如果坏人可以将您的活动会话发送回自己(因此有了“跨站点”部分),他们可以使用它登录到您的帐户并执行您可以执行的任何操作(坏消息)。

什么是转义?

在计算机科学中,“转义”一词具有特殊的含义。

将字符或字符串转换为在特定上下文中按字面解释,通常是为了防止这些字符被解释为代码。

换句话说,在 WordPress 前端开发的上下文中:转义将可能存在恶意的内容转换为安全的内容。

这里最大的危险通常是<script>标签和其他执行 JavaScript 的方法(例如onclick="javascript:")。如果可以在页面上输出并执行<script>,那将非常危险。转义意味着将其转换为&lt;script&gt;,这是安全的。

为什么需要转义:一个例子

如果您不熟悉 XSS,一个简单的例子将展示风险。

假设您的主题有一个字段可以添加阅读链接。“阅读更多”链接,如果可以这样说。在 WordPress 仪表板上,它可能如下所示:

Custom Field

在您的主题中,您希望在文章底部显示此链接,如下所示:

Custom Field on the Front End

因此,您打开single.php(负责显示博客文章的文件)并在底部附近添加以下内容:

<?php 
  $read_more_link = get_post_meta( 
    get_the_ID(), 
    'read_more_link', 
    true 
  ); 
?>

<!-- Don't do this -->
<a href="<?php echo $read_more_link; ?>">Read More</a>

假设有人恶意地将以下文本输入到您的自定义字段中:

Custom Field With Evil Script

当您访问页面时,您将看到以下内容:

Evil Script Executed!

糟糕!如果该错误输入允许坏人执行 JavaScript,他们可以:

  • 重定向用户
  • 劫持用户的 cookie
  • 执行其他恶意操作

为所有内容转义

既然我们知道了转义的重要性,让我们看看 WordPress 提供的转义方法,并为每个方法提供一些上下文。

函数:esc_html

用于:输出绝对不应该在输出中包含任何 HTML 的内容。

作用:将 HTML 特殊字符(例如<>&)转换为其“转义”实体(&lt;&gt;&amp;)。

一个常见的示例是在主题中显示纯文本自定义字段。

<?php $dog_name = get_post_meta( $post_id, 'dog_name', true ); ?>
<span class="dog-name"><?php echo esc_html( $dog_name ); ?></span>

esc_html 的 Codex 条目

函数:esc_attr

用于:在 HTML 属性上下文中使用的输出(例如“title”、“data-”字段、“alt”文本)。

作用:esc_html完全相同。唯一的区别是不同的 WordPress 过滤器应用于每个函数。

以下是esc_attr在图像上的使用示例:

<img src="/images/duck.png" 
alt="<?php echo esc_attr( $alt_text ); ?>" 
title="<?php echo esc_attr( $title ); ?>" >

esc_attr 的 Codex 条目

函数:esc_url

用于:必须是 URL 的输出。例如图像src属性和href值。

作用:esc_attresc_html函数更彻底、更具体的转义,它将 URL 中不允许的任何字符删除或转换为其 URL 安全格式。

当您需要输出链接或动态图像路径时,请使用esc_url

<a href="<?php echo esc_url( $url ); ?>">Link Text</a>
<img src="<?php echo esc_url( $image_url ); ?>" >

esc_url 的 Codex 条目

函数:esc_js

用于:打印 JavaScript 字符串,主要用于内联属性,例如onclick

作用:转换特殊字符,例如<>、引号——任何可能破坏 JavaScript 代码的内容。

由于以下几个原因,esc_js可能是最少使用的 esc_ 函数。

  1. 大多数 JS 加载在单独的文件中。
  2. 大多数 JS 不是作为属性内联编写的。
  3. 对于非内联 JS,json_encode是更好的选择。

但是,如果您需要转义一些内联 JS,则可以按照以下方法操作:

<?php $message = get_post_meta( get_the_ID(), 'onclick_message', true ); ?>
<a href="/blog/" onclick="alert('<?php echo esc_js( $message ); ?>')">...</a>

esc_js 的 Codex 条目

函数:json_encode

用于:打印 PHP 变量以供 JavaScript 使用。

作用:将 PHP 变量(对象、字符串、数组等)转换为该 PHP 变量的合理、转义的 JavaScript 表示形式。

尤其对于使用 WP 变量的<script> 代码块很有用。一个简单的例子

<

预设 rel=”PHP”><?php $categories = get_categories(); ?>

<script type="text/javascript">
var allCategories = <?php echo json_encode( $categories ); ?>;
// 在这里对分类进行一些有趣的操作
</script>

PHP 中 json_encode 的参考

函数:wp_kses

用途:需要允许某些 HTML 但不允许所有标签或属性的输出。

功能:去除内容中与传入规则列表不匹配的任何标签或属性。

如果某个上下文允许打印某些标签(例如,像<strong> 和<em> 这样的内联格式化标签)作为 HTML,则使用wp_kses

一个基本的例子是显示评论

, , 和 标签数组( ‘a’ => array( // 在这里,我们把 ‘href’ 和 ‘title’ 属性列入白名单 – 其他都不允许! ‘href’ => array(), ‘title’ => array() ), ‘br’ => array(), ’em’ => array(), ‘strong’ => array() ) ); ?>

wp_kses 的 Codex 条目

转义函数 (esc_attr_e, esc_attr_x) 的 _e 和 _x 版本是什么?

这些是便捷函数(为了让你的生活更轻松),在打印可翻译字符串时很有用:可以通过 WordPress 翻译文件更改的文本。

如果你正在开发一个主题或插件以供广泛分发(而不是一个一次性的客户端项目),你将希望使每个字符串都支持国际化。这意味着曾经由你控制的 PHP 字符串可以由翻译人员编辑 – 因此需要转义(你不能相信任何人

Blog

_e 函数的第二个参数是翻译域。翻译人员在编写和生成翻译时会使用它。

_x 函数(如 esc_html_x)基本上与其_e 对应项相同,但增加了一个“上下文”参数来解释单词或短语的使用上下文。对于具有多种含义的单词很有用



  

esc_attr_e 的 Codex 条目
esc_attr_x 的 Codex 条目

the_titlethe_content 怎么样?

如果你打开默认的 WordPress 主题(在撰写本文时名为“Twenty Fifteen”),你会看到类似这样的代码输出文章的标题

‘, ” ); ?>

你还会看到像这样未转义的 the_content 调用

你可能会感到恐慌。为什么这些函数没有转义?!两个原因

1. WordPress 自动转义它们

the_title 这样的函数是便捷函数 – 使前端开发更容易的工具。因此,为了使开发人员更轻松WordPress已经自动转义了the_title 的输出 更新:WordPress不会转义the_title,请小心!.

2. 上下文:某些内容是 HTML

the_content 的情况下,输出预期未转义的 HTML。当用户在内容中添加

时,我们可以假设他们实际上想要一个

输出到页面 – 而不是转义后的版本。

如果你担心用户能够在 the_content 的输出中添加脚本,你可以使用 wp_kses 从最终输出中去除不需要的标签。这在子域名和共享主机上很有用,而且我非常确定他们在 WordPress.com(一个托管版的 WordPress,用户不允许添加自己的 JavaScript)上使用的是这种方法。

实用技巧:如果你想将 the_title 用作 HTML 属性,请使用 the_title_attibute 来节省转义操作。the_title_attribute 的实际应用

...

转义内容

我使用过很多插件和主题 – 商业的、免费的和自定义构建的 – 我看到了大量未转义的内容(以及由此产生的 XSS 漏洞)。希望本文能为你提供使你的 WordPress 更加安全的基本工具。

我是否忽略了什么?请在评论中告诉我!