WordPressセキュリティの教科書|ハッキングされて泣く前にエンジニアがやっておくべき鉄壁の防御術

目次

対策をしていない素人の管理者が多い

日曜日の夜23時。自宅のソファで映画を見てくつろいでいたとき、スマホが不快な音を立てて震えました。
画面には、先日納品したばかりのクライアントである社長の名前が表示されています。
こんな時間の電話にろくな用件はありません。嫌な予感を押し殺しながら恐る恐る電話に出ると、受話器の向こうからパニック寸前の声が耳に飛び込んできました。

「会社のサイトを開くと、変な英語の薬の通販ページに飛ばされるんです。どうなってるんですか」

心臓が早鐘を打ちました。すぐにPCを開いて該当のサイトにアクセスしてみます。
一瞬だけ見慣れたトップページが表示されたかと思った直後、画面が暗転し、見たこともない海外の怪しげなショッピングサイトへと強制的にリダイレクトされました。
ブラウザのアドレスバーを確認すると、ドメインは間違いなくクライアントのものなのに、表示されているコンテンツは完全に乗っ取られている状態。
いわゆる「改ざん」です。

深夜のデスクで、改ざんされたサイトを目の当たりにして顔面蒼白になっているエンジニアの線画イラスト

背筋が凍るとはまさにこのことでした。
そのサイトは、私が半年前に納品したコーポレートサイトでした。予算の都合上、納品後の保守契約を結んでいなかったため、WordPressの本体やプラグインのバージョンは納品時のまま放置されていました。
サーバーのログを洗うと、数週間前から海外IPによる不審なアクセスが急増しており、最終的に古いプラグインの脆弱性を突かれ、バックドア(裏口)を仕掛けられていたことが判明しました。

復旧には丸3日かかりました。サーバーにある数千個のファイルをすべてチェックし、汚染されたデータベースをクリーニングし、検索エンジンにインデックスされてしまった大量のスパムページを削除する申請を送る。
その間、サイトは「緊急メンテナンス中」のまま。クライアントの機会損失は計り知れませんし、何よりエンジニアとしての私の信用は崖っぷちでした。

「もっと強く、しつこいくらいに保守の重要性を伝えておけばよかった」
後悔しても後の祭りでした。

エンジニアとしてWeb制作に関わる以上、セキュリティは避けては通れない道です。
よく「WordPressはセキュリティが弱い」なんて言われることがありますが、それは大きな間違いです。
正しくは「世界で最も利用者が多いCMSだから攻撃の標的になりやすく、かつ対策をしていない素人の管理者が多いから被害が目立つ」だけなのです。
鍵をかけずに外出している家が泥棒に入られるのと同じで、適切な鍵さえかけておけば、そう簡単に侵入されるものではありません。

今回は、私があの悪夢のような夜を二度と繰り返さないために、現場で徹底している「WordPressのセキュリティ対策」について、泥臭い経験談と技術的な裏付けを交えながらすべてお話しします。
教科書的な「パスワードを強くしましょう」程度の話で終わらせるつもりはありません。
攻撃者がどこを見て、どうやって侵入してくるのか。それを防ぐために、具体的にどのファイルに何を書き込めばいいのか。
実務で使えるレベルの知識を、余すところなく共有します。

非常に長い戦いになりますが、これを読み終わる頃には、あなたの構築するサイトは隙だらけの小屋から「鉄壁の城」に生まれ変わっているはずです。

なぜWordPressばかりが狙われるのか

対策をする前に、まずは敵を知ることから始めましょう。
なぜ世界中のハッカーたちは、執拗にWordPressを狙うのでしょうか。
「うちみたいな地方の小さな工務店のサイトなんて、金目の情報もないし誰も狙わないだろう」
そう思っているクライアントやエンジニアがいたら、今すぐその甘い認識を捨ててください。インターネットの世界に「安全地帯」など存在しません。

攻撃者はあなたを見ていない

