2016年3月23日水曜日

StartSSLにドメイン認証不備の脆弱性

Osama almanna's blogにて、StartSSLにドメイン認証に脆弱性があったと報告されています。
In 9 March, 2016 During my research I was able to replicate the attack and issue valid certificates without verifying the ownership of the website which I will explain later in my post, the vulnerability was reported and fixed within hours. 
ウェブサイトの所有権を検証しないで、正当な証明書が交付されるというものですね。脆弱性は報告の後数時間で修正されたとのことです。

以下、彼のブログ記事を元に、脆弱性の内容と修正方法について説明します。

問題の説明

StartSSLのドメイン認証証明書は無料で交付されるため、私も実験用サイトなどで利用しており、アカウントを既にもっています。以下、tokumaru.orgというドメイン名の認証を試みます。
以下は、Validation WizardからDomain Validationを選択して、ドメイン名(tokumaru.org)を入力しているところです。

その後サイト側でwhois情報を参照(以前はこのステップはなかったと記憶していますが)し、whoisに登録されたメールアドレスその他、認証に用いるメールアドレスを返します。
POST /Validate/GetWhois HTTP/1.1   ← whois情報を得るためのリクエスト
…

domainName=tokumaru.org&isNewWhois=1

HTTP/1.1 200 OK                       ← whois情報その他からのメールアドレス一覧
Content-Type: application/json; charset=utf-8
Content-Length: 105
...

"0|proxy@whoisprotectservice.com|postmaster@tokumaru.org|hostmaster@tokumaru.org|webmaster@tokumaru.org|"
上記のレスポンスは、ドメイン名の所有者であることを確認するためのメールアドレスの一覧ですね。これを元に、画面は以下のように変わります。


ラジオボタンは動的に生成されていますが、DOMの内容を見ると、以下の内容になっています。
<input name="ValidateEmails" type="radio" checked="checked" value="proxy@whoisprotectservice.com">proxy@whoisprotectservice.com
<input name="ValidateEmails" type="radio" value="postmaster@tokumaru.org">postmaster@tokumaru.org
<input name="ValidateEmails" type="radio" value="hostmaster@tokumaru.org">hostmaster@tokumaru.org
<input name="ValidateEmails" type="radio" value="webmaster@tokumaru.org">webmaster@tokumaru.org
ここで「Send Verification Code」ボタンを押すと、以下のリクエストがAJAXで送信されます。
POST /Validate/SendDomainVerifyEmail HTTP/1.1               ← 認証コードを送信するリクエスト
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Content-Length: 69
Cookie: fid=DE64D0FE74B0…

domainName=tokumaru.org&sendToEmail=postmaster%40tokumaru.org&index=0

HTTP/1.1 200 OK                                 ← レスポンス
Content-Type: application/json; charset=utf-8
Content-Length: 12

{"status":1}
赤字で示したpostmaster%40tokumaru.orgに検証コードを送り、それを受信できることでドメイン名の正当な所有者であることを検証するという、ドメイン認証証明書の検証方法としてよくある方法です。ここで指定したメールアドレスに以下のようなメールが届きます。

このメール中のverification codeを先の画面上で入力してValidationボタンを押せば、ドメイン認証は完了です。

ここで問題は、さきほど赤字で示したメールアドレスを別のものに差し替えてもそのまま動いてしまうことでした。例えば、cracker@gmail.comのようなメールアドレスに差し替えても、そこにverification codeが送信され、tokumaru.orgのドメイン名の認証が通ってしまうということです。これはまずい…

どう修正すべきか

Osama almanna's blogでは、わざわざ古いOWASP Top 10 2004を参照して、これはinvalidated input vulnerability(検証されていない入力値の脆弱性)と指摘しています。確かに、正しいメールアドレスのリスト(ホワイトリスト)はサイト側は分かっているので、これと比較検証することで、正しいメールアドレスであることは確認できます。
しかし、メールアドレスは4つの選択肢から選ぶわけなので、フルのメールアドレスは表示のためだけに用い、ラジオボタンの属性値は1から4の数字にしてしまえば、仮に検証で多少ミスをしたとしても、まったく関係のないメールアドレスを指定できてしまうことはなかったはずです。つまり、メールアドレスの選択肢はユーザ入力ではなく、システム側で生成した値なのに、それを文字列として受け取ることが問題と言えます。
まとめると、以下のようになります。
  • 利用者本人からも改変されると困る値はtype=hiddenのinput要素やラジオボタン、セレクト要素などで受け渡しせずに、セッション変数を用いるべし
  • 上記で複数の値から利用者に選択させる場合は、選択肢の中身はセッション変数におき、数字等で選択の指定をさせるとよい


【HASHコンサルティング広告】
HASHコンサルティング株式会社は、ウェブアプリケーションのセキュリティに関心のあるセキュリティエンジニアを募集しています。
興味のある方は、twitterやfacebookのメッセージ、あるいは問い合わせページからお問い合わせください。


2016年3月22日火曜日

ウェブアプリケーションにおいて「ホワイトリスト」と"White List"は用法が異なる

海外(主に米国)のウェブアプリケーションセキュリティのドキュメントを読むと、"white list input validation" という言い方がたびたび出てきます。たとえば、OWASPのSQL Injection Prevention Cheat Sheetには、まさにWhite List Input Validationという節があります。
3.2 White List Input Validation
Input validation can be used to detect unauthorized input before it is passed to the SQL query. For more information please see the Input Validation Cheat Sheet.

【私訳】
3.2 ホワイトリスト入力値検証
SQLクエリに渡される前に無許可の入力値を検知するために入力バリデーションを用いることができます。詳細は、入力値検証チートシートを参照ください。
しかし、長年このwhite listの意味が私には謎でした。というのは、引用した文に続いて、以下の文があるからです。
Validated data is not necessarily safe to insert into SQL queries via string building.

【私訳】
バリデーションされたデータは、文字列組み立てを通じてSQLクエリに挿入する上では必ずしも安全ではありません。
ホワイトリストで検証した値が安全ではない、ですと?
しかし、このような文章は珍しくありません。以下は、OWASP Top 10 2016からA1-Injectionの解説です。
3. Positive or “white list” input validation is also recommended, but is not a complete defense as many applications require special characters in their input. If special characters are required, only approaches 1. and 2. above will make their use safe.

【私訳】 3.ポジティブ(いわゆる「ホワイトリスト」)入力値検証も推奨されますが、 多くのアプリケーションが特殊文字の入力を必要とするため、完全な防御ではありません。特殊文字が要求される場合、上述の1.と2.(訳注: 安全なAPIの使用とエスケープ処理)のみにより、特殊文字の使用が安全になります。
このような用例から、私は英語圏のウェブアプリケーションセキュリティに関する文書では、white listの定義は「アプリケーションが許可した入力値」、もっと言えば「アプリケーションの入力値に対する仕様」であると解釈するしかないと考えるに至りました。このあたり、海外のドキュメントに対する知識が豊富というわけではないので、私の理解が間違いであればご指摘下さい。

