与WordPress安全相关的一些建议

WordPress算是最易安装和使用的PHP程序之一,就在不久前,它在全网的使用率达到25% ,并且这个百分比会进一步变大(数据源:看这里)。

这意味着 WordPress 至少对开发者或使用者是友好的,不幸的是,这同样意味着 WordPress 是众多心怀不轨的黑客心目中的一个大蛋糕,可是,开发者或使用者可以通过通过听取以下几个建议让自己的 WordPress 实例更安全。

安全第一

像许多程序一样,WordPress 最大的安全威胁并非其自身代码或者服务器,而是与之交互的用户。

1.密码要够强壮

这里说的密码至少涵盖:服务器的SSH密码(如果你清楚的知道自己并没有SSH密码的话,可以忽略)、 FTP密码、MySQL密码、WordPress 管理员密码,它们要做够强壮。

WordPress 自 v3.7 版本起,已采用了一个基于Dropbox 的 zxcvbn 库的  密码强度指示器 ,这个工具能让你显而易见的知道自己的 WordPress 管理员密码的强壮度,但这是不够的,你还要同样重视上面提到的其它几个密码的强壮度。

2.使用密码管理工具

一个安全的密码应该是唯一的,也就是说,你最好不要在多个应用/网站上使用它,它应该仅仅用在一个地方: WordPress 管理员密码就是 WordPress 管理员密码,而不应该再被用在它处了,那么问题来了:密码要很强壮,那么它就很复杂并且很长,密码要是唯一的,那么,就会有许多密码,怎么办?答案是:你应该使用一个密码管理工具。

如果你经常使用 Windows 平台,你可以使用 KeePass ,这是一个开源软件,并且有简体中文包;如果你使用 Mac/Mac Book ,那么,你可以选择  1Password 或者 Lastpass 。

3.使用HTTPS

如果您的网站还未采用SSL,那么,它应该采用SSL。

你对网站的每一次访问,都会发送一个含有cookie的请求到网站服务器,如果某人要拦截这个请求,他们可以使用相同的 cookie 来冒充是你来做一些见不得光的不法勾当。

在服务器上安装SSL证书的代价并不像国内那些卖SSL证书的网站的标价那样吓人,许多主机商会以很优惠的价格出售SSL证书,安装此证书并正确设置了您的服务器环境( Nginx/Apache )之后,浏览器与您的服务器之间的通信/交互时加密的,也就是说,对这些通信/交互的拦截行为在大多数情况下都是无意义的了。

4.不要信任任何人

在保障了浏览器/客户端与您的网站服务器之间的通信时安全的前提下,该考虑下是谁在使用包括浏览器在内的客户端与您的网站通信了。

江湖险恶,你懂的,虽然我们应该相信大多数访客都是善良的,但是不能排除就有那么一小撮居心不良的人尝试以各种方法搞定您的网站,如果您对自己的网站持呵呵态度的话,看到这儿,您就可以关闭这个页面,该干啥干啥去了。

用户管理

上述建议可以说是泛泛而论,几乎适用于任何在线服务,以下是针对 WordPress 的具体安全建议。

5.一种用户,一个角色

一个常见的 WordPress 管理错误是在一个 WordPress 网站上干不同事儿的人,在使用一个用户账户 — 这个账户可能是在 WordPress 被安装时创建的,并且用户并还很可能是 admin (这得有多糟糕,建议你还是将其改为尽量臭长无意义一些更好),这样真的不好。

WordPress 内置了复杂精巧的角色和权限管理系统 ,您完全可以为不同的干不同事情的同事们每人分配一个用户账户,并且制定特定的角色。

长话短说,除非您需要修改管理员设置,否则不要使用管理员账户。

内置的“投稿者”这个角色用于创建内容(其创建的内容并不会即时发布);

内置的“作者”这个角色用于创建和发布内容;

内置的“编辑”这个角色用于创建、发布和修改其它用户发布的内容;

内置的“管理员”这个角色用于管理整个网站的一切

6.自定义用户角色和能力

您应该理解并能正确使用 WordPress 内置的角色与能力系统,这个系统内置的一些角色已经在上面列举了,每个角色都用不同的“能力”或者说权力,并且,您还可以自己创建角色以及与之相对应的“能力”。