ハッカーは、特定のサイトを恨んで攻撃しているわけではありません(もちろん、そういう標的型攻撃も稀にありますが、大半は違います)。
彼らは「Bot(ボット)」と呼ばれる自動化プログラムを使って、インターネット上にあるWordPressサイトを無差別に探索しています。
Botは24時間365日、休むことなく世界中のサーバーを巡回し、ドアノブをガチャガチャと回し続けています。
「WordPressで作られたサイトはないか」「バージョンが古いまま放置されているサイトはないか」「パスワードが admin のままのサイトはないか」
こうやって機械的にスキャンしているのです。

そして、セキュリティの甘いサイトを見つけると、自動的に攻撃スクリプトを実行します。
そこに「大手企業だから」とか「個人の日記ブログだから」といった区別はありません。
開いているドアがあれば、とりあえず入って荒らす。それが彼らのやり方です。
あなたが「狙われるようなサイトじゃない」と思っていても、Botにとっては「侵入可能なIPアドレス」の一つでしかないのです。

攻撃の目的は「踏み台」と「リソース泥棒」

侵入して何をするかというと、多くの場合、そのサイト自体を破壊したり、情報を盗んだりすることが主目的ではありません。
あなたのサイトを「踏み台」にすることが目的なのです。

一つは、スパムメールの送信拠点としての利用です。
あなたのサーバーから、何万通もの詐欺メールやウイルスメールをばら撒くのです。
こうなると、あなたのドメインはブラックリストに登録され、通常のメールすら届かなくなります。

もう一つは、フィッシング詐欺サイトの設置です。
銀行やクレジットカード会社を装った偽サイトをあなたのドメイン配下に設置し、そこへ誘導して個人情報を盗み取ります。
被害者からすれば、URLはあなたのサイトなわけですから、あなたが詐欺に加担しているように見えてしまいます。

さらに最近多いのが、サーバーのリソースを勝手に使って仮想通貨のマイニング(採掘)を行わせるケースです。
サイトが異常に重いなと思って調べたら、裏でマイニングプログラムがフル稼働していた、なんてこともあります。

つまり、被害者になるだけじゃなく、知らない間に加害者になってしまうリスクがあるということ。
これが一番怖いのです。
自分の管理していたサイトから何万通ものスパムメールがばら撒かれたとしたら、エンジニアとしての信用は地に落ち、最悪の場合、損害賠償請求に発展する可能性すらあります。

ログイン画面は「玄関」である

セキュリティ対策の一丁目一番地は、ログイン画面の防御です。
ここを突破されたら、管理者権限を奪われ、何をされても文句は言えません。
WordPressのデフォルト設定では、ログインURLは「ドメイン/wp-login.php」または「ドメイン/wp-admin」と決まっています。
これは世界共通の規格であり、周知の事実です。
つまり、攻撃者はあなたのサイトのログイン画面の場所を最初から知っているということです。
住所を知られている家の玄関に、鍵もかけずにいるようなものです。これでは侵入してくださいと言っているようなものでしょう。

ログインURLを変更する技術

まずやるべきは、この「玄関の場所」を隠すことです。
物理的な場所を変えるわけではありませんが、入り口となるURLを変更することで、機械的な攻撃をシャットアウトできます。
functions.php をいじってリライトルールを変更することもできますが、記述をミスするとサイト全体が見られなくなるリスクがあるため、メンテナンス性を考えるとプラグインを使うのが現実的です。

私が日本の案件で必ず導入しているのが「SiteGuard WP Plugin」です。
国産のセキュリティプラグインで、日本語の説明がわかりやすく、機能も必要十分です。海外製の多機能すぎるプラグインは設定が複雑で、逆にセキュリティホールになることもあるため、シンプルで信頼性の高いものを選びます。

このプラグインを有効化して「ログインページ変更」の設定をオンにすると、ログインURLを好きな文字列に変更できます。
たとえば「ドメイン/my-secret-gate」のように変えてしまうのです。
これだけで、機械的に「/wp-login.php」にアクセスしてくるBot攻撃をすべて「404 Not Found」として弾くことができます。
玄関の場所が変われば、そもそもノックされることすらなくなりますからね。
ただし、変更後のURLを忘れると自分も入れなくなるので、必ずブックマークをしておくことを忘れないでください。