しかし、この定義は私の「ホワイトリスト」の語感とは異なります。ホワイトリストというからには、

ホワイト = 安全
リスト = 列挙されたもの

であるはずであり、「安全な値の列挙」がホワイトリストの定義だと思うからです。そして、用語辞典でのホワイトリストの定義もそのようになっています。
ホワイトリストとは、警戒する必要のない対象の一覧表のこと。対義語はブラックリスト。
ホワイトリスト - Wikipedia より引用
ホワイトリストとは、対象を選別して受け入れたり拒絶したりする仕組みの一つで、受け入れる対象を列挙した目録を作り、そこに載っていないものは拒絶する方式。また、そのような目録のこと。対義語は「ブラックリスト」(black list)で、目録に載っているものだけを拒絶し、それ以外は受け入れる方式である。
ホワイトリストとは|ホワイトリスティング|white list|WL - 意味/定義 : IT用語辞典 から引用
私の語感や用語集での意味は上記の通りだとしても、日本のウェブアプリケーション開発者の語感はどうだろう、それを知りたいと思うようになりました。そこで、簡易な調査ではありますが、Twitter上で以下の選択肢によるホワイトリストに対するアンケートを実施しました。
  • 許可された入力値をリストとして列挙したもの
  • 入力値が安全になるように文字種等を制限したもの
  • 入力値に対するアプリケーションの仕様
  • その他(よろしければメンションで教えて下さい)
実に580名もの方にご協力いただき、ありがとうございました。結果は下記の通りで、「許可された入力値をリストとして列挙したもの」が84%と大半を占める結果とりました。

ということで、私の語感は、日本の多くのウェブアプリケーション開発者と共通しているようだと考えました。

このエントリの結論は下記のとおりです。
  • ウェブアプリケーションの分野で、日本語の「ホワイトリスト」と英語の"White List"では、用法に違いが見られる
  • ホワイトリスト=アプリケーション仕様という意味だと、どんな場合にでも使えるが、必ずしも安全ではない
  • ホワイトリスト=許可リストという意味だと、使える局面は限定されるか、安全なものとして扱える
  • 両者の意味を混同することは危険である
  • 「ホワイトリスト」という用語が出てきたら、警戒心をもって、どのような意味かを深読みしよう

参考: 僕が「ホワイトリスト」を採用しなかった訳


【HASHコンサルティング広告】
HASHコンサルティング株式会社は、ウェブアプリケーションのセキュリティに関心のあるセキュリティエンジニアを募集しています。
興味のある方は、twitterやfacebookのメッセージ、あるいは問い合わせページからお問い合わせください。

2016年3月14日月曜日

決済代行を使っていてもクレジットカード情報が漏洩するフォーム改ざんに注意

先日以下の記事が公開されました。決済代行会社を使っていたのにカード情報が漏洩したというものです。
同社は、薬局への医薬品の卸売りのほか、運営するショッピングサイト「eキレイネット」でコラーゲンやヒアルロン酸などの美容関連製品を販売している。流出した疑いがあるのは、平成26年10月8日~27年11月5日、サイトでカードを使って商品を購入した顧客の氏名や住所、クレジットカードなどの情報だった。この間、1955人が利用していた。
 名の売れた大企業ではない。従業員わずか10人の小さな会社がサイバー攻撃の標的になったのだ。
 問題が発覚したのは昨年11月。決済代行会社からカード情報が流出した疑いがあると指摘があった。
従業員10人なのに「標的」に サイバー攻撃、中小企業が狙われる理由より引用
これに対して、以下のブックマークコメントがつきました。
そもそも、決済代行会社を使っているのになぜカード情報が漏れる?普通は自分たちの側には一切カード情報を残さないものだが。getで送るとうっかりアクセスログに残る、とかの例はあるけど。
はてなブックマークより引用
実は2013年以降、決済代行会社を使っているのにカード情報が漏洩する事件が続いています。その場合の漏洩経路には以下の二種類が知られています。
  • 決済代行を使っているのに、カード情報を自社サイトでも保存していた
  • カード情報の入力フォームを改ざんされ、別サイトにカード情報を転送された
前者の例としては、以下の記事で紹介しました。
しかし、実際の事件を調べてみると、多いのは後者の経路です。このパターンとして最初の、そしてもっとも有名な事例は、JINSオンラインショップからのカード情報漏洩でしょう。
ジェイアイエヌでは、クレジット情報漏えいの専門調査機関であるPayment Card Forensics株式会社(PCN)に調査を依頼。4月8日に受領した報告書によれば、3月6日にサーバーにバックドアプログラムが設置され、第三者のデータベースにカード情報が転送されるようにアプリケーションのプログラムが改ざんされていたことが判明した。
JINS、不正アクセスによるカード情報流出は最大2059人、当初発表下回るより引用
セキュリティコードをはじめクレジットカード情報は、弊社では保管しておりません。
保管していない情報が流出した理由につきましては、オンラインショップの支払方法入力画面に改ざんが加えられ、入力したクレジットカード情報が不正に外部のサーバに送信されるよう改ざんされたためであります。
よくあるご質問 | JINS - 眼鏡(メガネ・めがね)より引用
入力フォームが改ざんされて、入力内容が外部に送信されるような仕掛けが組み込まれたということですね。恐らく、JavaScriptが追加されて、フォームの入力内容を外部に送信するように、Webビーコンのように動的にIMGタグを生成するとか、XMLHttpRequestオブジェクトによりフォームの内容を送信する仕組みが組み込まれたのでしょうね。

では、JINSオンラインショップの事件以降、同種の事件がどの程度発生しているかを調べてみたところ、以下の様に継続的に、フォーム改ざんが攻撃経路と思われるカード情報漏洩事件が発生しています。

サイト名漏洩期間漏洩件数セキュリティコード決済代行
JINS オンラインショップ2013/3/6~2013/3/142,059漏洩使用
光文社が運営する3サイト2013/12/29~2014/1/211,160漏洩
ホビーショップタム・タム2014/5/3~2014/6/20923漏洩使用
eキレイネット2014/10/8~2015/11/5不明漏洩使用
ONYONEベースボールギア2014/11/1~2015/2/2772漏洩使用
中村屋2014/11/8~2014/12/241,422漏洩
エアコンの森Plus2015/1/1~2015/7/1712 使用
プリマージュオンラインショップ2015/4/1~2015/7/22563漏洩使用
DiXiM Store2015/8/1~2015/9/11480漏洩使用
ブルーラグオンラインストア2015/8/1~2015/8/1645 使用
シネマイクスピアリ2015/10/17~2015/10/301,414漏洩使用
日本オッターボックス2015/5/19~2016/3/2397漏洩使用
THE KISS ONLINE SHOP2016/1/16~2016/3/2537漏洩使用
「カミチャニスタ」ウェブサイト2016/1/25~2016/3/2744漏洩使用
vivid golf2016/1/25から2016/3/11616漏洩使用
NETSEA(*1)2016/1/1から2016/4/157,386漏洩使用
軒先パーキング2015/5/8~2016/7/2738,201漏洩使用

