このプラグインは、現状の OpenPNE 3 に不足している各種セキュリティ対策を透過的に施すプラグインです。
それぞれの対策について適用の有無が選択できるほか、場合によっては適用内容を細かく制御することができます。
現時点では導入するだけで以下の対策が有効になります。
- Android 標準ブラウザにおける JSON ハイジャック攻撃への対策
- Internet Explorer 9 および 10 においてクロスドメインの JSON の内容が読み取れる問題への対策
- Internet Explorer 8 以前における JSON ハイジャック攻撃への対策
- Internet Explorer 8 以前における JSON コンテンツを悪用した XSS 攻撃への対策
- クリックジャッキング攻撃への対策
- Internet Explorer における XSS 攻撃を誘発しかねない仕様を、 Internet Explorer 8 以降にて無効化する対策
- Internet Explorer や Google Chrome、 Safari にて備わっている XSS フィルタのブロックモードを有効にすることによる、 XSS フィルタの悪用による XSS 攻撃への対策
- UTF-8 の範囲外の文字列を悪用することによる、主に入力値検証回避を目的とした各種脆弱性への対策
- セッションクッキーに HttpOnly 属性を付加し、 XSS 脆弱性があった場合の影響を軽減する対策
- パスワード文字種および文字列長の不適切な制限の撤廃
- アカウントロック機構の追加
- メールアドレス変更時に変更前のメールアドレスにも通知する機構の追加
- 退会時、管理者だけでなく利用者のメールアドレスにもその旨を通知する機構の追加
- ログイン時、ログアウト時、アカウントロック時、メンバー登録時、メンバー退会時、メンバーの認証情報変更時、各種投稿時にログを残す機構の追加
お使いの plugins ディレクトリに opHardeningPlugin というディレクトリを作成し、本プラグインのすべてのファイル群がそのディレクトリに格納されているようにしてください ( opPlugin:install
コマンドによってソースコードを設置済みの場合は、本作業は不要です)。
ファイルを設置した後、以下のコマンドを実行してください:
$ ./symfony openpne:migrate --target=opHardeningPlugin
本プラグインによって適用される各セキュリティ対策は、それぞれ OpenPNE.yml によって設定をおこなうことができます。
たとえば JSON_hijacking_protection
というセキュリティ対策を無効にしたい場合、以下のような記述を OpenPNE.yml に追加します (インデントは半角スペース 2 つによっておこなってください。スペースではなくタブ文字を使用したり、 1 インデントあたりのスペースの数に誤りがあった場合は文法エラーとなります):
hardening: JSON_hijacking_protection: enabled: false
JSON_hijacking_protection
の他に、 escape_html_in_JSON
を無効にしたくなった場合は、追記部分を以下のように変更します:
hardening: JSON_hijacking_protection: enabled: false escape_html_in_JSON: enabled: false
どのようなセキュリティ対策が存在し、どのような設定をサポートしているかについては、「2. 各セキュリティ対策毎の詳細」の章を参照してください。
保護対象の攻撃: | JSON ハイジャック攻撃 (他、 JSON からの情報漏洩に繋がる攻撃も含む) |
---|---|
保護対象の脅威: | 情報漏洩 |
対策の種類: | 防止 |
特定環境における JSON ハイジャック攻撃を受けなくするようにリクエストとレスポンスの検証、およびレスポンスの加工をおこないます。
- enabled : 真偽値 (デフォルト:
true
) - この対策を適用する場合は
true
を、しない場合はfalse
を指定します。
Android 標準ブラウザの多くのバージョンでは、他の主要ブラウザでは対策済みの手法による JSON ハイジャック攻撃が未だに有効です。この攻撃への対策として、 Android で application/json のコンテンツをブラウジングした際に、次に挙げる条件を 1 つも満たしていない場合、エラーを返すようになります。
- POST リクエストである
- X-Requested-With リクエストヘッダの値が XMLHttpRequest である
この条件を満たさなかった場合、 Your request is denied. Please retry to request with "X-Requested-With" header.
といったエラーを残し、本来のレスポンスの送信を拒否します。
Internet Explorer 9 および 10 においては、 http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2013-1297 にて公表されている、クロスドメインの JSON の内容を読み取ることにできる問題が、仕様であるとして修正されていません。
そこで、 Internet Explorer 9 および 10 で application/json のコンテンツをブラウジングした際にも、「2-1-2. Android 標準ブラウザに対する対策内容についての解説」にて解説したような対策が適用されます。
なお、 この問題については、機密情報を含む JSON コンテンツのレスポンスヘッダとして X-Content-Type-Options: nosniff を送信することでも対策となります。したがって、この「JSON_hijacking_protection」を無効にした場合でも、後述する「disable_content_sniffing」が有効であれば、この問題の影響を受けることはなくなります。
Internet Explorer 8 以前では、 JSON コンテンツを UTF-7 で記述された JavaScript として外部から読み込むことで、 JSON ハイジャック攻撃が成立する問題があります。
UTF-7 では JSON ハイジャック攻撃にて用いるメタ文字 (が、通常エスケープされる) を、 UTF-7 独特の記法によっても表現することができます。そのため、 Internet Explorer のように UTF-7 を解釈するブラウザが、 UTF-7 としてエンコードされた場合に JSON の構文を破壊しうる文字列を含む UTF-8 コンテンツを UTF-7 として読み込んでしまうと、 JSON ハイジャック攻撃が成立してしまうことになります。
この問題への対策として、 UTF-7 独特の記法の開始文字である + (プラス) 記号を Unicode エスケープシーケンス \u002b に変換することによって、コンテンツが UTF-7 として解釈されたとしても、 JSON ハイジャックとならないようにレスポンスを加工します。
保護対象の攻撃: | XSS 攻撃 |
---|---|
保護対象の脅威: | 情報漏洩、なりすまし、表示コンテンツの改竄 |
対策の種類: | 防止 |
Internet Explorer 8 以前における JSON コンテンツの直接ブラウジングによる XSS 攻撃を受けなくするようにレスポンスの加工をおこないます。
- enabled : 真偽値 (デフォルト:
true
) - この対策を適用する場合は
true
を、しない場合はfalse
を指定します。
Internet Explorer は、サーバ側で適切な Content-Type を返していたとしても、独自の検出ロジックによって MIME タイプを推測する機能があります。この機能を悪用し、 JSON コンテンツを HTML と誤認させ、本来エスケープが必要でない HTML のメタ文字を用いて XSS を成立させる攻撃方法が知られています。
この問題への対策のために、 <
記号および >
記号を Unicode エスケープシーケンスに変換することで、コンテンツが HTML として誤認された場合でも XSS となることを回避します。
保護対象の攻撃: | クリックジャッキング攻撃 |
---|---|
保護対象の脅威: | 意図しない操作の強制 |
対策の種類: | 防止 |
クリックジャッキング攻撃への対策として、コンテンツを異ドメインから iframe 等によって埋め込むことを禁止するレスポンスヘッダ、 X-Frame-Options: SAMEORIGIN
を発行します。
- enabled : 真偽値 (デフォルト:
true
) - この対策を適用する場合は
true
を、しない場合はfalse
を指定します。 これは異ドメインからの iframe 等による埋め込みを禁止する対策となるため、 SNS 内コンテンツを、連携している異ドメインのサイト上で iframe 等によって埋め込む形でサービスを提供している場合、ほとんどのモダンブラウザにおいて、 iframe 内に SNS 内コンテンツが表示できないといった問題を生じさせる ことになります。 ただし、クリックジャッキング攻撃は CSRF 攻撃と同程度に警戒するべき問題です。このセキュリティ対策を適用しないことを選択する前に、同ドメイン上でサービスを提供できないか、 API 連携等によって同等機能を実現できないかを充分検討してください。また、 Internet Explorer のみになりますが、X-Frame-Options
にて、埋め込みを許容するドメインを指定するような値を送信することもできます (本プラグインにおいてはまだ未対応です)。
保護対象の攻撃: | XSS 攻撃 |
---|---|
保護対象の脅威: | 情報漏洩、なりすまし、表示コンテンツの改竄 |
対策の種類: | 防止 |
サーバ側で適切な Content-Type を返していたとしても、独自の検出ロジックによって MIME タイプを推測する Internet Explorer の機能を (Internet Explorer 8 以降においてのみ) 無効化します。この機能はサーバが適切な Content-Type を返さない場合に有効でしたが、 OpenPNE 3 のように、 (適切なコーディングさえしていれば) ほとんどのコンテンツが適切な Content-Type を返すようなアプリケーションでは XSS 攻撃に悪用される危険性の方が高いものでした。
- enabled : 真偽値 (デフォルト:
true
) - この対策を適用する場合は
true
を、しない場合はfalse
を指定します。
このセキュリティ対策を有効にすると、動的に生成するすべてのコンテンツにおいて、レスポンスヘッダ "X-Content-Type-Options: nosniff" を発行します。これにより、 JSON レスポンスを HTML であると誤認するようなことがなくなるため、 2-2. escape_html_in_JSON
にて説明した問題への対策にもなります。
ただし、この機能の無効化設定は Internet Explorer 8 以降でしかおこなうことができません。 Internet Explorer 7 以前では、この設定が有効かどうかにかかわらず、この問題への対策をアプリケーション側で実施する必要があります。
保護対象の攻撃: | XSS 攻撃 |
---|---|
保護対象の脅威: | 情報漏洩、なりすまし、表示コンテンツの改竄 |
対策の種類: | 軽減 |
XSS 攻撃に対するブラウザ側の保護機構として XSS フィルタがあります。
このセキュリティ対策では、 XSS フィルタのブロックモードを有効にし、 XSS 攻撃を検知した場合にレスポンスのレンダリングを中止させるようにします。
- enabled : 真偽値 (デフォルト:
true
) - この対策を適用する場合は
true
を、しない場合はfalse
を指定します。
Internet Explorer や Google Chrome、 Safari 等には XSS フィルタと呼ばれる機能が搭載されています。この機能は、リクエストに XSS 攻撃のような内容が含まれていて、レスポンスにそのリクエストと同じ内容が含まれる場合に、そのスクリプトの実行を、レスポンスの内容を改変することによって無効化するものです。つまり、サーバ側にこの種の XSS 脆弱性があったとしても、クライアント側でのスクリプトの実行には繋がらないため、この機能をサポートしたブラウザを利用しているユーザに対する脅威が軽減されることが期待できます。
しかしながら、この XSS フィルタの挙動を利用し、 XSS の発動に繋げられてしまうブラウザ側の脆弱性がかつて存在していました。現在この問題は修正されていますが、同種の未知の問題を防ぐため、このセキュリティ対策ではフィルタのブロックモードを有効にします。このブロックモードをサポートしているブラウザでは、フィルタが攻撃を検知した場合に、攻撃を取り除くのではなく、レスポンスのレンダリングを取りやめます。
状況によっては、この対策が過剰な場合があります。あくまでこれはブラウザ側に脆弱性があった場合の保険的な対策ですので、そのようなケースではこのセキュリティ対策を無効にすることを推奨します。
保護対象の攻撃: | XSS 攻撃 |
---|---|
保護対象の脅威: | なりすまし |
対策の種類: | 軽減 |
セッション cookie を発行する際、 HttpOnly というフラグを付加することで、 XSS 攻撃に遭った場合でもセッション ID を盗まれないようにします。
- enabled : 真偽値 (デフォルト:
true
) - この対策を適用する場合は
true
を、しない場合はfalse
を指定します。
Android 標準ブラウザを除くほとんどのモダンブラウザは、 HttpOnly というフラグのついた cookie の発行をサポートしています。
このフラグが付加された cookie は、通信時に Cookie ヘッダには含まれるものの、 DOM の Document への紐付けはおこなわれなくなるので、 JavaScript から読み込むことはできなくなります。
セッション ID を JavaScript から読み書きする必要はほとんどないはずなので、セッション ID を格納する cookie にこのフラグを付加しておくことで、サイトに XSS 脆弱性があった場合でも、セッション ID を盗むことはできなくなり、なりすましの被害を生じさせないようにすることができます。
古いブラウザの中にはこのフラグをサポートしていないものがありますが、通常、単にフラグが無視されるのみとなります。 http://lists.webappsec.org/pipermail/websecurity_lists.webappsec.org/2006-August/001482.html では、 Mac 版 Internet Explorer 5.0 と WebTv においてページのレンダリングがおこなわれないというトラブルを引き起こす旨がレポートされていますが、極めてレアケースであるといってよいでしょう。
保護対象の攻撃: | 各種攻撃 (SQL インジェクション攻撃、 XSS 攻撃等) |
---|---|
保護対象の脅威: | なりすまし、情報漏洩、表示データの改竄、格納データの改竄等 |
対策の種類: | 軽減 |
OpenPNE では、多くの Web アプリケーションと同様、文字列処理をあらゆる場面で実施しています。文字列処理のなかにはセキュリティに関わりのあるものも少なくありません。この文字列処理を、文字エンコーディングに関する攻撃手法によって誤らせることで、ある制限を回避したり、 SQL Injection 攻撃や XSS 攻撃などの各種攻撃への脆弱性を生じさせてしまう可能性があります。
このセキュリティ対策では、 OpenPNE の初期化処理時点で、リクエストパラメータを PHP の mbstring 拡張モジュールによって変換し、 UTF-8 として不適切な文字を取り除きます。
- enabled : 真偽値 (デフォルト:
true
) - この対策を適用する場合は
true
を、しない場合はfalse
を指定します。
保護対象の攻撃: | なし |
---|---|
保護対象の脅威: | なりすまし、情報漏洩、格納データの改竄等 |
対策の種類: | 軽減 |
OpenPNE 3 では、「6 文字から 12 文字までの英数字」のみをメンバーのパスワードとして許容します。しかし、これは特段の理由があって設けられた制限ではありません。この制限によって、メンバーは充分な文字列長や複雑性をもったパスワードを設定することができなくなります。この制限は撤廃されるべきものです。
このセキュリティ対策では、このような不当な制約を撤廃し、「スペースを含むすべての印字可能な文字からなる、 6 文字以上の文字列」をパスワードとして設定可能にします。
実のところ、このセキュリティ対策は、 http://redmine.openpne.jp/issues/1482 にて Youichi Kimura さんから提案された変更のうち、パスワードの文字列長、利用可能な文字種の制限の撤廃に関する修正と同様の内容のものを動的に実現するようにしたものです。このチケットの変更は、 [openpne-dev:707] にて取り込みのための議論がおこなわれましたが、なんらかの理由により OpenPNE 3.8 の対応内容から外れ、現時点で配布されている OpenPNE のすべてのバージョンには存在していない状態となっています。
- enabled : 真偽値 (デフォルト:
true
) - この対策を適用する場合は
true
を、しない場合はfalse
を指定します。