WordPressブロガー界隈でちょっと物議を醸している問題があります。ユーザーの権限のあり方を見直すいい機会だったのでメモ書きを残します。

この問題は、とある方が「制作を代行したWordPressを使ったサイトでExec-PHPを使った。」と自身のブログに書いたことから始まり、「Exec-PHPをインストールするのはいいのか」という問題となりました。

Exec-PHPは使わないほうがいい?

Exec-PHPとは記事の中でPHPを記述、実行できるようにするWordPressのプラグインです。

ただし、PHPを記述できるのは管理者権限を持ったユーザーが書いた記事やテキストウィジェットに限られています。全ユーザーがPHPが使えるようになるわけではありません。

管理者権限がないと使えないので、そもそも記事を書くユーザーは名前の通り「編集者」や「寄稿者」のユーザーでやれば、もし記事中にPHPの開始タグを打ち込んでも問題なく動作します。ですのでユーザー管理さえしっかりしていれば使っても問題ないのではと思っています。

管理画面上でPHPが使えるということ

管理画面は作業する場所

本当に問題となるのはユーザーやプラグインがどうこうではなく「WordPressの管理画面上で自由にPHPを動かせるのはいいのかどうか」ということ。

Exec-PHPやrunPHPなどのPHPを動かすプラグインをいれなくても、管理画面上からテーマやプラグインの編集ができるようになっていればPHPを自由に動かすことができます。
もし悪意のある誰かがWordPressの管理画面にログインしてPHPを動かしたら…一体どうなるでしょうか?

管理画面上でPHPが使えると表現の幅がとても広がり管理も楽になのですが、なんでも出来るようになります。ちょっくらExec-PHPを入れて記事上でPHPを動かしてみます。

記事にPHPコードを書く。
テストその1

これは、「ふぇぇ」という文字を出力しろというコードです。

保存して記事をプレビューすると、先ほどのPHPが実行される。
テストその1 - 実行結果

ちゃんと「ふぇぇ」と出力されました。

それでは、これはどうでしょう?

DBのログイン情報を表示する。
テストその2
おっと。ログイン情報が表示されてしまいました。
テストその2 - 実行結果

このPHPコードを実行するとそのWordPressで使われているデータベース(以下、DB)のログイン情報が表示されるわけです。

それじゃ、ログイン情報が入手できたのでログインしてみましょうか。

DBにログインして情報を呼び出してみる
テストその3
DBの構造が表示される。
テストその3 - 実行結果

DBのログイン情報がわかればWordPressに保存されているデータを好きにいじることもできます。

すべての記事を編集してみる
テストその4