*1 NETSEAの情報漏えいは、改ざんによるものではなくHeartBleed脆弱性によるもの(報道)
※ 2016年4月12日:2件(THE KISS ONLINE SHOP、カミチャニスタ)追記
※ 2016年4月27日:1件(vivid golf)追記
※ 2016年4月28日:2件(日本オッターボックス、NETSEA)追記
※ 2016年8月27日:1件(軒先パーキング)追記

特徴としては、下記の三点です。
  • 漏洩の対象が特定期間に取引した利用者に限られ漏洩件数は比較的少ない
  • セキュリティコードが漏洩するケースが多い
  • 決済代行を利用していても漏洩に至っている(決済代行業者に落ち度はない)
ということで、決済代行を使っているからカード情報は漏れないと油断していると危険です。
対策としては、JINSオンラインショップの下記が参考になります。
・画面遷移型のクレジットカード情報非保持サービスの採用
このサービスを採用することにより、オンラインショップの購入画面で決済方法としてクレジットカード決済を選択した場合に、決済代行会社が管理するウェブサイトへ画面が遷移することで、購入者のクレジットカード情報が当社サーバ等のシステムを一切通過しないこととなり、当社システムからの情報漏えいの可能性が排除されることとなります。
なお、上記再発防止策に対しては、本調査委員会より、非常に高い情報セキュリティレベルが実現可能であり、セキュアなクレジット決済を行うことが可能になる施策であると評価されております。
不正アクセス(JINSオンラインショップ)に関する調査結果(最終報告)より引用
ちょっと上記だけだとわかりにくいですが、決済代行サービスには大別して、データ伝送(API)型と画面遷移型があり、JINSオンラインショップは元々データ伝送型を採用していたが、画面遷移型に切り替えるということですね。これですと、クレジットカード情報の入力フォームは決済代行業者が提供するものになり、ECサイト事業者は関与を切り離すことができます。リスクの移転というやつですね。

また、一般的な脆弱性管理やWAFの導入などに加えて、改ざん検知システムの導入も有効です。Webページの改ざんは、中々人手では検知が難しく、上記に紹介したサイトの事例でも、大半がカード事業者か決済代行業者からの連絡で事件が発覚しています。改ざん検知システムによりページ改ざんをすばやく検知できれば、被害を小さくできることが期待されます。


【HASHコンサルティング広告】
HASHコンサルティング株式会社は、ウェブサイトの保護に関心のあるセキュリティエンジニアを募集しています。
興味のある方は、twitterやfacebookのメッセージ、あるいは問い合わせページからお問い合わせください。

2016年3月7日月曜日

OWASPのSQLインジェクション対策方針を読んで「おまえは俺か」と思った

つい最近まで、グローバル・スタンダードのセキュリティ施策ではバリデーションが極めて重視されている、いささか過剰ではないかと思っていたのですが、OWASPの文書を読みなおしたところ、これは僕の思い過ごしだったかと思い始めました。あくまでOWASPに限った話ではありますが…
OWASP Top 10 2004については、以下のようなプレゼンをしたことがあります(2012年3月27日)。
OWASP Top 10 2004をはじめとして、バリデーションが過剰に重視されているのではないかという指摘でした。
しかし、最近OWASPの文書を読みなおしてみると、OWASP Top 10 2004当時にあった「バリデーション至上主義」のようなものはすっかり影を潜め、私が(そして日本の専門家の多くが)言っていることとほとんど変わらないことに気が付きました。以下、SQLインジェクション対策に焦点を絞り、以下の3種類の文書を元に説明します。
  • OWASP Top 10
  • SQL Injection Prevention Cheat Sheet
  • OWASP Top 10 Proactive Controls

OWASP Top 10

OWASPのドキュメントでももっとも有名なものがOWASP Top 10ですが、副題としてThe Ten Most Critical Web Application Security Risksとなっているように、ウェブアプリケーションにおいても重大なセキュリティリスクのトップ10を集めたものです。その最初の版である2004年版では、筆頭に「Unvalidated Input(検証されていない入力)」がありました。その後2007、2010、2013と改版されており、2007以降ではUnvalidated Inputはトップテンからは消えています。2010以降の第1位は、Injection(SQLインジェクション、OSコマンドインジェクション等)となっています。

そこまでは認識していたのですが、2013年版のInjectionの解説では防御方法が以下のように説明されています。実は2010年版もほぼ同じです。
防止方法
インジェクション攻撃を防止するには、コマンドとクエリから信頼出来ないデータを常に区別することが必要です。

1. 推奨されるオプションは、インタープリタを全く用いない安全なAPIを利用するか、パラメータ化されたインターフェースを用いる事です。ただ、ストアードプロシージャなどの、パラメータ化していてもインジェクション攻撃が可能なAPIには注意して下さい。

2. パラメータ化されたAPIが利用出来ない場合、インタプリタにて定められたエスケープ構文を用いて特殊文字のエスケープ処理を慎重に実施すべきです。OWASP's ESAPIはこれらの定番のエスケープを多く提供します。

3. 多くのアプリケーションが特殊文字の入力を必要とするため、“ホワイトリスト”による入力検証も推奨しますが、完全な防御ではありません。特殊文字が必要な場合、上述の1.と2.を用いることで、安全に使用出来ます。OWASP's ESAPIは、ホワイトリストの入力検証ルーチンの拡張可能なライブラリがあります。

https://www.owasp.org/images/7/79/OWASP_Top_10_2013_JPN.pdfより引用
1はプレースホルダを使えということですね。「インタプリタを全く用いない」とは、静的プレースホルダを指すのでしょう。動的プレースホルダ(俗にいうクライアントサイド・プリペアードステートメント)は、呼び出し側でSQLを構文解析するので、インタプリタを用いることになります。
また、「ホワイトリスト」の定義が曖昧ですが、「特殊文字が必要な場合」とはアプリケーション仕様として特殊文字を許容する場合という意味でしょうから、ホワイストリストも「アプリケーションの仕様に従って」という意味だと考えます。
つまり、以下の様になりますね。
  • 根本的対策としてはプレースホルダの使用か記号文字のエスケープである
  • 可能な限りプレースホルダの使用を優先すること
  • アプリケーションの仕様にしたがって入力値検証することを推奨するが、完全な防御にはならない
これなら概要としてはまったく同意ですので、目くじらを立てる必要もないのでした。

SQL Injection Prevention Cheat Sheet

SQLインジェクション防御のチートシート(カンニングペーパー)というタイトルのドキュメントです(英語版)。こちらについては、OWASP名義で下記の記事を投稿しましたのでご笑覧ください。
肝心の防御方法については以下のように書かれています。
  • Defense Option 1: Prepared Statements (with Parameterized Queries)
  • Defense Option 2: Stored Procedures
  • Defense Option 3: Escaping All User Supplied Input
ストアド・プロシージャについては前述の私の記事でマイルドにツッコミを入れていますので参考にしてください。また、前述のOWASP Top 10でもストアド・プロシージャに対するツッコミが入っていますね。このツッコミに私は同意します。

また、本稿と関連するトピックスについては下記のように書かれています。
まずエスケープに関して。

Defense Option 3: Escaping All User Supplied Input

This second technique is to escape user input before putting it in a query. However, this methodology is frail compared to using parameterized queries and we cannot guarantee it will prevent all SQL Injection in all situations. This technique should only be used, with caution, to retrofit legacy code in a cost effective way. Applications built from scratch, or applications requiring low risk tolerance should be built or re-written using parameterized queries.

【参考訳】この第2の手法は、ユーザ入力をクエリ内に入れる前にエスケープすることです。しかし、この方法論はパラメータ化クエリ(訳注:プレースホルダを用いたSQL呼び出しのこと)を用いる場合と比較して弱く、我々はそれがすべての状況ですべてのSQLインジェクションを防げると保証することができません。この手法は、既存のコードを費用対効果がよい方法で改修する場合に限り、用心深く用いられるべきです。スクラッチから構築するアプリケーションや、リスク許容度の低いアプリケーションは、パラメータ化クエリを用いて構築あるいは書き換えされるべきです。
バリデーションについて。

3 Additional Defenses

3.2 White List Input Validation
Input validation can be used to detect unauthorized input before it is passed to the SQL query. For more information please see the Input Validation Cheat Sheet. Proceed with caution here. Validated data is not necessarily safe to insert into SQL queries via string building.

【参考訳】無許可の入力がSQLクエリに渡される前に検知するために入力バリデーションを用いることができます。詳細は、入力値検証チートシートを参照ください。以下に注意して下さい。バリデーションされたデータは、文字列組み立てを通じてSQLクエリに挿入する上では必ずしも安全ではありません。
方向性としては前項のOWASP Top 10と同じですが、エスケープについては、より強く使わないことを推奨しています。引用した内容について、私は完全に同意します。

OWASP Top 10 Proactive Controls

こちらは、「Proactive Controls」ですから、事前の対策についてまとめられたものですね(英語版、日本語版)。先ほどのSQL Injection Prevention Cheat Sheetよりも全体的な話題となります。トップテンは下記の通りです。
  1. 早期に、繰り返しセキュリティを検証する
  2. クエリーのパラメータ化
  3. データのエンコーディング
  4. すべての入力値を検証する
  5. アイデンティティと認証管理の実装
  6. 適切なアクセス制御の実装
  7. データの保護
  8. ロギングと侵入検知の実装
  9. セキュリティフレームワークやライブラリの活用
  10. エラー処理と例外処理
1の「セキュリティを検証」とは、脆弱性の検査を開発プロセスの中で繰り返し行えということですね。
問題は2から4です。SQLインジェクションについては、2のクエリーのパラメータ化、すなわちプレースホルダを使えと書かれています。
SQLインジェクションを防ぐには、信頼できない入力値がSQLコマンドの一部として解釈されるのを避ける必要があります。最も良い方法は「クエリーのパラメータ化」と呼ばれる実装方法です。この方法では、SQLの問い合わせ構文とパラメータは、それぞれ別々にデータベースサーバーに送信され、データベース上で解析されます。
「SQLの問い合わせ構文とパラメータは、それぞれ別々にデータベースサーバーに送信され」の部分はわかりにくいですが、これは静的プレースホルダの性質を説明しています。詳しくは「安全なSQLの呼び出し方」の解説を参照下さい。つまり、OWASP Top 10とは別の表現で、動的プレースホルダではなく静的プレースホルダを使えと推奨しているのです。

3の「テータのエンコーディング」とはエスケープ処理のことですが、この節では主にXSSを例示に用いています。SQLインジェクションも同じ方法で対策することは可能ですが、本文中ではエスケープによるSQLインジェクション対策については触れられていません。

4の「すべての入力値を検証する」については面白いことが書いてありました。

入力チェックとセキュリティに関する補足

入力チェックの段階では、信頼できない入力値を「無害な状態に」変換してしまう必要はありません。危険と思われるデータも「正しいデータ」として受け入れなければならない場合があります。潜在的に危険な文字も「正しいデータ」として受け入れなければならない場合があるため、入力検証によって信頼できない入力が無害になるとは限りません。アプリケーションのセキュリティは、入力値が実際に使われる箇所で担保されるべきです。たとえば、入力値をHTMLの一部として出力するのであれば、クロスサイトスクリプティング対策としてHTMLエンコーディングを実装します。同様に、入力値をSQL文の一部として使うのであれば、クエリーのパラメータ化を使います。どのような場合であれ、セキュリティ対策を入力チェックに依存してはいけません。
『「無害な状態に」変換してしまう必要は』ないというのは、サニタイズは無用だということでしょうね。

(2016/3/7 14:00追記)
奥さん(@kazuho)から指摘をいただきました。Input validation does not necessarily make untrusted input “safe” since it may be necessary to accept potentially dangerous characters as valid input. の訳として、『信頼できない入力値を「無害な状態に」変換』は誤訳であり、「入力値検証によって、信頼できない入力値が無害なものになるとは限りません」くらいの意味であるということです。確かにそうですね。引用した訳はOWASPジャパン有志による翻訳ですが、ここは重要な箇所なので私訳に差し替えました。
(追記終わり)


そして、「アプリケーションのセキュリティは、入力値が実際に使われる箇所で担保されるべきです」という文句がいいですねぇ。「おまえは俺か」と思いましたよ。例えば、次の記事で書いたようなことですね。
この記事で私は以下のように書きました。
これは、入口でのチェックだと漏れやすいから、脆弱性が発生するその箇所で対策するという考え方にシフトしているのだと私は考えます。
ここで念押ししておかなければなりませんが、「入力チェックをしなくていい」、なんて誰も言ってないですからね。入力チェックはするべきですが、SQLインジェクション対策という文脈では、入力チェックをあてにしてはいけない、ということです。バリデーションしていれば防げたのに、という脆弱性はたくさんあります。その辺については以下の資料にまとめています。

まとめ

