2020年3月11日水曜日

WordPress では /?author=数字 で WordPressのユーザー名(ログインID)が漏洩してしまう件の対応について

何が問題か


WordPress では、
  • WordPressサイトのURL/?author=数字
にアクセスすることで、
  • WordPressサイトのURL/author/ユーザ名
に自動転送される仕組みになっています。
これを悪用すれば、
  • WordPress のユーザー名に割り当てられている「すべての」ユーザー名(ログインID)を知られてしまいます。
このことは
にあるように脆弱性診断システムなどで脆弱性ありと判断される場合があります。

対策しているかどうかの確認方法


コマンドラインツール curl を使えば(macOS には標準搭載)、たとえば、 http://example.com に WordPressのサイトがあるとすると
  • curl -v -D -  "http://example.com/?author=1"
と Mac ならターミナルから入力することで、標準出力にヘッダー情報が出てきます。
そこの location: をみると
  • location: http://example.com/author/ユーザー名/
になってユーザー名が見えてしまっています。これが存在しない場合、ユーザー名でない場合には何らかの対策がされているということになります。

実際にウェブサーバーログをみると、
?author=1
?author=2
?author=3
?author=4
...
など大量にスキャン(ポーリング)されているサイトもありました。

ユーザー名が漏洩したからといって即座に問題になるとは限らない


先に説明しておきますが、ログインのユーザー名が漏洩したからといって、それだけで不正ログインされるわけではありません。一般的にはパスワードが必要だからです。しかしながら、他のサイトとパスワードを同一(パスワードの使いまわし)をされていれば、もし他のサイトからパスワードが漏洩してしまうとログインできてしまいます。ですので別途ログインについては、下記のようなセキュリティ対策を施しておくのがよいです。
  • IPアドレス制限
  • 認証にクラウドサービス(Google認証等)をつかう
  • 総当り攻撃(ブルートフォース攻撃)への対策(一度に大量アクセスを防止)
などです。そうすれば、たとえユーザー名が漏洩したとしても問題はなくなります。

とはいえ、WordPress にどのユーザーがログインできているのか知られることは嫌ですよね。ですので対策したほうがよいでしょう。
ここでは

1. ウェブシステム側で止める
2. WordPress プラグインで止める(自作)

に絞って備忘録として残しておきます。

対策1. ウェブシステム側で止める