これを実行するとそのWordPressに保存されている全ての記事の末尾に「ヽ(`Д´)ノプンプン」が追記されます。ユーザーや下書き公開済みなどは関係なく、すべての記事です。もちろん特定のユーザーの記事や公開済みの記事のみ、何月何日~何月何日の間に公開した記事など細かい指定も可能です。

どんなにいい記事を書いていても、最後の一文が「ヽ(`Д´)ノプンプン」だと何だか締りませんね。しかも記事にアクセスするたびにヽ(`Д´)ノプンプンが増殖する。ステキです。

じゃあこれはどうでしょうか?

テストその5

これを実行すると特定のユーザーのパスワードのデータが変更されます。

パスワードは暗号化されているのでデータベースのデータを見てもログイン画面に入力するパスワードはわかりません。ですがデータを上書きすることはできます。

WordPressの暗号化の仕組みはよくわかりませんが、パスワードの暗号化にはブログ固有のキーなどは使われていないみたいで、他のWordPressのユーザー情報を上書きすることで、任意のパスワードに変更できます。
このコードをいれておけば記事に誰かがアクセスするたびにパスワードが書き換えられるという大変便利な(


追記

記事を公開してからはてなやTwitterで「あれ?ハッシュの設定なかったっけ?」と質問が上がってきたのでそれについて追記します。

たしかにwp-config.phpにハッシュの設定があります。ここの値はWordPressをインストールした時に自動的にランダムに生成されwp-config.phpに記述されるのであまり意識することはありません。実際ぼくも存在を忘れていましたw

ちなみにこのハッシュというものは、上述パスワードの時に出てきた「ブログ固有のキー」みたいなもの。
パスワードを保存するときに暗号化するのですが、このハッシュを使って暗号化することで「ハッシュがわからなければ暗号を解読できない」とするものです。

もしサーバーに保存されているデータがハッシュで暗号化されていたとしたら?

それでは、もしサーバーに保存されているデータにも何らかの固有のキーが使われていたとしましょう。これでログイン情報が守れるでしょうか?
よく考えてください。WordPressはオープンソースといってソースコードが公開されています。ですのでどこに何が記述されていてどうやって暗号化しているかは調べればわかるんです。

そうなると攻撃者が考えることは、その固有のキーを呼び出すこと。もしwp-config.phpに書かれているのであれば、最初に書いたパスワードを呼び出すようにAUTH_KEY、LOGGED_IN_SALTと書けばハッシュがわかります。

まぁそれだと先に書いたパスワードと一緒の方法ですので、また違ったやり方をやってみます。

テストその6

これを実行すれば、ID2のユーザーのログインパスワードが「tekitounapass」に変更されます。

やっていることは単純でWordPressの暗号化をする部分だけを動かして、任意のパスワードを暗号化。それを任意のユーザーに上書きしています。

wp-config.phpのハッシュの使い道

ちなみに、wp-config.phpで設定されているハッシュは、”ブラウザにログイン情報を保存するとき”に使われているようでした。
そうすることで同じブラウザで管理画面を見ている限りは、何度もログイン画面が表示されることはありません。
これはブラウザに保存されているデータを元に自動的にログインしているわけですが、パソコンに保存されているデータはwp-config.phpに記述されているハッシュを元に暗号化されているので、もしそれを見られてもパスワードは解読できません。そして、もし不正なログインに管理者が気づいた時はこのハッシュを変更すれば、暗号化の方法が変わるのでブラウザに保存されているデータが使えなくなり、ログインしているユーザー全員を強制的にログアウトさせられます。もう一度ログインするにはユーザー名とパスワードを入力しないといけません(ブラウザの機能で入力したユーザー名とパスワードが記録されていればまた話はかわりますが)

——————– 追記ここまで


PHPを実行できる = やりたい放題

と、こんな具合に管理画面でPHPを動かせるということは色んなことができちゃうということです。

ただ例に挙げたデータの操作は、管理者権限を持っていれば管理画面上からできるんですけどね。

もし攻撃者がなんらかの脆弱性やキャッシュを使ってログインしてきた場合は、パスワードはわからない可能性もありますし、ユーザー情報を変更する時にパスワードの入力を求めるプラグインがあるかもしれません。が、PHPを直接実行出来れば上述のパスワードの書き換えが行えます。WordPressの正規の手順を通さずに実行することになるので、WordPressに実装する履歴保存やセキュリティ系のプラグインも無意味になります。ログイン履歴を保存するプラグインもありますが、その履歴も削除されてしまうわけです。

どう防ぐか?

対策1. 管理画面上からPHPを使えなくする

不正な方法でログインされる危険性がある以上「管理画面からはPHPを使えなくする」ということです。普段はPHPを動かせない状態にして、必要があれば一時的に設定を戻すか、FTPから直接操作することになります。
管理画面からPHPを使えるようにするには以下の条件があります。

  1. 管理画面上からテーマファイルとプラグイン、もしくはそのいずれかの編集ができる
  2. FTPのログイン情報がWordPressのログイン情報と同じ
  3. FTP情報を求められずにプラグインやテーマのインストールができる
  4. Exec-PHPなどPHPを実行できるプラグインがインストールされている

ファイルの編集機能の停止と、プラグインの自動インストールを停止してください。

ファイルの編集機能を停止する

wp_config.phpに以下のコードを追記。

これで管理画面上でプラグインやテーマファイルの編集が一切できなくなります。

更新、インストール時のパスワード認証を必ず行う

これはぼくもよく使っている設定なのですが、このコードが書かれているとプラグインやテーマをインストールするときにFTP情報を求められなくなり、インストールがとってもスムーズ。
反面、管理者権限でログインすればプラグインをインストールし放題という恐ろしいことに。もしこの設定をしているならすぐさま削除してください。

この設定がされた状態だと、Exec-PHPがインストールされておらずファイルの編集ができない状態でも、Exec-PHPをインストールすればPHPを実行してやりたいh(

このコードがなければ、もし管理者権限でログインされてもファイルの編集はできないし、プラグインをインストールしようにもFTP情報がわからず断念。ということになります。ただFTPのログイン情報がWordPressのログイン情報と同じだとインストールされたり直接FTPに侵入sれてしまいます。

対策2. 厳密なユーザー管理を行う

管理画面上でテーマやプラグインの編集ができないと困る…。そういう時はもっと厳密なユーザー管理を行います。

管理者は記事を書かない

管理者はテーマの編集やユーザーの操作など管理面の操作を行うときのみにログインします。そしてできることならGoogleの2段階認証プラグインを使うなど、出来る限りセキュアなものにしてください。

記事の編集は編集者

記事の作成・編集は編集者が行います。権限の名前的にも違和感ありません。

ユーザーをわけることのメリット

カッター

ブログで普段やることといえば記事を書くことです。記事を書くのにPHPを動かすことはまずありません。普段から使うユーザーの権限を下げ、記事を書くことだけにしておけば、もし外出先や何らかの拍子に漏れてしまっても被害を最小限に食い止めることができます。

結局のところ

WordPressのセキュリティを強化していっても、FTPやデータベースを攻撃されてログインされてしまうと意味がありません。不要な権限は省き、出来る限りのことはやってリスクを少しでも減らそうということですね。

と、まぁ今回の件で「WordPressの管理画面上でPHPを使えたら何ができるか」から「ユーザーの権限をもっと厳密に」という考えにいたりこの記事を書きました。ぼくもWordPressのサイトを頼まれた時にそのあたりを全然意識してなかったなぁと今更になってガクプルです。

自身が運営するサイトであればログイン情報の管理も徹底できますが、その手を離れてしまうとどうやって管理されているかわかりません。ユーザーにどこまでの権限を振るかはサーバーの管理では基本中の基本のセキュリティ。でもやっぱり権限が広いと便利なんですよね。「こっちの方が楽だから…」と不必要な権限まで与えてしまうと痛い目を見るかもしれない。クライアントからしてもリスク回避につながりますし納品の時点で出来る限りやっておきたいところ。

でもクライアントが自由にプラグインを入れられる環境も魅力的ですし、セキュリティを重視して自由度を削るか…どっちも捨てがたいですね。