- WordPressサイトは、手軽にサービスを構築できる反面、機密ファイルが認証なしでアクセスできてしまうような事例も。
- REST APIが有効なままだったり、.htaccessの制限がなくuploadsフォルダも丸見えだったり。
- 基本設定の見落としって怖いですね。
はじめに
最近、あるWebサービスで深刻なセキュリティ問題が発覚しました。大学生向けの就職活動支援サービスで、面接の音声データが認証なしで誰でもアクセス可能な状態になっていたのです。
このサービスには秘密保持についての法的な問題も指摘されていましたが、今回は、WordPressのセキュリティ設定についての検討します。WordPressは汎用性のあるシステムですが、個人ブログレベルの知識の延長で、機密性の高い音声ファイルを扱うようなサービスを構築してしまうことには大きなセキュリティリスクがあるからです。
音声ファイルが丸見えに?
問題となったサービスは、WordPressで構築されていました。
表面上は登録してログインしないと音声再生ボタンを押せない仕様になっていましたが、実際には、音声ファイル本体への直接アクセスが可能でした。URLを直接入力すれば、認証を一切通さずに音声データをダウンロードできる状態だったのです。
家の中に例えると、WordPressの標準設定は「玄関の鍵はかけているが、窓は全開」のような状態です。正面玄関(ログイン画面)からは入れませんが、窓(直接URL)から自由に入れてしまうのです。
WordPressセキュリティの基本的な仕組み
WordPressは元々ブログやWebサイト作成のためのツールであり、写真や文書を「みんなに見てもらう」ことを前提に設計されている点です。そのため、アップロードしたファイルは基本的に誰でもアクセスできる状態になります。
この仕組み自体は正常ですが、機密ファイルを扱う場合は追加の保護が必要です。
ファイルアップロードの標準的な動作
WordPressでは、アップロードしたファイルは通常 wp-content/uploads/ フォルダに保存されます。一般的なブログでは、記事に貼り付けた画像を読者が見られなければ困ります。そのため、WordPressは「アップロードしたファイルは公開する」という前提で動作するのです。
メディアファイルの直接アクセス問題(.htaccess)
最も基本的な問題は、アップロードした音声ファイルへの直接アクセスを防いでいなかった点です。
「直接アクセス」とは何でしょうか。通常のWebサイトでは、ファイルに固有のURLが自動的に割り当てられます。例えば https://example.com/wp-content/uploads/2024/12/interview.mp3 のようなアドレスです。このアドレスを知っていれば、ブラウザで直接入力して音声ファイルをダウンロードできてしまいます。
ログイン画面をバイパスして、ファイルに直行してしまうのです。
通常、機密ファイルを扱う場合は .htaccess ファイルでアクセス制限を設定します1。
<Files "*.mp3">
Order Deny,Allow
Deny from all
</Files>
Code language: HTML, XML (xml)
.htaccess は、Webサーバーに「このファイルにはアクセスさせないで」と指示するためのテキストファイルで、「.mp3で終わるファイルは、全てアクセス拒否」という意味です。たとえば、この設定を wp-content/uploads/.htaccess に記述すれば、音声ファイルへの直接アクセスを遮断できます2。
音声ファイル特有のセキュリティ要件
音声や動画ファイルは、テキストデータとは異なる特殊な性質を持ちます。たとえば、声紋によって個人を特定することもでき、一度流出すると完全な回収は不可能です。
特に面接音声ならなおさらです。個人の声だけでなく企業の選考プロセスや機密情報も含まれるため、通常のWebサイトよりもはるかに高いセキュリティレベルが求められます。
そのため、音声ファイルを安全に配信する方法として、以下のようなアプローチがあります。
- ストリーミング配信を利用し、ファイルのダウンロードを防ぐ方法。
これは、YouTubeや音楽配信サービスが使っている仕組みと同じです。動画や音楽を再生できますが、ファイル自体をダウンロードして保存することはできません。 - ファイルを公開ディレクトリ外に保存し、PHPスクリプト経由でアクセス制御する方法。
Webサイトの公開フォルダの外に音声ファイルを置き、専用のプログラムを通してのみアクセスできるようにします。銀行の貸金庫のように、特別な手続きを経ないとファイルに到達できません。 - 時限的なアクセストークンを生成し、一定時間後に無効化する方法。
一時的な「パスワード」のようなものを発行し、時間が経つと自動的に使えなくなる仕組みです。
認証チェックの実装不足(is_user_logged_in)
ファイルアクセス時の認証チェックも完全に欠如していました。認証チェックとは、「この人は本当にファイルを見る権限があるのか」を確認する処理です。
通常の会員制Webサイトでは、重要なページにアクセスする前に「ログインしているか」「適切な権限があるか」をチェックします。
if (!is_user_logged_in()) {
wp_die('アクセス権限がありません');
}
Code language: JavaScript (javascript)
このような認証チェックをファイルアクセス処理の前に配置することで、未認証ユーザーのアクセスを防げます。「ログインしていない人がアクセスしようとしたら、エラーメッセージを表示して止める」という意味です。
認証システムは二重構造にする
また、適切なWordPressサイトでは、フロントエンド(画面上の制御)とバックエンド(サーバー側の制御)の両方で認証チェックを行います。
しかし、今回の事例では、フロントエンドでのみ制御していました。画面上では「ログインが必要」に見えても、サーバー側では何の制限もかけていませんでした。
REST APIを使わないなら無効化に(rest_enabled)
また、このサービスでは、REST APIを通じてログインなしで全データにアクセス可能という問題も見つかりました。
WordPressのREST APIとは、簡単に言うと「外部のプログラムがWordPressの中身を読み書きできる機能」です。バージョン4.7以降でデフォルト有効になっています3。「REST」は “Representational State Transfer(表現状態の転送)”の略です4。
なぜこのような機能があるのでしょうか。本来は開発者向けの便利な機能で、例えば、スマートフォンアプリからWordPressサイトに記事を投稿したり、他のWebサービスと連携したりする際に使われます。
しかし、今回の事例では、REST APIを通じてログインなしで全データにアクセス可能でした。機能を適切に制限しないと、第三者が簡単にサイトの情報を取得できてしまうのです。2017年にはWordPress 4.7に「REST API」の脆弱性が発覚しました5。
REST APIを使用しない場合は、無効化しておくのが大事です。
// functions.phpに追加
add_filter('rest_enabled', '__return_false');
remove_action('wp_head', 'rest_output_link_wp_head');
Code language: JavaScript (javascript)
これらのコードをテーマの functions.php に追加することで、REST APIを無効化できます6。「REST機能を使えなくして、関連する情報もページから削除する」という意味です。
管理画面のURLがデフォルトのまま(wp-login.php)
さらに問題だったのは、WordPress管理画面への直接アクセスが可能だった点です。管理画面とは、記事の投稿や設定変更を行う重要なページです7。
通常、WordPress管理画面のURLは https://example.com/wp-admin/ や https://example.com/wp-login.php となります。このアドレスは規則性があるため、悪意のある人に簡単に推測されてしまいます。
管理画面が外部に公開されていると、パスワードを総当たりで試す攻撃(ブルートフォース攻撃)の標的になります。1秒間に何百回もログインを試行されると、いずれパスワードが破られる可能性があります。
<Files wp-login.php>
order deny,allow
allow from xxx.xxx.xxx.xxx # 許可するIP
deny from all
</Files>
Code language: HTML, XML (xml)
このような設定で、特定のIPアドレスからのみ管理画面アクセスを許可できます。「指定した場所(IPアドレス)以外からは、管理画面にアクセスできないようにする」という意味です。自宅や会社など、決まった場所からのみ管理できるようにする仕組みです。
セキュリティの経験不足
運営者が「激安で作ってもらった」と公言していたこのサービス。低価格での開発依頼が、結果的に深刻なセキュリティ問題を引き起こしたとも考えられます。
セキュリティ知識の不足した開発者が、基本的な設定すら行わずにサイトを構築。その結果、25年前の技術レベルにも劣るセキュリティ実装となっていました。
法的責任への理解不足
技術的にはサーバー側の設定ミスが原因にも関わらず、利用者に全責任を押し付ける構造になっていました。このサービスの利用規約には「録音データを投稿した学生が責任を負う」旨が記載されていたからです。
「リーガルチェック済み」と謳っていましたが、これは運営会社が法的責任を回避するためのチェックであり、利用者を保護するものではありませんでした。
他のWordPressサイト運営者への教訓
この事例から学べる最も重要な教訓は、機密ファイルを扱う場合の設計思想です。「表面上は制限されているように見える」だけでは不十分で、技術的に確実なアクセス制御が必要です。
特に音声や動画などの大容量ファイルを扱う場合は、ファイルの直接配布は、セキュリティリスクを大幅に増加させます。
また、開発完了後のセキュリティテストも欠かせません。未認証状態でのアクセステスト、直接URLアクセスのテスト、権限昇格のテストなど、悪意のあるユーザーの視点でのチェックが必要です。WordPressサイトの運営では、初期設定だけでなく継続的なセキュリティ管理が重要です。定期的なセキュリティ診断、ファイルアクセスログの監視、不要な機能の無効化など、運用段階での対策も欠かせません。
まとめ
今回の事例は、WordPressの基本的なセキュリティ設定を怠ることで生じる深刻なリスクを明確に示しています。REST APIの不適切な設定、メディアファイルへの直接アクセス許可、認証システムの実装不備という基本的なミスが重なり、機密性の高い音声データが完全に無防備な状態で公開されていました。
特に注意すべきは、フロントエンドでの制御のみに依存し、サーバーサイドでの適切なアクセス制御を実装していなかった点です。この設計思想の欠如が、認証バイパスによる全データ漏洩という最悪の結果を招きました。WordPressで機密データを扱う際は、ファイルアクセス制御、REST API無効化、認証システムの二重実装が必須であり、開発段階からセキュリティを最優先に考慮した設計が不可欠です。
- 安全なウェブサイトの作り方|IPA 独立行政法人 情報処理推進機構 – WordPressを含むWebアプリケーションのセキュリティ対策に関する公式ガイドライン
- 情報セキュリティ10大脅威 2024|IPA 独立行政法人 情報処理推進機構 – 2024年の主要なセキュリティ脅威とWordPress関連のリスクについて
- WordPress REST API セキュリティの基本知識 – REST APIの脆弱性と適切な設定方法に関する詳細解説
- WordPressのセキュリティ対策の基本|WPセンター – WordPress運営者向けの基本的なセキュリティ設定手順
- WordPress脆弱性情報まとめ|超高速CMS実行環境 KUSANAGI – 最新のWordPress脆弱性情報と対策方法
- Webアプリケーションの脆弱性とその対策|LAC WATCH – Webアプリケーション脆弱性の技術的詳細と対策
- 認証バイパスの脆弱性について|サイバーセキュリティ情報局 – 認証バイパス攻撃の仕組みと防御方法
- WordPressセキュリティ対策プラグイン解説|ミニナレ – 実用的なWordPressセキュリティプラグインの導入方法
- WordPress脆弱性の最新動向|Xserverブログ – WordPress脆弱性の傾向分析と予防策
- Webアプリケーション脆弱性診断|GMOサイバーセキュリティ – 専門的なセキュリティ診断サービスの概要と重要性
- .htaccessによるアクセス制限は、特定のファイル拡張子や条件に基づいてWebサーバーレベルでアクセスを制御する仕組みです。WordPressのセキュリティ対策として、管理ファイルや機密データへの不正アクセスを防ぐ基本的かつ効果的な手法とされています。 – .htaccess だけでできる WordPress セキュリティ強化策 – 実践 WordPress
- .htaccessファイルはApache Webサーバーの設定ファイルで、ディレクトリごとにアクセス制御やリダイレクトなどの設定が可能です。WordPressのwp-content/uploadsディレクトリに配置することで、アップロードされたメディアファイルへのアクセスを制限できます。 – WordPressのuploadsにあるファイルへの直接アクセスを制限(WP新仕様対応)
- WordPress 4.7は2016年12月にリリースされ、それまでプラグインとして提供されていたREST API機能が正式にWordPressコアに統合されました。この変更により、外部アプリケーションとの連携が容易になった一方で、セキュリティ上の新たなリスクも生まれました。 – WordPress 4.7と4.7.1の脆弱性とREST APIを無効にする方法 | ブロギングライフ
- 2000年にコンピューター科学者のロイ・フィールディング(Roy Fielding)博士が自身の博士論文で提唱した、Webシステムの設計思想・アーキテクチャスタイルでWeb上でシステム同士が効率的かつ柔軟に通信できるように設計された原則群 – REST API とは?をわかりやすく解説 | Red Hat
- この脆弱性(CVE-2017-1001000)は、認証なしで投稿やページのコンテンツを改ざんできる極めて深刻なものでした。発覚後、世界中で155万以上のWebサイトが被害を受けたと報告されており、WordPressの歴史上最も深刻なセキュリティインシデントの一つとされています。 – WordPress REST APIのセキュリティが脆弱という誤解 | Otogeworks
- functions.phpはWordPressテーマの重要なファイルで、カスタム機能やフィルター、アクションフックを追加するために使用されます。編集前は必ずバックアップを取り、文法エラーがあるとサイト全体が表示されなくなる可能性があるため注意が必要です。 – WordPress REST APIとは|概要と基本のコマンドをわかりやすく解説 | wp.geek
- WordPress管理画面(wp-admin)は、サイトの全ての機能を制御できる重要な領域です。そのため、ブルートフォース攻撃やディクショナリ攻撃の標的になりやすく、IPアドレス制限やベーシック認証などの追加的な保護措置が推奨されています。 – WordPressのセキュリティを高める.htaccessの設定 | クロジカサーバー管理