OWASPの最近の主要ドキュメントを読む限り、SQLインジェクション対策の方法論について日米(日本とグローバル)の差はほとんどないことが分かりました。まとめると以下のようになります。
  • とにかくプレースホルダを使う
  • どーーしてもプレースホルダを使えないとか、既存アプリの脆弱性対処を素早く行う必要がある場合に限りエスケープ手法を用いる
  • バリデーションはすべきだが完全ではないので保険的に用いること
私のブログの読者にとっては目新しいことは何もないと思いますが、私は私なりに、グローバル・スタンダードとしての脆弱性対策と日本のそれに差異があることを気にしていたのです。「日本独自の脆弱性対策手法」なんていうと、何かガラパゴス的なものを連想するではありませんか。しかし、こうして米国側から「歩み寄って」下さったおかげで、もはやガラパゴスなんて心配は無用であり、私はいい気持ちになりました。


【HASHコンサルティング広告】
HASHコンサルティング株式会社は、SQLインジェクションの正しい対策方法に関心のあるセキュリティエンジニアを募集しています。
興味のある方は、twitterやfacebookのメッセージ、あるいは問い合わせページからお問い合わせください。


2016年2月19日金曜日

東京の図書館で技術書を借りよう

こんにちは。東京都品川区在住の徳丸です。東京で消耗しながら生活しています。
都会での生活には、家賃が高いとか、通勤が地獄のようだ、などのデメリット(消耗)がありますが、一方メリットもたくさんあります。書籍が手に入りやすいこともその一つです。若い頃地方の工場(鹿児島県霧島市)でエンジニアとして生活していて痛感したことの一つに、
  • 田舎では技術書との出会いが不自由だ
ということがありました。なので東京出張の旅に大きな書店に出向いて技術書を買いあさっていました。書泉グランデにドラゴンブックの原書が平積みにされていたのを見たのは今から20年以上前のことですが、私はその衝撃を今でも生々しく覚えています。

実は東京は大きな書店があるというだけでなく、公共図書館に技術書が多く所蔵されていることをご存知でしょうか? かつて、図書館に技術書があると図書館に行きたくなくなるとおっしゃられた市長がおられましたが…
大体ね、公立の図書館は駄目なんですよ。
なんか技術とかあったり、哲学とかあったり、もうあれ見た瞬間に行きたくなくなるもんね。
【テキスト起こし】武雄新図書館構想発表記者会見 - Google ドキュメント から引用
個人の感想としてはそういう方もおられるでしょうが、エンジニアとしては、やはり技術書も所蔵してくれると助かります。

そこで、東京23区の図書館にどの程度技術書が蔵書されているかを数値的に示すために、「新春座談会 このコンピュータ書がすごい! 2016年版 -2015年に出たコンピュータ書ならこれを読め!-」のトップテンが、実際のどの程度蔵書されているかをカーリルで調べてみました。トップテンは下記の通りです。リンクは、それぞれの東京都の図書館での蔵書(カーリルによる)を示します。

結果は以下の通りです。蔵書の種類が多い順に並んでいます。

このコンピュータ書がすごい! 2016年版の蔵書冊数
書籍番号(1)(2)(3)(4)(5)(6)(7)(8)(9)(10)蔵書種類蔵書数
杉並区45113114111022
大田区1263352263942
文京区332121222918
葛飾区321221211915
中野区131212111913
練馬区78212211824
世田谷区59211111821
江東区43151312820
新宿区4312232717
品川区4311322716
港区3221311713
荒川区211111178
目黒区541123616
足立区441122614
豊島区222121610
千代田区12111167
北区33232513
江戸川区33231512
板橋区3121259
台東区2211157
渋谷区1212157
墨田区2111156
中央区3124

ご覧のように、杉並区の図書館は、トップテンすべてを所蔵しています。すごい! ワーストは中央区の2種類ですが、中央区以外の区立図書館は、5種類以上を蔵書していることがわかります。

東京在住・在勤でなくても利用できる図書館は多い

東京23区の図書館に技術書の蔵書が多いことを紹介しましたが、これら図書館の多くは、その区に在住・在勤でなくても利用できます。
たとえば、文京区、世田谷区、目黒区、品川区等の図書館は、在住・在勤地が「どこであっても」図書館カードを作成できます。気前がいいですね。
また、港区の図書館は、東京23区に在住あるいは在勤を証明するものがあれば、図書館カードを作成できます。
僕自身は、品川区、港区、文京区の図書館カードを持っていて、カーリルで検索して受け取りに一番便利な図書館でネット予約して借りています。書籍の受け取りは最寄りの図書館や地域センターを指定できるのでとても便利です。
読者のみなさまがどの図書館カードを作成できるかについては、こちらのサイトから簡単に調べることができます。

さて、技術者であれば技術書は図書館で借りずに購入すべきだという意見があると思いますが、私は必ずしもそうではないと思います。大きな書店に行かなくても、ネット予約した書籍を地域の図書館で受け取れるのはとても便利ですし、「書籍の内容を購入前に確認したい」、「書籍の悪評が本当か自分の目で確かめたい」、「書籍のサンプルコードに脆弱性がないか確かめたい」などは、エンジニアであれば当然の欲求ではないでしょうか。私自身、図書館で借りた後に「これは持っておくべき書籍だ」と思い購入した本は何冊もあります。

ということで、技術書に触れるための機会の一つとして、図書館も選択肢に加えてみてはいかがでしょうか?


【HASHコンサルティング広告】
HASHコンサルティング株式会社は、新しい技術に関心の高いセキュリティエンジニアを募集しています。
興味のある方は、twitterやfacebookのメッセージ、あるいは問い合わせページからお問い合わせください。


以下の書籍は東京の図書館の多くで借りることができます。

2015年12月18日金曜日

Joomla!の「ゼロデイコード実行脆弱性」はPHPの既知の脆弱性が原因

Joomla!にコード実行脆弱性(CVE-2015-8562)があり、パッチ公開前から攻撃が観測されていたと話題になっています。
パッチ公開の前に攻撃が始まる状態を「ゼロデイ脆弱性」と言いますが、それでは、この脆弱性のメカニズムはどんなものだろうかと思い、調べてみました。
結論から言えば、この問題はJoomla!側に重大な脆弱性はなく、PHPの既知の脆弱性(CVE-2015-6835)が原因でしたので報告します。

exploitを調べてみる

既にこの問題のexploitは公開されていますが、悪い子が真似するといけないのでURL等は割愛します。以下のページでは攻撃の原理が説明されています。
ざっくり言うと、以下の様な攻撃です。
  1. Joomla! がUser-Agentをセッション変数に保存するので、セッション形式のデータ(文字列)をUser-Agent経由でセットする
  2. その際、MySQLのデフォルトでは、UTF-8の4バイト形式があると、それ以降をトランケートする仕様を悪用して、攻撃に不要なデータを切り詰める
  3. 何ということでしょう! 切り詰めをすると、文字列がオブジェクトに化けるではありませんか
  4. 上記によりJoomlaのJDatabaseDriverMysqli、SimplePie等のクラスのオブジェクトをインジェクションして、デストラクタにより任意コードを起動
