Help us understand the problem. What is going on with this article?

[WordPress] /?author=xx をちゃんと阻止した話

2019.04.16補足
実際に実装してみたところ、[2017.05.29補足]のようにhtaccessに1行を追加すると、

/?author=1 => /author/hoge => 302 redirect

となり、/author/hoge を経由してしまうため本文同様(ログインIDが明示される)の状態になります。

RewriteRule ^\?author=(.*)? / [R=302,L]

も併せて設定されることをおすすめします。


2017.05.29補足
PHP(Wordpress)上でリダイレクトを行わなくても、htaccessに一行足せば簡単に問題が解決しました...。

RewriteRule ^author/(.*)? / [R=302,L]

mikkame 様からご指摘を受けました。ありがとうございます。


事の発端

とある管理サイトでの話。
/?author=xxでユーザーのログインIDが漏れるのは知っていたので

author.php
<?php header('Location: ' . get_bloginfo('url') . '/403.php'); exit; ?>

と403ページへ転送していました。
これに加えてAudit Trailというプラグインでログイン失敗だけ記録

これでひとまず安心...。しかしレンタルサーバーのエラーログを見ていたら

Error.log
WordPress Login Failure: adminID from xxx.xxx.xxx.xxx

と、ログインIDがバレていた!!

どうしてだろうか...

前後のエラーログやアクセスログを見ても/?author=xxxmlrpc.phpへのアクセスばかりでさっぱりわからず。

xmlrpc.phpも念のためアクセス制限をかけていました。使わないので。

<Files "xmlrpc.php">
order deny,allow
deny from all
</Files>

curl

ダメ元でcurlコマンドで叩いてみました。

# オプションなし
$ curl http://example.com/?author=xx

リダイレクト処理を行っているので応答なし。

そこでもしや、と思い -v をつけてHeaderを表示。

# リクエストヘッダーとレスポンスヘッダーの両方を見ることができます。
$ curl http://example.com/?author=xx -v
*   Trying xxx.xxx.xxx.xxx...
* TCP_NODELAY set
* Connected to example.com (xxx.xxx.xxx.xxx) port 80 (#0)
> GET /?author=xx HTTP/1.1
> Host: example.com
> User-Agent: curl/7.51.0
> Accept: */*
> 
< HTTP/1.1 301 Moved Permanently
< Date: Sun, 28 May 2017 19:07:33 GMT
< Server: Apache/2.2.31
< X-Powered-By: PHP/5.6.30
< Location: http://example.com/author/adminID/
< Content-Length: 0
< Content-Type: text/html; charset=UTF-8
< 
* Curl_http_done: called premature == 0
* Connection #0 to host example.com left intact

なんと、ヘッダーに隠したはずのログインIDが書かれているではないですか!!

対応策

大急ぎで対応を検討しました。
しかし、Headerの出力をWordPressで制御するのは大変。
そこで以下のようにリライトを制御。author.phpを経由することなくTOPページへリダイレクトするようにしました。

functions.php
function author_custom_redirection() {
    global $wp_rewrite;
    $wp_rewrite->flush_rules();
    $wp_rewrite->author_base = '';
    $wp_rewrite->author_structure = '/';
    if (isset($_REQUEST['author']) && !empty($_REQUEST['author'])) {
        wp_redirect(home_url());
        exit;
    }
}
add_action('init', 'author_custom_redirection');

補足
のちの参考リンク先ではif分岐が一段多いですが、これはログイン済みユーザーと非ログイン者とで処理を分けているからです。今回はログイン済みユーザーもauthor.phpを見ることができない仕様にしました。

# リクエストヘッダーとレスポンスヘッダーの両方を見ることができます。
$ curl http://example.com/?author=xx -v
*   Trying xxx.xxx.xxx.xxx...

# ### 中略 ###

< HTTP/1.1 301 Moved Permanently
< Date: Sun, 28 May 2017 19:07:33 GMT
< Server: Apache/2.2.31
< X-Powered-By: PHP/5.6.30
< Location: http://example.com
< Content-Length: 0
< Content-Type: text/html; charset=UTF-8
< 
* Curl_http_done: called premature == 0
* Connection #0 to host example.com left intact

無事にHeaderからもログインIDが消えました!!

まとめ

/?author=xxを非表示にする方法としてよく挙がる「author.phpからのリダイレクト」では抜け穴があることを学べました。ありがとうございました。

参考リンク

authorクエリを利用したWordPressのユーザー名漏洩を防ぐ方法

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした