多くのWEBサイトで利用されているCMS「WordPress」ですが、初期状態では多くのセキュリティホール(セキュリティの脆弱性)があるのはご存知でしょうか。
特に問題なのはログインページが誰でもアクセス可能であることです。
この記事では、ログインページがデフォルトだと、どのように不正ログインされてしまうのかと、WordPressのテーマのfunctions.phpにコピペするだけで簡単にログインページを変更する方法を紹介します。
今回の記事ではfunction.php(WordPressのシステム部分のファイル)の変更を行います。バックアップを取った上で作業してください。また、WordPressが動かなくなった場合、お問い合わせから相談をお受けしますが、複雑な状況である場合、復旧の保証は致しかねます。
目次
初期設定の不正ログイン攻撃
WordPressのログインページは初期状態では、WordPressのインストールされているディレクトリ/wp-login.phpでアクセスすることが可能です。仮にWordPressのインストール箇所を移動していたとしても、ログインページを隠す対策をしていない限り、WordPressのログインページを見つけることは知識のある攻撃者からしたら容易です。
ログインページにアクセスできたからとはいえ、簡単にログインできるとは限らないと思うかもしれません。WordPressのログインには、ユーザー名またはメールアドレスとそのユーザーのパスワードが必要です。
この2つの組み合わせは実質無限であり、総当たり攻撃(ブルートフォース攻撃やパスワードリスト攻撃)をされる可能性も少ないでしょう。
何も対策していない状態の場合、もしテーマとかで使用していないとしてもユーザー名は簡単にバレてしまいます。
WordPressはトップページのURL末尾に?author=1
とつけると、/author/ユーザー名/
というURLにリダイレクトされてしまいます。これでユーザー名が取得されますので、あとはログインページでパスワードを総当たり攻撃することで不正ログインが完了してしまいます。
ログインページを変更する
それでは早速ログインページを変更することができるプログラムを紹介します。
下記のプログラムをテーマのfunctions.phpに記述してください。今回はログイン関連の変更を行うため、WordPressのテーマエディタから変更するのではなく、FTPに接続しfunctions.phpをアップロードする方法でプログラムの追記をすることをおすすめします。
functions.phpを編集する際は念のためバックアップを作成するようにしましょう。
/**
* ログインURLを変更
*/
if (!class_exists('Login_Security')) :
class Login_Security
{
const DEFAULT_LOGIN_NAME = 'wp-login.html';
public function __construct()
{
$this->init();
}
private function init()
{
$this->hooks();
}
private function hooks()
{
add_action('template_redirect', array($this, 'login_redirect'));
add_action('login_init', array($this, 'return_error_default_login_url'));
add_filter('site_url', array($this, 'login_change_site_url'), 10, 2);
add_filter('wp_redirect', array($this, 'login_wp_redirect'));
}
public static function return_error_default_login_url()
{
if (!defined('LOGIN_CHANGE') || sha1('page_changed') !== LOGIN_CHANGE) {
global $wp_query;
$wp_query->set_404();
status_header(404);
get_template_part(404);
exit;
}
}
public static function login_change_site_url($url, $path)
{
$require_login_name = apply_filters('login_endpoint_name', self::DEFAULT_LOGIN_NAME);
if (strpos($path, 'wp-login.php') !== false
&& (is_user_logged_in()
|| strpos($_SERVER['REQUEST_URI'], $require_login_name) !== false)) {
$url = str_replace('wp-login.php', $require_login_name, $url);
}
return $url;
}
public static function login_wp_redirect($location)
{
$require_login_name = apply_filters('login_endpoint_name', self::DEFAULT_LOGIN_NAME);
if (strpos($_SERVER['REQUEST_URI'], $require_login_name) !== false) {
$location = str_replace('wp-login.php', $require_login_name, $location);
}
return $location;
}
public static function login_redirect()
{
$full_uri = (is_ssl() ? 'https' : 'http') . '://' . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"];
$full_uri = explode('?', $full_uri)[0];
$require_login_name = apply_filters('login_endpoint_name', self::DEFAULT_LOGIN_NAME);
if ($full_uri === home_url('/') . $require_login_name) {
header("HTTP/1.1 200 LOGIN PAGE");
define('LOGIN_CHANGE', sha1('page_changed'));
require_once(ABSPATH . '/wp-login.php');
exit;
}
}
}
new Login_Security;
endif;
add_filter('login_endpoint_name', function() {
return 'login';
});
/** / ログインURLの変更 */
最後から4番目の行のreturn 'login';
の部分を変更することで、ログインURLが変更できます。
例えば、return 'secret_login_page.html';
と変更した場合、WordPressのインストールされている階層の後に/secret_login_page.htmlがログインページになります。
https://blog.zaty.jp/secret_login_page.html
(これはサンプルなので、実際にアクセスしても404です。)
このコードを追加することで、ログアウトやタイムアウトでのログアウトした際のモーダルログインフォームなど既存にあるログイン周りの機能も全て新しいログインページに置き換わります。
そのほかのログインページのためのセキュリティ対策
ログインページを隠すだけでは完全なセキュリティ対策とはいえません。ログインページを隠す以外のセキュリティ対策を紹介します。
以下のセキュリティ対策と併用することで強力なログインページとすることができます。
Google reCAPTCHAを使う
Google reCAPTCHAは、お問い合わせやコメントフォームなどで見たことあると思います。reCAPTCHAはフォームの入力が人間かBOTかどうかを判断します。
お問い合わせでのスパムやスクレイピングの対策など様々な対策になります。ログインフォームの対策としては「ブルートフォース攻撃」「パスワードリンク攻撃」の対策として有用です。
reCAPTCHAは画像を選択するものや、BOTではないのチェックを入れるものが有名ですが、現在は、普通にログインするだけで人間である判定をしてくれるAPI(機能)も存在します。
画像認証を行う
画像認証はランダムな4文字のひらがなやアルファベットを入力するフォームがある認証方法です。
これもブルートフォース攻撃に有用な対策です。ブルートフォース攻撃は自動化したプログラムを使用しています。画像認識を使用することでreCAPTCHA同様、BOTに対するセキュリティ対策になります。
Google Authenticatorを利用する
Google AuthenticatorはAuthenticatorという2段階認証アプリを使った認証システムです。ログイン完了後に2段階認証をさせることでかなり強固がセキュリティ対策になります。
Google Authenticatorについては別で運用しているブログサイトで、AuthenticatorをPHPで利用する方法などと共に紹介しているので、ぜひそちらもあわせてご覧ください。
GitHubでそのまま使えるWordPress Pluginも公開しています。リポジトリはこちら。
まとめ
今回はログインページのURLを変更する方法と、さらに有効なセキュリティ対策を紹介しました。
紹介したセキュリティ対策は公開されているプラグインでも利用可能です。プラグインを使用する際には開発元と開発頻度、その他セキュリティホールの報告がないかなど、問題ないことを確認するようにしましょう。
4/30追記
もし、jQueryをフロントテーマで使用しないため、デフォルトのjQuery読み込みを削除している場合は、新しいログインページではjQueryを利用するように分岐をし直す必要があります。
この設定をしないと、パスワードの表示非表示設定や言語選択の挙動が正しく機能しなくなります。セキュリティ上大きな欠点ではありませんが、使いづらくなるので、設定するようにしてください。
function delete_jquery () {
if( !is_admin() && !is_login_page() ) {
wp_deregister_script( 'jquery' );
}
}
このような記述がfunctions.phpなどにある場合、以下のように変更してください。
function delete_jquery () {
if( !is_admin() && !is_login_page() && !defined('LOGIN_CHANGE') ) {
wp_deregister_script( 'jquery' );
}
}
よくある質問
ログインページのURLを変更することで、本当にセキュリティが向上するのですか?
ログインページのURLを変更することで、攻撃者がログインページを見つけにくくなります。ログインページが特に攻撃されやすいページです。
ただし、ログインページを変更するだけではセキュリティ対策としては不十分です。複数のセキュリティ対策を併用することで強固なログインページとなります。
ログインページのURLを変更すること以外にはどのようなセキュリティ対策が有用ですか?
以下のセキュリティ対策を組み合わせて利用することで強固なログインページにすることができます。
- 二段階認証の導入
- Google reCAPTCHAの導入
- 長く複雑なパスワードを使用する
- パスワードの入力回数を制限する
- 画像認証を導入する
WordPressではプラグインを利用することでも対策が可能です。プラグインを利用する場合は、開発元の信頼性、開発頻度、セキュリティホールの報告がないかなどを確認するようにしましょう。
ログインページを変更しようとしてfunctions.phpを変更したらサイトが動かなくなりました。どうしたらいいですか?
今回は、functions.phpの変更のみなので、変更した箇所を修正するかバックアップのfunctions.phpに戻すことで復旧できます。
もし、WordPressのテーマエディタからプログラムの変更を行い、WordPressが動かなくなった場合は、FTP接続をし、functions.phpのバックアップ修正を行なってください。
FTPがわからない、functions.phpを修正しても復旧できない場合は、ZATYのお問い合わせからご相談ください。