ユーザー名「admin」は即刻削除せよ

これも基本中の基本ですが、意外と残っているサイトが多いです。
ユーザー名を「admin」や「info」、「webmaster」、あるいは「ドメイン名そのもの」にしていませんか。
攻撃者は、パスワードを総当たりで試す「ブルートフォースアタック(総当たり攻撃)」を仕掛けてきます。
その際、ユーザー名は真っ先に「admin」で試されます。これは攻撃ツールにデフォルトで設定されているからです。
もしユーザー名が「admin」で、パスワードが「password123」や「12345678」なんてサイトがあったら、3秒で突破されますよ。

必ず推測されにくいユーザー名に変更してください。
すでに「admin」で運用してしまっている場合は、新規に管理者権限のユーザーを作成し、古い「admin」ユーザーを削除します。その際、投稿した記事を新ユーザーに引き継ぐ設定を忘れずに行えば、コンテンツが消えることはありません。

ユーザー名の漏洩を防ぐ

WordPressには、セキュリティ的に少しおせっかいな仕様があります。
「ドメイン/?author=1」のように、著者IDを指定してアクセスすると、「ドメイン/author/ユーザー名」というURLにリダイレクトされるのです。
これにより、ログインID(ユーザー名)が外部にバレてしまいます。
IDがバレれば、あとはパスワードを当てるだけになってしまい、攻撃のハードルが半分下がります。

これを防ぐためにも、「Edit Author Slug」などのプラグインを使って、URL上のユーザースラッグ(表示される名前)をログインIDとは別のものに変更するか、functions.php にコードを書いて著者アーカイブ自体を無効化しておくのがプロの仕事です。
ログインIDは、パスワードと同じくらい重要な機密情報だという認識を持ってください。

攻撃者が自動プログラムを使って次々とログインを試行しているイメージ図

本体・テーマ・プラグインのアップデートは義務

「アップデートするとサイトが壊れそうで怖いから、そのままにしてます」
このセリフ、クライアントから何度聞いたかわかりません。
気持ちはわかります。WordPressのメジャーアップデートで画面が真っ白になるトラブルや、プラグインの互換性がなくなってレイアウトが崩れる事故は、確かに存在しますから。
でも、セキュリティの観点から言えば、アップデートしないことは「穴の空いた壁をそのまま放置する」のと同じ、いやそれ以上の自殺行為です。

脆弱性情報は公開されているという事実

WordPress本体やプラグインにセキュリティ上の欠陥(脆弱性)が見つかると、開発者は修正版をリリースします。
そして、「ここのコードに欠陥があったので直しました」という情報も公開されます(リリースノートやCVEデータベースなど)。
これは、善良な管理者にとっては「早く直さなきゃ」という警鐘ですが、攻撃者にとっては「攻撃のヒント」が答え合わせ付きで公開されているのと同じなのです。

「バージョンX.X以下のこのプラグインには、ここからSQLインジェクションができる穴がある」と世界中にアナウンスされているようなものです。
その状態で古いバージョンを使い続けることが、いかに危険か想像できますよね。
特に有名なプラグイン(Contact Form 7やAll in One SEOなど)の脆弱性は、公開された数時間後には世界中でその穴を狙う攻撃が始まると言われています。スピード勝負なのです。

バックアップがあれば怖くない

アップデートの恐怖に打ち勝つ唯一の方法は、「確実なバックアップ」を取ることです。
「何かあっても元に戻せる」という保証があれば、アップデートは怖くありません。

「All-in-One WP Migration」や「UpdraftPlus」といったプラグインを使えば、データベースもファイルも丸ごとバックアップできます。
さらに言えば、サーバー側の自動バックアップ機能も確認しておきましょう。
XserverやConoHa WINGなどの主要なレンタルサーバーなら、過去数日分から2週間分程度のバックアップを自動で取ってくれています。
復元ボタン一つで昨日の状態に戻せる機能があるサーバーを選ぶのも、エンジニアの重要な選定基準です。

私は保守契約を結んでいるクライアントの場合、必ず本番環境とは別に検証環境(ステージング環境)を用意し、そこで一度アップデートをテストしてから、本番環境に適用するようにしています。
そこまでやるのが、お金をもらって管理する人間の責任だと思っています。

不要なファイルは「裏口」になる

サーバーの中に、使っていないテーマやプラグインが残っていませんか。
「無効化しているから大丈夫」は大間違いです。
PHPファイルとしてサーバー上に存在している以上、外部から直接そのファイルにアクセスされて、脆弱性を突かれる可能性があります。
実際に、無効化していたプラグインの脆弱性を突かれてサイトを乗っ取られた事例は山ほどあります。
使わないプラグインは「無効化」ではなく「削除」する。これが鉄則です。
テーマについても同様で、現在使用しているテーマと、親テーマ、そして緊急時の予備としての最新のデフォルトテーマ(Twenty Twenty-Fourなど)の3つ以外は削除すべきです。

readme.html を消せ

WordPressをインストールすると、ルートディレクトリに readme.html というファイルが生成されます。
これ、実はWordPressのバージョン情報などが書かれているんです。
攻撃者に「このサイトのWordPressバージョンは5.8です」と親切に教えているようなものです。
バージョンがわかれば、そのバージョン特有の脆弱性を狙い撃ちしやすくなります。
インストールが終わったら、このファイルは即削除してください。
license.txt も同様です。
こういう細かいファイルを掃除しておくことで、攻撃者に「お、この管理者は手堅いな、面倒くさそうだから他に行こう」と思わせる抑止力にもなります。泥棒が、防犯カメラやセンサーライトのある家を避けるのと同じ理屈です。

XML-RPC を無効化する

「XML-RPC」という機能をご存知でしょうか。
これは、外部のアプリやサービスからWordPressを操作するための、古いAPI機能です。
スマホアプリから記事を投稿したり、Jetpackプラグインを使ったりする場合に必要になります。
しかし、現在ではREST APIという新しい仕組みが主流になっており、XML-RPCはセキュリティ上の大きな弱点として残ってしまっているケースが多いのです。

この機能は、「DDoS攻撃」の踏み台にされたり、ブルートフォースアタックの入り口にされたりすることが非常に多いです。
通常のログイン画面は守っていても、このXML-RPC経由で何百回ものパスワード試行が行われることがあります。

もし外部連携機能(スマホアプリからの投稿など)を使っていないなら、この穴は塞いでおくべきです。
.htaccess ファイルに以下のコードを記述することで、アクセスを完全に遮断できます。

<Files xmlrpc.php>
Order Deny,Allow
Deny from all
</Files>

あるいは、先ほど紹介した「SiteGuard」プラグインにも、XML-RPCの防御設定があります。
「XMLRPC防御」という項目をONにするだけです。
自分が使っていない機能は、徹底的にオフにする。これがセキュリティの基本原則「最小権限の法則」に通じます。

サーバーの裏口となっているXML-RPCファイルを封鎖しているエンジニアの様子

サーバーレベルでの防御「WAF」

WordPress側での対策も重要ですが、それより手前、サーバー側での防御も非常に効果的です。
多くのレンタルサーバーには「WAF(Web Application Firewall)」という機能が標準装備されています。
これは、Webサイトへのアクセスを解析し、SQLインジェクションやクロスサイトスクリプティングといった一般的な攻撃パターンを検知してブロックしてくれる、頼もしいガードマンです。

WAFの落とし穴と付き合い方

ただし、WAFには副作用もあります。
記事の中にプログラムのコードを書いたり、特定のHTMLタグ(iframeやscriptなど)を使ったりすると、WAFが「攻撃だ」と誤検知してしまい、保存できなくなることがあります。
記事を保存しようとして「403 Forbidden」というエラーが出たら、まずはWAFを疑ってください。
その場合、サーバーの管理パネルから一時的にWAFをオフにして保存し、作業が終わったらまたオンに戻すという運用が必要です。
面倒くさいですが、それだけ厳重に守ってくれている証拠でもあります。
また、SiteGuardなどのプラグインにもWAFチューニング機能がついていることがあるので、自分の環境に合わせて除外設定を行うことも可能です。

海外アクセスの制限

もしあなたのサイトが、日本国内向けのビジネスしかしていないなら、海外からのアクセスを許可する必要はありますか。
攻撃の多くは、ロシアや中国、東欧などの海外サーバーを経由して行われます。
サーバーの管理画面で「国外IPアドレスからのアクセス制限」を設定できる場合が多いです。
特に、ログイン画面(wp-login.php)やXML-RPCへの海外アクセスは、問答無用でブロックしておきましょう。
これだけで、不正ログインの試行回数は劇的に減ります。
私の管理しているサイトでも、これを設定した翌日から、ログに残る攻撃の足跡がピタッと止まったことが何度もあります。
ただし、海外出張中に更新したい場合や、海外在住のライターがいる場合は注意が必要です。その場合は、特定のIPアドレスだけ許可するなどのホワイトリスト運用が必要になります。

ファイルパーミッションの適切な設定

サーバー上のファイルには「パーミッション(権限)」という設定があります。
これは、「誰が」「読めるか(Read)」「書けるか(Write)」「実行できるか(Execute)」を決めるものです。
これが緩すぎると、誰でもファイルを書き換えられる状態になってしまいます。

推奨される設定は以下の通りです。

  • ディレクトリ(フォルダ): 755 (または705)
  • ファイル: 644 (または604)
  • wp-config.php: 600 (または400)

数字の意味を簡単に説明すると、

  • 7 = 読み・書き・実行すべてOK
  • 5 = 読み・実行OK(書き込みNG)
  • 4 = 読み取りのみOK
    といった具合です。
    「777」という設定は、誰でも(世界中の誰もが)読み書き実行できる状態を意味します。これは「どうぞご自由に改ざんしてください」と言っているようなものです。

特に重要なのが、データベースのパスワードなどが書かれている心臓部 wp-config.php です。
このファイルは、自分(所有者)以外は何もできないように、最も厳しい権限を設定しておく必要があります。
FTPソフト(FileZillaなど)でサーバーに接続し、ファイルを右クリックして「属性変更」や「パーミッション変更」を選べば確認・変更が可能です。
一度チェックしてみてください。もし不適切な設定になっていたら、即座に修正しましょう。

FTPソフトの画面を見ながらファイルのパーミッション設定を慎重に変更している様子

万が一、改ざんされてしまったら

どれだけ対策しても、100パーセント安全ということはありません。
GoogleやFacebookでさえハッキングされることがあるのですから、個人のサイトが絶対に安全とは言い切れません。
もし、冒頭の私のように「サイトが改ざんされた」という連絡を受けたら、どうすればいいのでしょうか。
パニックにならず、以下の手順で冷静に対応してください。

  1. 落ち着いて現状確認: どのページがおかしいのか、管理画面には入れるのか、FTPでサーバーには接続できるのかを確認します。スクリーンショットやログを保存し、被害状況を記録します。
  2. メンテナンスモードに切り替え: 被害拡大を防ぐため、サイトを一時的に閉鎖します。.htaccess でIP制限をかけ、自分以外アクセスできないようにします。
  3. パスワードの全変更: WordPressだけでなく、FTP、データベース、サーバー管理画面のパスワードもすべて変更します。これ以上侵入されないようにするためです。
  4. バックアップからの復元: これが一番確実です。改ざんされる前(できれば数週間前)のクリーンな状態のデータをサーバーに上書きします。
  5. 脆弱性の特定と修正: 復元しただけでは、また同じ穴から入られます。プラグインやテーマのアップデートを行ったり、怪しいファイルを削除したりして、穴を塞ぎます。セキュリティプラグインのスキャン機能を使って、改ざんされたファイルが残っていないかチェックします。

もしバックアップがない場合や、自分で対処しきれない場合は、プロの復旧業者に頼むのも手です。
費用は数万から数十万かかりますが、中途半端にいじって状況を悪化させるよりはずっとマシです。
「何かあった時の連絡先」を事前に決めておくのも、立派なセキュリティ対策の一つと言えます。

よくある質問(FAQ)

現場でクライアントや後輩エンジニアからよく聞かれる質問をまとめました。

