WP Total Hacks 1.8.0 – Pingbackをブロックする機能を追加しました。

WP Total Hacksをアップデートしてピンバックをブロックするための機能を追加しました。

https://wordpress.org/plugins/wp-total-hacks/

WP_Total_Hacks_‹_Welcome_to_the_Vagrant_—_WordPress

この機能を有効化すると、最近話題のピンバックを悪用した攻撃で踏み台になることを防ぐことができます。
企業サイトでは有効化しておくといいかもしれません。

一方でピンバックを受け付けなくなりますので、ブロガーさんとかは判断が難しいところですね。

具体的な実装はセキュリティ企業のSucuriの記事を参考にしました。

More Than 162,000 WordPress Sites Used for Distributed Denial of Service Attack | Sucuri Blog

以下のようにcurlで想定通り動作していることを確認済みです。

$ curl --header "Content-Type: text/xml" --data @pinback.xml http://example.com/xmlrpc.php
<?xml version="1.0" encoding="UTF-8"?>
<methodResponse>
  <fault>
    <value>
      <struct>
        <member>
          <name>faultCode</name>
          <value><int>-32601</int></value>
        </member>
        <member>
          <name>faultString</name>
          <value><string>server error. requested method pingback.ping does not exist.</string></value>
        </member>
      </struct>
    </value>
  </fault>
</methodResponse>

上のコードは実際にcurlで外部からWordPressサイトにピンバックを送って、その戻り値のXMLを出力したものです。

server error. requested method pingback.ping does not exist.

という行で、ピンバックが拒否されていることを確認した次第です。

あまりテストをしていないので、なにかあればツッコミ願います。

追記

いくつかのブログで以下のコードでブロックできるみたいなことが書いてありましたが、それは間違いです。

add_filter( 'xmlrpc_enabled', '__return_false' );

これはxmlrpcの中でもログインが必要なものだけをブロックするだけで、ピンバックはログインは不要なので効果がないです。

以下は、wp-includes/class-wp-xmlrpc-server.php内の該当部分のソースです。

/**
 * Log user in.
 *
 * @since 2.8.0
 *
 * @param string $username User's username.
 * @param string $password User's password.
 * @return mixed WP_User object if authentication passed, false otherwise
 */
function login( $username, $password ) {
    // Respect any old filters against get_option() for 'enable_xmlrpc'.
    $enabled = apply_filters( 'pre_option_enable_xmlrpc', false ); // Deprecated
    if ( false === $enabled )
        $enabled = apply_filters( 'option_enable_xmlrpc', true ); // Deprecated

    // Proper filter for turning off XML-RPC. It is on by default.
    $enabled = apply_filters( 'xmlrpc_enabled', $enabled );

    if ( ! $enabled ) {
        $this->error = new IXR_Error( 405, sprintf( __( 'XML-RPC services are disabled on this site.' ) ) );
        return false;
    }

    $user = wp_authenticate($username, $password);

    if (is_wp_error($user)) {
        $this->error = new IXR_Error( 403, __( 'Incorrect username or password.' ) );
        $this->error = apply_filters( 'xmlrpc_login_error', $this->error, $user );
        return false;
    }

    wp_set_current_user( $user->ID );
    return $user;
}

ちょっとまぎらわしいですよね。。。