各ウェブサイトの設定において、先頭から
  • /?author=***  = 404エラーとする
  • /author/*** = トップページへリダイレクトする
これが可能なら、WordPress に到達する前に止めることができるのでウェブサイトへの負荷が減ります。
/author/** のケースは、 /hogehoge/author/** を除外するかどうかが、ややこしくなります。たとえばカテゴリー名に使った場合とかです。とはいえ、author は予約語でもあるので、まぁそこは除外するでよいでしょう。

Apache での設定方法


WordPress側では、RewriteBase が設定されているはずなので
  • RewriteRule ^\?author=(.*)? / [NC,R=404,L]
  • RewriteRule ^author/(.*)? / [R=302,L]
の2つを追加すればよいです。
管理者画面側では、?hogehoge=**&author=**
となるので、管理者画面では除外できるはずです(未検証)。
うまくいかなければ、RewriteCond ルールなどを併用すればいいでしょう。筆者は NGINX しかほぼ触っていないので、詳細は

NGINX での設定


nginx は if 文など条件を入れ子構造にできないという問題があります。
したがって細かな条件を書くのが超大変です。
ここではドメインやサブドメイン直下(http://example.com やhttp://hogehoge.example.com/) のように http://example.com/hogehoge というサブディレクトリに保存されていないと仮定すると、汎用性がある設定としては、

set $rp_flag  flag;   
set $rp_flag2 flag; 

if ($request_uri ~ "^/wp-admin/"){
        set $rp_flag false;
}
if ($request_uri ~ "^/author/"){
        set $rp_flag2 "${rp_flag2}_true";
}
if ($args ~ "author=(.*)"){
        set $rp_flag "${rp_flag}_true";
}
if ($rp_flag = flag_true){ 
        return 404;
}
if ($rp_flag2 = flag_true){
        return 302 /;
}


上記コードでは、

1. /wp-admin/ (管理画面)は対象外(リダイレクトしない)
 *つまり公開している側のみリダイレクトする
2. /author/ か GETパラメーターに author= があるかのいずれか
上記をすべて満たす場合に、トップページへリダイレクトする

ということになります。
「1」が必要な理由は、管理画面の投稿や固定ページ等で各ユーザーごとに一覧を表示するのに、author パラメーターが使われているためです。それは必要だろうという判断です。

このように、フラグを文字連結させた上で、それを文字判定させる手法になります。
さらに、requiest_uri に ? があるとパラメータ扱いになって、$args に保存されるという仕様もあってなおややこしい。

参考:

対策2. WordPress プラグインで止める(自作)



ウェブサーバーのほうで止めることができない場合(設定をいじれない)もあると思います。その場合には、テーマの functions.php に書くなどの方法もありますが、サイトが大量にあるとやってられません。
公式プラグインだと WP-CLIコマンドなどで一括インストールが可能になるので、その設定をしていれば、
  • wp @all  plugin install  プラグイン名  --activate
プラグインを作成してそれを公式プラグインに登録しちゃえばよいのです。
幸い筆者は WordPress の公式プラグインをいくつかアップして、メンテナンスしているのでそのあたりのやり方は知ってます。

ただ問題はどのような手法で止めるのかがかなり悩みました。

など速度低下が著しい模様。wp_safe_redirect をつかうのも同様じゃないかなぁと思います。そこで結局は
で提示された方法を採用しました。また /author/ の場合を追加して、その場合にはトップへリダイレクトすることにしました。author=数字 は明示的に攻撃しているといってもいいですが、 /author/ はもしかして誤って入力したかもしれず、表示されないよりはリダイレクトにしたほうがいいかなぁという想いです。つまりは、
  1. 管理画面以外(公開されている部分のみ)に適用
  2. QUERY_STRING に「author」項目がある = 404エラー
  3. REQUEST_URI に /author/ があること =  トップへリダイレクト
  4. redirect_canonical にも対応し、自動補正時にもチェックが走るようにする
という感じです。

2020年3月11日 @kimipooh

2020年1月27日月曜日

コマンドツールで MAMP を SSL 対応しよう! - macOS Catalina (10.15) 編 -

基本的なところは
の通りです。Safari、Chromeでは確認済み。Firefoxは警告(警告: 潜在的なセキュリティリスクあり)がでますが、これは前から。まぁ自前でオレオレ証明書を作って、自分で承認する確信犯(テスト環境のため)ですから、それを検知してくれるのはいいんですけど、アクセスはできることと、SafariとChromeでは警告はでないので、Firefoxの警告を消す努力はもういいやって感じです。

さて、これまではうまくいっていたのにだめになった理由は次の通りでした。
にあるように、2019年1月1日以降の証明書については、2つのルールが追加されており、これに対応する必要があったのでした。
  1. ExtendedKeyUsage (EKU) extension にて serverAuth に対応すること
  2. サーバー証明書の有効期限は、825日以下にすること
です。これを探すまで超苦労したのでメモしておきます。なおそれ以外としては
  • 証明書は、RSA 2048bit 以上、TLS であること
  • SHA-2(SHA-256)を使うこと(SHA-1は駄目よ)
  • Subject Alternative name extension を設定すること
は従来どおりになります。

mamp-enable-ssl.csh (GitHUB)

において、configファイルで
  1. ExtendedKeyUsage (EKU) extension にて serverAuth に対応すること
  2. サーバー証明書の有効期限は、825日以下にすること
  3. 証明書は、RSA 2048bit 以上、TLS であること
  4. SHA-2(SHA-256)を使うこと(SHA-1は駄目よ)
  5. Subject Alternative name extension を設定すること
に対応しています。

  1. [user_cert] と [v3_req]において、下記を追加
     extendedKeyUsage = serverAuth
  2. [CA_default]において、有効期限を 700日の設定を追加
     default_days = 700
  3. [req] において、
     default_bits = 2048
  4. [CA_default]において、SHA-2 (256)の設定を追加
    default_md = 256
  5. [usr_cert] と [v3_req] において、subjectAltName = @alt_names を追加
    [alt_names] において
    DNS.1 = localhost
    を追加。
DNS.1 = localhost というのは、実際にサイトでつかうDNS名
[alt_names]
DNS.1 = localhost
DNS.2 = *.test

など複数の指定が可能になる。
逆にここでちゃんといれておかないと駄目ってことになります。

上記対応を1つでもしていないと、もれなくChrome君が



といってきます。すべて対応すれば表示されなくなり



のように安全だといってくれますね!
macOS 10.15 になって一番苦労したのはこれかもしれない...

参考



2020年1月27日 @kimipooh




2020年1月11日土曜日

#33 WP ZoomUP 新年座談会 & WordCamp Asia 情報交換会 に参加して #wordpress #WPZoomUP

WordCamp Asia 2020 に参加することになって、それ関連で WP ZoomUp というオンラインの WordPresss 勉強会・情報交換会を知りました。ちょうど WordCamp Asia 2020 がテーマになっていたので初参加してみました!

Photo by @WP ZoomUP (twitter)
プログラム
WP ZoomUPをささえる会
WP ZoomUP公式報告

WordCamp Asia 2020 はアジア初開催のフラッグシップ WordCamp!



Photo by @WP ZoomUP (twitter)
ということで、私も早い段階から参加申し込みをして楽しみにしています。ちょうど2019年9月にバンコク(タイ)にいく用事があったので、実際に会場となる ICON SIAMにいってきて、どうやっていくのかを
でまとめたりしています。

Photo by @WP ZoomUP (twitter)

WordCamp Asia 2020 ではグッズ販売をしているらしいですが、これは Swag Store での事前注文だそう。現地で直接買えるのはわぷーグッズぐらいみたいですね。

ブレイクアウトセッション


Zoom の機能「ブレイクアウトルーム」を使って4-5名に分かれて自己紹介をしたり、今年の抱負を話し合ったりと少人数グループでディスカッションできたのはよかったです! Zoom は何度か使っていましたが、この機能を体験したのは初めてでした。これいいですね!

タイ語講座


何度かタイにいっていますが、基本的に英語+ジェスチャーでやってなんとかなっているので、一般的なやり取りはなんとかなると思います。でもやっぱりタイ語がわかっていると楽しいだろうなと思いますね。

*カー(女性)、クラップ(男性)が最後につける(プはほぼ発音しない)

こんにちは! = サワディー カー(クラップ)

って感じですが、こちらはサーバーのホスト名に東南アジアのこんにちは(タイ語なら sawasdee)をいくつかつけていたこともあって馴染み深いものです。

マイ = Not 
パイ = Go

ぐらいはわかってましたが、それ以外は知らないので楽しく聞いてました!
私がメモしたのは次の通り、男性なので最後にクラップをつけていますが、女性ならこれを全部「カー」に置き換えてください。
  • ありがとう! / Thank you!
    • コープン(マー / very)クラップ
  • いくらですか? / How much?
    • カオライ クラップ
  • (タクシーにて) ICON SIAM まで行ってください。 / (In taxi) Please go to ICON SIAM.
    • パイ ICON SIAM クラップ
  •  (レストランなどにて) 辛くしないでください。/ (At restaurants) Please don’t make it hot/spicy.
    • マイ ペッ クラップ(マイ(Not)とマー(Very)は意味が真逆なので発音注意だそうだ)
  •  (レストランなどで) お勘定、お願いします / (At restaurants) Check, please.
    • チェック ビン(でいいんじゃない、他の言い方は難しくて)
  • トイレはどこですか? / Where is the rest room?
    • ホン(部屋) ナム(水) ユー(ある) ナイ(どこ) クラップ
  • 辛くないのはどれですか / Which not spicy?
    • アンナイ マイ ペッ クラップ(ペッ マイ クラップ?でOK)
    • ペッ マー(very):とても辛いのーになるので注意
  • 美味しい
    • アロイ
  • Yes / No
    • チャイ(sure)  / マイ チャイ(not sure)的な感じ (受け答えに使うのか)
    • クラップ / マイ クラップ(純粋な Yes / No)のようなものもあるけど、あまりそういうのは使わないようだ。
  • ちょっとまってください
    • ロウ(待て) ベッ ヌン クラップ
とまぁそんな感じかなー。

タイでやってはいけないボディランゲージ


タイでは王室不敬罪というのがあり、これが一番やってはいけないこと。ようはタイ王室に関して批判的なことをいってはいけないってこと。王室不敬罪で禁錮28年 国連がタイ政府に法改正要請(BBC News Japan)にあるように罪が極めて重くなるんですよね。

それはともかくこの会議では
  • 中指を立てる行為
  • 頭を触る行為
は駄目なことで
  • ハグ
はあまり良くない(初対面とかよく知らない人)
  • 握手
あまりしない

ってことのようです。

助け合いのコミュニティ


参加者でチャットのリンクをクリックをうまくできない人がいて、その人に対してみんながフレンドリーにどうしたら解決できるかというのをやっていたのが非常に印象的でした。オンラインチャットというその人の端末環境が見づらい環境にも関わらず、画面共有の機能を駆使したり、いろいろなところにうまくリンクできるように書き込んだりなど、工夫を凝らしていました。こういうのが WordPress コミュニティなんですよね!

では WordCamp Asia 2020 に参加される皆様、あと1ヶ月ちょっとあとにお会いしましょう!

2020年1月11日 @kimipooh