Q. セキュリティ系のプラグインはたくさん入れたほうがいいですか?
A. いいえ、逆効果です。プラグイン同士が競合して不具合を起こしたり、サイトが重くなったりします。「SiteGuard」ひとつ入れておけば、日本の環境では十分強力です。もし海外からの攻撃が激しい場合は「Wordfence」などを検討しますが、基本はシンプル・イズ・ベストです。多く入れれば安心というわけではありません。

Q. カフェのフリーWi-Fiで管理画面に入ってもいいですか?
A. 絶対にやめてください。暗号化されていないフリーWi-Fiは、通信を盗聴されるリスクがあります。ログイン情報(ID・パスワード)を盗まれたら終わりです。どうしても作業が必要な場合は、スマホのテザリングを使うか、信頼できるVPNを通して接続するようにしてください。私はスタバで作業するときも、必ず自分のiPhoneの回線を使っています。これはセキュリティ意識の問題です。

Q. Basic認証ってかけたほうがいいですか?
A. ログイン画面(wp-login.php)にBasic認証をかけるのは、非常に有効な「二重ロック」になります。Webサーバーレベルでの認証なので、WordPressの脆弱性に関係なくブロックできるからです。SiteGuardプラグインを使えば管理画面の画像認証も追加できるので、これらを組み合わせれば防御力は格段に上がります。開発中のサイト全体にかけるだけでなく、公開後も管理画面だけにかけておくのは良い習慣です。

Q. サイトがSSL(https)化されていれば安全ですか?
A. SSLは「通信の暗号化」であって、サーバーへの侵入を防ぐものではありません。通信経路での盗聴や改ざんは防げますが、サーバー内部への不正ログインや脆弱性攻撃には無力です。「SSLだから安心」というのは大きな誤解ですので、別途しっかりとした対策が必要です。

PC画面の前で復旧作業手順書を確認しながら真剣な表情で作業を進めるエンジニア

信頼を守るための戦い

長々と技術的な話をしてきましたが、セキュリティ対策の本質は「信頼を守ること」に尽きます。
クライアントは、技術のことはわかりません。
「プロに頼んだんだから、安全に作ってくれているはずだ」と信じて任せてくれているのです。
その信頼に応えるのが、私らエンジニアの仕事であり、矜持です。

セキュリティ対策は、デザインや機能と違って、目に見えません。
「こんなに対策しました」とアピールしても、「で、何か変わったの」と言われることもあります。
地味で、面倒で、お金にもなりにくい作業かもしれません。
でも、何も起きない平和な毎日こそが、最大の成果なのです。

あの日、改ざんされたサイトを復旧させた後、社長から言われた言葉を忘れません。
「直してくれてありがとう。本当に怖かったけど、これでやっと枕を高くして眠れるよ」

朝のオフィスで、セキュリティ対策が完了した安全なサイトの管理画面を満足げに見つめるエンジニア

その言葉を聞いたとき、エンジニアとして一番大切なものを守れた気がしました。
サイトを守ることは、クライアントのビジネスを守り、その先の生活を守ることでもあります。

今日から、あなたの管理しているサイトをもう一度見直してみてください。
アップデートは溜まっていませんか。
ユーザー名は「admin」になっていませんか。
バックアップは取れていますか。
不要なプラグインは削除しましたか。

その一つ一つの確認作業が、あなたとクライアントの未来を守る盾になります。
事故が起きてから泣くエンジニアが、一人でも減ることを願っています。

さあ、管理画面を開いて、まずは「SiteGuard」をインストールするところから始めましょうか。
地味な作業の積み重ねが、最強のセキュリティを作るのですから。

あなたなら、きっと鉄壁の要塞を築けるはずです。
健闘を祈ります。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いたエンジニア

高橋 沙耶のアバター 高橋 沙耶 QAオートメーションエンジニア

QAオートメーションに強く、テスト効率化を得意とするエンジニア。緻密な計画と粘り強さが魅力。周囲を和ませる空気感があり、開発チームとテストチームを上手に繋ぐ調整役。趣味は雑貨集めで、かわいいものに目がない。

目次