全体的には、典型的なオブジェクトインジェションによるコード実行です。なぜデストラクタにより任意コードが実行できるかについては、以下の記事を参照下さい。
問題は、上記の 3 です。なぜ、文字列を切り詰めると、文字列型のデータがオブジェクトに化けるのでしょうか。前記の記事にはその辺の説明はなかったので、自分で調べてみました。

シンプルな再現コード

以下は、セッション変数にログインユーザ名とUser-Agentのみをセッション変数にセットして、その際のセッション形式の文字列を表示するだけの簡単なプログラムです。
<?php
// インジェクションするクラス(攻撃対象の既存クラス)
class Class1 {
  private $private = 'prv';
  function __destruct() {
    echo "Class1::__destruct()\n";
  }
}

session_start();

$id = 'ockeghem'; // ログインユーザ名
// $browser はUser-Agentであり外部からコントロールできる
$browser = 'Mozilla/5.0';

$_SESSION['_default']['id'] = $id;
$_SESSION['_default']['browser'] = $browser;

echo str_replace("\0", '%00', session_encode()) . "\n";
出力は以下となります。
_default|a:2:{s:2:"id";s:8:"ockeghem";s:7:"browser";s:11:"Mozilla/5.0";}
セッション変数のシリアライズ形式は、以下のような形です。
  • _default   セッション変数のキー
  • a:2:{...}  要素数2の配列
  • s:2:"id"   文字列長の2の文字列「id」
一方、外部からは操作できませんが、browserのところにオブジェクトをセットした場合の形式は下記のとおりです。ヌル文字を含むため、パーセントエンコードした形で表示しています(bloggerの制限により%記号は全角にしていますが実際は半角です)。
_default|a:2:{s:2:"id";s:8:"ockeghem";s:7:"browser";O:6:"Class1":1:{s:15:"%00Class1%00private";s:3:"prv";}}
これを念頭におきつつ、外部からUser-Agentとして以下を設定してみます(パーセントエンコード形式)。■は、実際には、UTF-8の4バイト形式の文字をセットします。
_aa|O:6:"Class1":1:{s:15:"%00Class1%00private";s:3:"prv";}■
セッション変数のシリアライズ結果は下記となります。
_default|a:2:{s:2:"id";s:8:"ockeghem";s:7:"browser";s:57:"_aa|O:6:"Class1":1:{s:15:"%00Class1%00private";s:3:"prv";}■";}
しかし、これはあくまで文字列です。それは、s:57という型指定がある以上、外部からは変更できないはずです。
しかし、Joomla!のデフォルトのセッションストレージはMySQLであり、文字エンコーディングはutf8_general_ciとなっています。この場合、MySQLは、UTF-8の4バイト形式の文字があると、その文字を含めてそれ以降が切り詰められる、というすごい仕様があります。