举例来说:您在网站后台有个广告管理页面,并且您想仅有“广告管理员”身份的用户可以管理这个页面,可以这么搞:

//adding a custom "Ad Manager" role
function add_role_ad_manager() {
    add_role( 
        'ad-manager', 
        __( 'Ad Manager', 'cwp' ), 
        array( 
            'read'       => true, 
            'manage-ads' => true,
        )
    );
}
add_action( 'init', 'add_role_ad_manager' );

在创建了“广告管理员”这个角色后,就可以在这个广告管理页面的头部添加个判断了,示例如下:

if ( current_user_can( 'manage-ads' ) ) {
    // ... playground for ad manager...
} else {
    wp_die( __( 'WTF!You are not allowed to do this!.', 'cwp' ) );
}

代码安全

WordPress 开发者应遵循一些约定俗称的编码中的最佳实践,主要的原因是:涉及到安全。

7.过滤所有输入

这个是老生常谈了,大家都懂:不要相信任何的用户输入内容,因为用户输入的内容大多数情况下是要出现在查询或者插入之类的SQL语句的。

在 WordPress 的世界里,这意味着任何的 $_GET、$_POST、$_REQUREST 数据/变量都应该被过滤:

// basic filter example.
$integer = absint( $_GET['number'] ); // an integer > 0
$boolean = (bool) $_POST['selected']; // boolean
$title = sanitize_title( $_POST['title'] );      // sanitize a title input
$input = sanitize_textarea( $_POST['content'] ); // sanitize a textarea input

//if the content may contain HTML, pass it through "kses" to "strip evil scripts"
$content = wp_kses_post( $_POST['content'] );

//if you need to whitelist a specific array of tags, instead use wp_kses

$content = wp_kses( $_POST['input'], array(
    'a'      => array(
        'href'  => array(),
        'title' => array(),
    ),
    'br'     => array(),
    'em'     => array(),
    'strong' => array(),
) );

8.验证所有需要输出的数据

同样的,当您需要打印输出到浏览器时,您应该把数据库当做用户,不要相信它给你的东西,将它给你的数据也过滤一遍。

大多数主题作者在主题中输出一篇文章时,可能是这样的:

<article data-id="<?php echo $post->id; ?>">
    <title><?php echo $post->title; ?></title>
    <section>
        <?php echo $post->content; ?>
        <a href="<?php echo $post->permalink; ?>">Read more...</a>
    </section>
</article>

上面的示例看起来没什么不妥,其实不然,下面的这样才是安全的:

<article data-id="<?php echo esc_attr( $post->id ); ?>">
    <title><?php echo esc_html( $post->title ); ?></title>
    <section>
        <?php echo esc_html( $post->content ); ?>
        <a href="<?php echo esc_url( $post->permalink ); ?>">Read more...</a>
    </section>
</article>

善用 WordPress 内置的如下过滤函数,才会更安全:

  • esc_attr() 过滤 HTML attributes
  • esc_html() 过滤 HTML 内容
  • esc_url() 过滤 URL
  • esc_js() 过滤传递给 JavaScript 的值
  • esc_textarea() 过滤传递给 textarea 的值

更多数据验证函数的列表: WordPress Codex.

9.及时更新

当有重要的安全更新时, WordPress 可以自动更新 (自v3.7起),以保护您的网站,但并非全部需要更新的东西:WordPress 核心、主题、插件都是可以自动更新的,通常是会在网站后台给你一个更新提示,当你看到那个或者那些提示时,就应该在备份网站数据库后进行更新了。

当然了,及时更新并非仅包括 WordPress或者其主题、插件,还包括其运行环境:PHP版本是否过时?OpenSSL是否有新的补丁了?您使用的Nginx是否是最新的稳定版本?您使用的MySQL是否有安全威胁?

10.及时备份

这个算是后补的招数吧:当前面所有的建议你都做了,或者有哪些建议您没有做,导致网站被干掉,您可以先通过备份及时恢复在线业务,再通过分析服务器的日志来查找原因,以查漏补缺。

结论

以上所有所说的与 WordPress 安全相关的内容 对那些自以为“我只差一个程序员”的网站经营者或管理者是无效的,因为他们不知道什么是安全,更不了解 WordPress,总以为 WordPress 是免费的,它就得什么都给我做好,这种想法是错误的。本文首发索凌网络,转载请保留原始链接。