セキュリティ専門家でも間違える!文字エンコーディング問題は難しいのか?

一見徳丸さんのブログは分かりやすいように思えますが、それは単純な実験により分かりやすいように見えるだけで複数の間違いがあります。

その間違いとは

  • 意図の取り違い – 誤読
  • 言語の仕様と実装の理解不足
  • HTTPやPHP仕様の理解不足
  • セキュリティ対策をすべき場所の理解不足

です。(※0)

“セキュリティ専門家でも間違える!文字エンコーディング問題は難しいのか?” の続きを読む

PHP:既知のセキュリティ脆弱性 – Session Adoption

追記:より新しい情報については間違いだらけのHTTPセッション管理とその対策をどうぞ。

PHPには広く知られているにも関わらず放置されている既知のセキュリティ脆弱性が幾つかあります。その一つがセッションモジュールのセッションアダプション(Session Adoption)脆弱性です。この脆弱性は現在広く利用されているWebアプリケーションの安全性に、非常に大きな影響を与える脆弱性です。

セッションアダプション脆弱性とはセッション固定化攻撃を可能とする脆弱性の一種です。セッションアダプションに脆弱なセッション管理システムは、ユーザ(ブラウザ)が送信してきた未初期化のセッションIDを受け入れ、セッションを初期化してしまいます。PHPに限らず、RailsやJavaのフレームワーク等、多くのWebフレームワークに発見されている脆弱性です。

セッションアダプション脆弱性を利用すると、攻撃者は長期間に渡って他人のIDを使う成りすましが可能になる場合があります。IDを盗みたい犯罪者には利用価値の高い脆弱性です。

この脆弱性は、10年以上前から問題視されている国別TLD(ccTLD)の属性ドメイン(国別Top Level Domain, co.jp, or.jpなどのドメイン)にも下位ドメインからクッキーが設定でき、サブドメインのクッキー設定が無視される(送信順序、優先順位がいい加減)、というとんでも無いクッキーの仕様と組み合わせると、大量の他人のユーザセッションIDを取得(設定)し、成りすます事ができます。

セッションアダプション問題は全てのPHP、PHP 4.4.9/PHP 5.2.8/PHP 5.3/PHP 6.0に共通する脆弱性です。

最近、影響範囲はかなり狭くなりましたが、まだまだ注意が必要な脆弱性であり、根本的な解決にはパッチと適切なセキュリティ対策が必要です。

“PHP:既知のセキュリティ脆弱性 – Session Adoption” の続きを読む

ホワイトリストはどう作る?

まずホワイトリストの基本中の基本は”デフォルトで全て拒否するであることに注意してください。全て拒否した上で許可するモノを指定しないとホワイトリストになりません

例えば、CSPはホワイトリストで不正なJavaScriptの実行を防止する仕組みです。2016年のGoolgeの調査によると95%のCSP定義が、実際にはJavaScriptインジェクション脆弱性の防止に役立っていない、との調査結果を発表しています。原因はホワイトリストの作り方の基本、全て拒否した上で許可するモノを指定する、を理解していないことにあると考えられます。1

私はいつも基本的に能動的なセキュリティ対策2を選択するようにお勧めしています。能動的なセキュリティ対策とは全ての入力値の厳格なバリデーション処理であり、出力時に過剰とも言えるエスケープ処理です。入力/出力の両方にホワイトリスティング対策をお勧めしています。3

“ホワイトリストはどう作る?” の続きを読む

正しいメールアドレスのチェック方法

正しいメールアドレスのチェック方法がちょっとした話題になっているようです。Web屋のネタ帳でも取り上げられていますが、メールアドレスのチェック方法自体は解説していません。ついでなので書いておきます。

「本当に正しいメールアドレスかチェック」するには実際にメールを送信して、送信されたユーザしか知り得ない情報をユーザが知っている事により確認しなければなりません。これはWeb屋のネタ帳で解説されている通りです。

“正しいメールアドレスのチェック方法” の続きを読む

SET NAMESは禁止

MySQLには文字エンコーディングを変更する「SET NAMES」SQL文が用意されています。(PostgreSQLも同様のSQL文、SET CLIENT_ENCODINGがあります)この機能はSQLコンソールからは使ってよい機能ですが、アプリケーションからは使ってはならない機能です。SQLインジェクションに脆弱になる場合があります。

Ruby on Railsの本を読んでいて、ActiveRecordを説明している部分にMySQLの文字エンコーディングを変更する場合の例としてSET NAMESが利用されていました。アプリケーションからはSET NAMESは使ってはならない事を周知させるのは結構時間が必要かなと思いました。

PHPも5.2の途中からMySQLモジュールにlibmysqlの文字エンコーディング設定APIのラッパー関数が追加されていたりするので、たまたま最近読んだRoRの本だけでなく、多くの開発向け情報ソースにSET NAMESを利用した例が載っていると思います。

ストアドプロシージャだけ使っていれば安全ですが、アプリケーションからDBMSの文字エンコーディングを設定する場合、SQL文ではなく必ず文字エンコーディング設定APIを利用するよう紹介しなければならないです。MySQL4はストアドプロシージャが使えないので、フレームワークなどではエミュレートしています。ストアドプロシージャだけ使って防御している「つもり」で防御になっていない場合もあります。これもフレームワークを使っていてもアプリケーションが脆弱になる良い例ですね。

脆弱性の説明は面倒ですが注意事項は簡単です。「DBMSをアプリケーションから利用する場合、文字エンコーディング設定は必ずAPIを利用する」つまり「SET NAMES(PostgreSQLのSET CLIENT_ENCODING等も)は禁止」です。

PHPのMySQL:

PHPのPostgreSQL:

PHPのPDO:

Rails:

 

解答:まちがった自動ログイン処理

問題:まちがった自動ログイン処理の解答です。このブログエントリは最近作られたアプリケーションでは「問題」にしたような実装は行われていないはず、と期待していたのですがあっさり期待を破られたのでブログに書きました。このブログの方が詳しく書いていますけが「Webアプリセキュリティ対策入門」にも正しい自動ログイン処理を書いています。

参考:自動ログイン以外に2要素認証も重要です。「今すぐできる、Webサイトへの2要素認証導入」こちらもどうぞ。HMACを利用した安全なAPIキーの送受信も参考にどうぞ。

“解答:まちがった自動ログイン処理” の続きを読む