このため、セッションをいったんMySQLに保存して、次のページでそのセッションデータを読みだすと、以下のように■以降がカットされた状態となります。
_default|a:2:{s:2:"id";s:8:"ockeghem";s:7:"browser";s:57:"_aa|O:6:"Class1":1:{s:15:"%00Class1%00private";s:3:"prv";}
このセッションデータをダンプすると、何ということでしょう! 文字列だった部分がオブジェクトになっているではありませんか。そして、オブジェクトが生成されているので、このデストラクタも実行されます。
array(2) {         ← ダンプ
  ["_default"]=>
  NULL
  ["57:"_aa"]=>
  object(Class1)#1 (1) {
    ["private":"Class1":private]=>
    string(3) "prv"
  }
}
Class1::__destruct()    ← デストラクタの実行
上記から、以下のことが言えます。
  • これは Joomla! の脆弱性ではない

この問題の原因は何か

phpallを使ってこの問題を確認すると、PHPの以下のバージョンで起こることが分かります
  • PHP-5.0.3~PHP-5.0.5
  • PHP-5.1.x ~ PHP-5.3.x 全て
  • PHP-5.4.0~PHP-5.4.44
  • PHP-5.5.0~PHP-5.5.28
  • PHP-5.6.0~PHP-5.6.12
すなわち、以下のバージョンで修正されています。
  • PHP-5.4.45
  • PHP-5.5.29
  • PHP-5.6.13
  • PHP-7.0.0
これらで修正されている脆弱性はなんだろうと思ってリリースノートを見ると、以下が該当するようですね。
  • Fixed bug #70219 (Use after free vulnerability in session deserializer). (CVE-2015-6835)
セッション・デシリアライザのUse after free脆弱性ということで、挙動から見てもビンゴでしょう。

Linuxディストリビューションではどうか?

PHP本家の対応は上記のとおりですが、RHEL/CentOS等のLinuxディストリビューションから、パッケージとして提供されているPHPのパッチの対応状況はどうでしょうか?
  • CentOS 5,6,7ともパッチ提供なし(参考)
  • Ubuntu 12.04、14.04ともパッチ提供済み(参考)
  • Debian/GNU Linux Debian6はパッチ未提供、7以降は提供済み
  • Fedora Fedora21以降でパッチ提供済み(20はサポート終了でパッチ提供なし)
Red Hat社の脆弱性トリアージ(緊急度判断)は通常妥当だと思っているのですが、この件に関しては外れてしまったようです。ただし、シリアライズされたセッションデータが切り詰められるなんて状況はちょっと予想しがたいので、悪いのはMySQLの仕様だ!、と思わなくもありません。

影響を受けるソフトウェア

PHPのこの脆弱性の影響は、Joomla!に限られるものではありません。セッションストレージとしてMySQLを使うことは、一般的によく行われているからです。

このため、影響の有無判定はともかく、PHPの最新版を使うことを推奨します。

RHEL/CentOSについてはパッチが提供されていないので、個別の対策をとるしかないでしょう。例えば、以下の様な対応が考えられます。
  • アプリケーション側で対応したバージョンを導入する(例:Joomla! 3.4.6)
  • MySQL 5.5.3 以降で使える utf8mb4 エンコーディングを使用する
  • セッションストレージとしてMySQLを避ける
  • バリデーションによりUTF-8の4バイト形式をエラーにする
緩和策としては、WAF(Web Application Firewall)の導入があります。

まとめ

Joomla!のリモートコード実行の問題を分析しました。これまで説明したように、この問題の直接の原因は、Joomla!側にはなく、PHPの既知の脆弱性(CVE-2015-6835)が原因です。私も「Joomla!にゼロデイ脆弱性」とツイートしてしまいましたが、Joomla!の問題ではないと訂正いたします。

この問題は、
  • PHPの通常は顕在化しない脆弱性CVE-2015-6835が
  • MySQLのUTF-8 4バイト形式以降を切り詰めるという仕様のため顕在化した
ことが問題と考えます。とくに、MySQLの上記挙動は、こちらでも書いたように、長いデータを黙って切り詰めると思わぬバグや脆弱性の原因になり得るという例だと言えるでしょう。



【HASHコンサルティング広告】
HASHコンサルティングが販売するWAF(SiteGuard、SiteGuard Lite)は、このJoomla!のコード実行の問題に対応したシグネチャを提供済みです。お問い合わせはこちら。
HASHコンサルティング株式会社は、セキュリティエンジニアを募集しています。
興味のある方は、twitterやfacebookのメッセージ、あるいは問い合わせページからお問い合わせください。


2015年12月7日月曜日

WordPressの侵入対策は脆弱性管理とパスワード管理を中心に考えよう

この記事はWordPress Advent Calendar 2015の7日目の記事です。

今年初めてWordCamp Tokyoにて講演の機会をいただき、WordPressのセキュリティについて話しました(スライド)。そこでもお話ししましたが、WordPressに限らず、Webサイトへの侵入経路は2種類しかありません。それは以下の2つです。
  • ソフトウェアの脆弱性を悪用される
  • 認証を突破される
したがって、侵入対策としては以下が重要になります。
  • 全てのソフトウェア(OS、Apache等、PHP、WordPress本体、プラグイン、テーマ等)を最新の状態に保つ
  • パスワードを強固なものにする
以上! と叫びたい気分ですが、それではシンプル過ぎると思いますので、以下、WordCampでお話した内容とリンクしながら、もう少し細く説明したいと思います。

全てのソフトウェアを最新の状態に保つ

WordPressサイトを前提とすると、以下のソフトウェアの脆弱性を悪用した攻撃の可能性があります。
  • Apache、OpenSSL等
  • PHP
  • WordPress本体
  • WordPressのプラグイン、テーマ
これらのうち、Apache、OpenSSL、PHP等については、できればソフトウェアのアップデートを自前でやるのではなく、ホスティング業者等が代行してくれるサービスを選ぶとよいでしょう。昔からあるレンタルサーバー(共用ホスティング)も該当しますし、PaaS(Platform as a Service)も原則としてアップデートを事業者側でやってくれるはずです(要個別確認)。

WordPress本体とプラグイン、テーマのアップデートは重要です。とくに、プラグインとテーマについては、セキュリティ上の品質が本当にまちまちなのが困ったところです。WordCampでデモに用いたのはMailPoetというプラグインですが、過去のバージョンではテーマアップロードの際に認証をチェックしておらず、誰でも自由に勝手なテーマをアップロードできたという脆弱性があり、このため、脆弱性のデモも以下のように単なるアップロードフォームで攻撃できてしまいました(攻撃がマネできないように一部伏せ字)。
<body>
<form action="http://examle.jp/wp-admin/admin-post.php?page=xxxxxxxxxxxx&action=xxxxx" method="post" enctype="multipart/form-data">
<input type="text" name="action" value="xxxxxxxxx">
<input type="text" name="submitter" value="xxxxxxx">
<input type="text" name="xxxxxxxxxxxxx" value="xx">
<input type="file" name="xxxxxxxxx">
<input type="submit" value="攻撃">
</form>
</body>
このため、プラグインとテーマのアップデートは特に重要です。具体的には、
  • 本当に必要最小限のプラグインとテーマのみを導入する
  • プラグインとテーマのアップデートは自動化する
ことが重要です。
自動アップデートするとサイトが動かなくなることが心配という人もいるでしょうね。そういう心配には、クラウドのイメージバックアップ機能によりサイト全体を保存しておき、万一サイトが動かなくなった場合はバックアップから戻した上でゆっくりと原因分析をするとよいでしょう。ただし、バックアップから戻した直後はプラグイン等が古いわけですから、そのままの状態で公開してはいけません。動かなくなった原因を究明して対処を行い、プラグインのアップデートをすませてから公開するべきです。

パスワードを強固なものにする

もう一つの侵入経路は、認証を突破されるケースですが、WordPressの場合は「パスワードがばれちゃった」というケースが該当します。具体的な手口としては以下の様なものがあります。
  • パスワードが辞書に載っているもので、パスワードの辞書攻撃により侵入された
  • パスワードを他サイトでも使い回ししていて、パスワードリスト攻撃により侵入された
  • 管理端末がウイルス感染して、ウイルスがパスワードを漏洩させた
したがって、対策としては、下記が有効です。
  • よいパスワードを設定する(他で使っていない、辞書に載っていない、できればランダムな)
  • 管理用パソコンのウイルス対策(ソフトウェアのアップデートとウイルス対策ソフト)
WordPressの場合、よく「管理者のユーザ名としてadminは避けましょう」ということが言われます。確かに、admin決め打ちの攻撃も多いのでできればadminを避けたほうがよいとは思いますが、WordPerssは、ログイン名が外部にバレやすいという特性があります。下記は、WPscanというツールを用いてWordPressの辞書攻撃を行った結果の例ですが、adminユーザの方は良質なパスワードを設定していたので破られなかったものの、yamadaユーザはtiggerというパスワードが辞書攻撃によりばれてしまいました。
  +----+--------+------+----------+
  | Id | Login  | Name | Password |
  +----+--------+------+----------+
  | 1  | admin  |      |          |
  | 4  | yamada |      | tigger   |
  +----+--------+------+----------+
つまり、良質なパスワードをつけることが第一優先であり、その他は副次的な対策である、ということです。
WordPressの場合、ログインユーザ名を隠すことは不可能ではないようですが、かなりハードルが高いといえます。このため、ログインユーザ名がわかってしまうことは許容し、パスワード管理に注力することが得策であると考えます。

ファイルのパーミッション

レンタルサーバーにおいては、ファイルのパーミッション設定が重要となります。これは、一つのApacheを複数ユーザーで共有するという特性上必要なものです。
レンタルサーバー事業者側の対策が十分であれば通常は問題になることはないはずですが、現実に大規模な攻撃に至ったケースもあるので、利用者側でもできる対策はしておきましょう。
レンタルサーバーにおいては、以下のパーミッション設定が基本となります。
  • HTMLやJS、CSS、画像は604
  • PHP スクリプトは 600
  • CGI スクリプトは 700
  • ディレクトリは 701
※レンタルサーバー事業者によっては多少異なるパーミッションを指定している場合があります

静的なファイルに関しては、レンタルサーバ独自の特性として、1桁目(右端の桁)にReadパーミッションが必要となります。その他、PHPスクリプトやCGIスクリプトについては、ファイルオーナーのみに権限を与えることが重要です。

その他の「対策」について

上記二点がWordPressサイトのセキュリティ施策としてもっとも重要なものですが、「WordPress セキュリティ」等のキーワードで検索すると、「WordPressを守るために必須の10個の対策」みたいな記事をよく見かけます。
これらの記事を読むと、往々にして「それ、無意味とは言わないけど、それほど効果は期待できないから…」というものが多いです。
以下、それらの代表例を紹介します。

テーブル名のプレフィックをデフォルトから変更することの効果

WordPressのテーブル名にはデフォルトでwp_というプレフィックスがつきますが、そのままだとSQLインジェクション攻撃を受けるので、必ず他のものに変えるようにという記事をよく見かけます。
やらないよりはやった方がよいと思いますが、SQLインジェクション脆弱性があるという前提では、実はそれほど効果はありません。
なぜなら、SQLデータベースにはinformation_schemaという機能があり、テーブル名やデータベース名(スキーマ)は、ここから分かるからです。具体的には、information_schemaに対してSQLインジェクション攻撃をかけることで、テーブル名等の情報を得ることができます。
したがって、プレフィックスを変更すると、へっぽこな攻撃者や攻撃ツールは避けることができるかもしれませんが、腕の良い攻撃者からの攻撃は避けられません。
つまり、SQLインジェクション脆弱性があり、それを攻撃者に見つけられた時点で終わりなのです。このため、SQLインジェクション脆弱性を全力で避ける必要があります。
WordPressのプラグイン等であれば、WordPressの提供するプレースホルダ機能でSQLを呼び出すこと、素のPHPスクリプトであれば、PDOのプレースホルダ機能を用いてSQLを呼び出すことで、SQLインジェクション対策を行って下さい。

.htaccess等で wp-config.php をアクセス制限することの効果

.htaccess等を用いて、外部からwp-config.phpのアクセス制限をするという施策はよく見かけますが、この「対策」が役に立つケースは、実はそれほど多くありません。
wp-config.phpは設定のためのパラメータ設定のPHPスクリプトが並んでおり、このファイルにアクセスしても何も起きません。外部に公開されているPHPスクリプトなのでそれは当然です。問題は、wp-config.phpに記述されたデータベースのユーザ名やパスワードが漏洩することです。
しかし、wp-config.php自体にアクセスしてもそのソースコードは表示されません。表示されるとしたら、なんらかの脆弱性がある場合ですが、wp-config.php自体は単純なものなので、これ自体に脆弱性がある可能性はまずありません。したがって可能性としては、下記が考えられます。

(a) PHPのインストールを忘れていてwp-config.phpが生のままダウンロードされる
(b) 他のPHPスクリプトにディレクトリトラバーサル等の脆弱性がありwp-config.phpを閲覧される
(c) PHP等に脆弱性があり、PHPのソースが漏洩する

(a)は論外のケースであり、インストールの手順をしっかり立てましょう。万一 wp-config.phpの内容を閲覧されてしまった可能性がある場合、すみやかにデータベースのパスワードを変更する必要があります。また、念のため、データベースをすべて削除しておくとよいでしょう。(まだデータは入っていないはずなので)

(b)はあり得るケースですが、残念ながらこの場合は .htaccessの設定では防げません。.htaccessで制限しても、PHP等からは読めるからです。そうでないと、PHPスクリプトからインクルードもできないことになりますよね。

(c)も過去にはありました。CGI版のPHPにCVE-2012-1823という脆弱性があり(参考)、以下のURLのように、?-s をURLにつけることでwp-config.phpのソースを閲覧することができました。
  • http://example.jp/wp-config.php?-s
なんだ、効果があるじゃないかと思われるかもしれませんが、CVE-2012-1823に関しては、リモートコード実行もできたので、.htaccess による制限だけでは、結局ソースコードの閲覧も含め、さまざまな攻撃を許してしまう状況でした。
実際、レンタルサーバー事業者の中には、上記 ?-s による攻撃のみを重視した結果、肝心のリモートコード実行を防ぐことができず、重大な攻撃を受けてしまったところもあります。
将来見つかる脆弱性において、PHPのソースを閲覧できるものが出てくるかもしれませんので、その場合は .htaccess による制限も効果はあることになります。よって、「やっても無駄」というつもりはありませんが、今後そのような脆弱性が発見される見込みはそれほど高くないと思いますので、優先順序としては、脆弱性やパスワードの管理をしっかりやった後、ということです。

SiteGuard WP Pluginのすすめ

今までの話がWordPressのセキュリティ対策の「原則」の話ですが、いくら注意していても設定漏れ等により侵入を許す場合もあり、また長いパスワードをつけているので辞書攻撃の被害を受けないことはわかっていても、延々と攻撃を受け続けると気分はよくありません。
このため、付加的なセキュリティ対策についての検討をするところですが、私からはSiteGuard WP Pluginを紹介したいと思います。
SiteGuard WP Pluginは、WordPressのログイン周りに特化した無料のプラグインで、以下の機能を提供します。


管理ページアクセス制限ログインしていない接続元から管理ディレクトリ(/wp-admin/)を守ります。
ログインページ変更ログインページ名を変更します。
画像認証ログインページ、コメント投稿に画像認証を追加します。
ログイン詳細エラー
メッセージの無効化
ログインエラー時の詳細なエラーメッセージに変えて、単一のメッセージを返します。
ログインロックログイン失敗を繰り返す接続元を一定期間ロックします。
ログインアラートログインがあったことを、メールで通知します。
フェールワンス正しい入力を行っても、ログインを一回失敗します。
ピンバック無効化ピンバックの悪用を防ぎます。
更新通知WordPress、プラグイン、テーマの更新を、メールで通知します。
WAFチューニングサポートWAF (SiteGuard Lite)の除外リストを作成します。
JP-Secure社の紹介記事より引用

SiteGuard WP Pluginのレビューについては既に多くの記事がありますので、そちらをお読みいただければと思いますが、私がよいと思うポイントは下記の三点です。
  • SiteGuard の不正ログイン防止に特化している
  • 簡単に導入できて効果が高い
  • プラグイン自体の脆弱性対策がなされている(重要)
「セキュリティプラグイン」と称していながらSQLインジェクション脆弱性があったなんてものも過去ありましたので、プラグイン自体がセキュアであることは現実問題として非常に重要です。

SiteGuard WP Pluginのインストールはこちらから。

まとめ

WordPressの侵入対策について説明しました。
WordPressに限りませんが、ウェブサイトに対する侵入対策としては、脆弱性管理とパスワード管理が極めて重要であり、これらをおろそかにして他の(楽な)対策をいくら積み重ねても、あまり効果はありません。レンタルサーバーを利用する場合は、ファイルのパーミッション設定も重要です。
本稿の内容が皆様のサイトの安全性寄与にお役に立てれば幸いです。


フォロワー

ブログ アーカイブ