主题开发文档

💡 云策文档标注

概述

本文档作为 WordPress 安全编码的补充指南,强调在主题开发中防范常见漏洞的重要性,并指向 Common APIs Handbook 作为主要学习资源。文档概述了跨站脚本(XSS)、SQL 注入和跨站请求伪造(CSRF)等常见威胁及其防护技术。

关键要点

  • 安全编码是主题开发的核心责任,需警惕所有潜在利用途径。
  • Common APIs Handbook 的 Security 章节是主要学习来源,本文档为补充而非全面指南。
  • 常见漏洞包括跨站脚本(XSS)、SQL 注入和跨站请求伪造(CSRF),需使用特定函数如 esc_url()、wp_kses()、$wpdb->prepare() 和 wp_nonce_field() 进行防护。
  • 优先使用 WordPress API 函数(如 add_post_meta())以避免手动 SQL 操作,减少 SQL 注入风险。
  • 保持对安全漏洞的更新关注,推荐参考 WordPress Security Whitepaper 和 OWASP Top 10 等资源。

代码示例

// 转义图像 URL 以防止 XSS
<img src="<?php echo esc_url( $great_user_picture_url ); ?>" />

// 使用 wp_kses() 清理 HTML 内容
$allowed_html = array(
    'a' => array(
        'href' => array()
    ),
    'br'     => array(),
    'em'     => array(),
    'strong' => array()
);
echo wp_kses( $custom_content, $allowed_html );

// 使用 $wpdb->prepare() 防止 SQL 注入
$wpdb->get_var( $wpdb->prepare(
    "SELECT something FROM table WHERE foo = %s and status = %d",
    $name, // 未转义的字符串(函数将进行清理)
    $status // 不可信的整数(函数将进行清理)
) );

// 在表单中使用 nonce 防止 CSRF
<form method="post">
    <!-- 一些输入字段 ... -->
    <?php wp_nonce_field( 'name_of_my_action', 'name_of_nonce_field' ); ?>
</form>

注意事项

  • 安全环境不断变化,需持续关注新漏洞和防护技术。
  • 本文档仅提供常见漏洞概述,更多详细信息应参考 Resources 部分列出的资源。
  • 在主题中尽量避免复杂 SQL 查询,如需使用,务必依赖 $wpdb 函数进行防护。
  • CSRF 在插件中更常见,但主题若包含表单提交,也应使用 nonce 机制。

📄 原文内容

When releasing any code out into the world, whether it will only exist on your own site or hundreds of thousands of sites, it’s important to strive to make it as secure as possible. Responsible coding means being vigilant about all the ways your theme can be exploited.

Your primary source for learning about security in the Security chapter in the Common APIs Handbook. This article should be considered a supplement to what you will learn there and is not an all-encompassing guide on security itself. 

Below, you will find a list of common vulnerabilities to consider, but please use the Resources section for a more comprehensive overview of how to secure your themes.

Common vulnerabilities

Security is an ever-changing landscape, and vulnerabilities evolve over time. The following is an overview of common vulnerabilities you should protect against and the techniques for protecting your theme from exploitation.

Cross-Site Scripting (XSS)

Cross-Site Scripting (XSS) happens when a nefarious party injects JavaScript into a web page.

To avoid XSS vulnerabilities, any output should be escaped. Since it’s the theme’s primary responsibility to output content, you should always escape dynamic content with the proper function based on the data type.

This example shows how to escape an image URL to avoid XSS vulnerabilities:

<img src="<?php echo esc_url( $great_user_picture_url ); ?>" />

Content that has HTML entities within can be sanitized to allow only specified HTML elements:

$allowed_html = array(
	'a' => array(
		'href' => array()
	),
	'br'     => array(),
	'em'     => array(),
	'strong' => array()
);

echo wp_kses( $custom_content, $allowed_html );

SQL Injection

SQL Injection happens when values being input are not properly sanitized, allowing for any SQL commands in the data to potentially be executed. To prevent this, the WordPress API is extensive. For example, it offers functions like add_post_meta() so that you don’t need to manually insert metadata via SQL.

The first rule for hardening your theme against SQL Injection is: when there’s a WordPress function, use it.

While it is rare to do so in themes, sometimes you need to do complex queries that have not been accounted for in the API. If this is the case, always use the $wpdb functions. These were built specifically to protect your database.

All data in SQL queries must be SQL-escaped before the SQL query is executed to prevent SQL injection attacks. The best function to use for SQL-escaping is $wpdb->prepare() which supports both a sprintf()-like and vsprintf()-like syntax:

$wpdb->get_var( $wpdb->prepare(
	"SELECT something FROM table WHERE foo = %s and status = %d",
	$name, // an unescaped string (function will do the sanitization for you)
	$status // an untrusted integer (function will do the sanitization for you)
) );

Cross-Site Request Forgery (CSRF)

Cross-site request forgery or CSRF (pronounced sea-surf) is when a nefarious party tricks a user into performing an unwanted action within a web application they are authenticated in. For example, a phishing email might contain a link to a page that would delete a user’s account in the WordPress admin.

This is more common in plugins than themes. But if your theme includes any HTML or HTTP-based form submissions, use a nonce to guarantee a user intends to perform an action:

<form method="post">
	<!-- some inputs here ... -->
	<?php wp_nonce_field( 'name_of_my_action', 'name_of_nonce_field' ); ?>
</form>

Resources

Use the resources listed below to dive more deeply into securing your themes, plugins, and anything else you build on top of WordPress:

Staying current

It is important to stay current on potential security holes. The following resources provide a good starting point: