覚えないパスワードは生成する物 〜 余計な文字数制限などは有害 〜

Webサイトにはパスワードの登録に余計な制限をかけているサイトが少なからずあります。特に最悪なのはたった20文字程度のパスワードしか許可しないサイトです。

Webサイトのパスワードは基本的には覚える必要がありません。安全性を第一に考えると十分過ぎるくらいの長さのランダムパスワードを設定する/設定できるようにすると良いです。

参考:覚える場合のパスワードの作り方

TL;DR;

パスワード用のランダム文字列が必要でアクセスした方は以下のURLを参照してください。生成されたランダム文字列の一部、90文字くらい、をパスワードとして使うと安全です。

パスワード用のランダム文字列生成スクリプト

“覚えないパスワードは生成する物 〜 余計な文字数制限などは有害 〜” の続きを読む

hash_hkdf()でわざわざバイナリキー/バイナリSaltを使うことに意味はない

PHP 7.1で追加された hash_hkdf() は出鱈目なシグニチャを持っています。バイナリキーを使うことを想定して、わざわざ既存のハッシュ関数とは異なり、バイナリハッシュ値だけを返せるようになっています。

暗号化がプログラム内で完結する、といった極一部の例外を除きhash_hkdf()でわざわざバイナリキーを使う意味はありません。

CSRFキーを守るURLを守るAPIキーを守る、といったWebアプリケーションで最も頻繁に使われる鍵導出ではバイナリキー/バイナリSaltは、遅いのでむしろ有害と言えます。わざわざバイナリを使う必要はありません。

参考: HMACハッシュの使い方のまとめ – HAMCですが、HKDFはHMAC based Key Derivation Functionです。多くがHKDFで置き換えられます。HKDFが使える場合、hash_hkdf()を使った方が速くなるでしょう。これはPHPの関数呼び出しのオーバーヘッドが比較的大きいことに起因します。

“hash_hkdf()でわざわざバイナリキー/バイナリSaltを使うことに意味はない” の続きを読む

Computer Programming Fundamentals and Principles – Input Validation


I had discussion on PHP dev mailing list. It appeared that not few developers misunderstand “What is Input Validations“. Therefore, I summarize computer programming fundamentals and basics to help understanding validations.

Without fundamentals and basics understanding, discussion is meaningless. “Input Validation” is one of the most important countermeasure for cyber attacks. The idea is strongly supported by notable computer scientists (e.g. CMU’s CERT) and security specialists, yet it is misunderstood by majority of developers. Therefore, almost all web applications are missed to have proper “Input Validation” currently.

I came across this discussion too often, so I summarize why, “Input Validation”, “Input Data Validation” or “Application Input Data Validation” especially, is fundamental and mandatory requirement for applications.

TL;DR;

“Application Input Data Validation” and “Business Logic Validation” are 2 different validations by fundamentals and principles. Except few exceptions, ALL web application input data can be validated by “Application Input Data Validation” without user interactions. This achieves more secure state and cleaner/manageable code structure. Thus, applications should implement “Application Input Data Validation” always.

Note: “Application Input Data Validation” is NOT a replacement of “Business Logic Validation”.

“Computer Programming Fundamentals and Principles – Input Validation” の続きを読む

validate-phpのPHPスクリプト版

入力バリデーションCモジュール、Validate PHPモジュールの待望(?)のスクリプト版です。

週末に半日くらいで書いて、サンプルスクリプトだけしか作っていないので「超開発版」です。(まだ未実装機能もあります)

特定のエントリポイント(つまりMVCのコントローラー)のGET/POST/COOKIE/FILES/HTTP Headerをまとめて、一気に、効率良くバリデーションできるように設計してあります。

個別に「入力値の形式」を定義さえすれば、「データ型を指定する感覚」で理想的な入力バリデーションを実装できます。

https://github.com/yohgaki/validate-php-scr/blob/master/src/examples/00-validate.php

スクリプト版のAPIが安定したら、Cモジュール版が同じように動作するように更新します。(その為に、C言語で実装しやすいような感じのPHPスクリプトを書いています)

https://github.com/yohgaki/validate-php-scr

ドキュメントはほとんど意味がないので、サンプルスクリプトとコードを読んでください。

一気に書いて、後で多少手直しした程度です。バグがあると思うので見つけたら教えてください。こうしたら良い、こうして欲しい、といったご意見も歓迎です。

「脆弱性を局所的に潰す」はアンチプラクティス

本物の「セキュアコーディング」(セキュアプログラミング)を知ればもう議論など必要ない、と思っています。本物の「セキュアコーディング」を「知ろうとしない」と幾らでもアンチプラクティスを作ってしまいます。

議論は終り、と思っていたのですがそうも行かないようなので紹介します。セキュアコーディングの概念を全く知ろうとしないで、セキュリティを作るのは「ただの無駄」です。多数のアンチプラクティス/間違いが含まれるスライドの中から(一々指摘するとキリがない)

  • 「脆弱性を局所的に潰す」

これ”だけ”だとアンチプラクティスです。

※ 契約プログラミングが流行らない理由はこいうアンチプラクティスも原因でしょう。

“「脆弱性を局所的に潰す」はアンチプラクティス” の続きを読む

エンジニアなら分かる文字エンコーディングバリデーションの必要性

入力バリデーションで文字列の妥当性を検証(保証)しないと、不正文字問題の解決はできません。

よく「文字エンコーディングバリデーションは入力バリデーションしなければならない」と紹介はするのですが、その理由を詳しく解説していませんでした。これは文字エンコーディング攻撃の仕組みを理解してれば分かる事なのでしていませんでした。

しかし、文字エンコーディング攻撃の仕組みを理解していても必要なし、とする意見があるので理解り易く説明します。(理解りづらかったら教えてください)UTF-8のみですが、他の文字エンコーディングでも基本は同じです。

“エンジニアなら分かる文字エンコーディングバリデーションの必要性” の続きを読む

バリデーションには3種類のバリデーションがある 〜 セキュアなアプリケーションの構造 〜

バリデーション、と一言で言っても一種類/一箇所だけではありません。バリデーションには3種類のバリデーションがあります。

バリデーションは重要であるにも関わらず誤解が多い機能の筆頭だと思います。日本に限らず世界中でよくある議論に

  • バリデーションはモデルで集中的に行うべきだ!
  • なのでコントローラー(入力)でバリデーションなんて必要ない!
  • モデル集中型バリデーション以外の方法/場所でバリデーションするのは非効率で馬鹿馬鹿しい考えだ!

があります。どこかで見た事があるような議論ですが、世界的にこのような考えの開発者が多いことは、この入力バリデーション用のPHP拡張モジュールを書いた時の議論で分かりました。1

実際、多くのWebアプリケーションフレームワークは入力バリデーション機能をデフォルトでは持たず、アプリケーションレベルでの入力バリデーションを必須化していません。開発者が上記のような考えになっても当然と言えるかも知れません。しかし、必要な物は必要です。何故?と思った方はぜひ読み進めてください。

流石にこの時の議論ではありませんでしたが、以下の様な議論も見かけます(ました)

  • 入力データはバリデーションはできない!
  • どんな入力でもWebアプリは受け付けて”適切”に処理しなければならない!
  • 入力バリデーションにホワイトリスト型は無理、適用できない!
  • ブラックリスト型とホワイトリスト型のバリデーションは等しいセキュリティ対策!
  • 入力バリデーションはソフトウェアの仕様でセキュリティ対策ではない!

全てセキュアなソフトウェア構造を作るには問題がある考え方です。最後の「入力バリデーションはソフトウェアの仕様でセキュリティ対策ではない!」とする考え方の問題点は”セキュリティ対策の定義”2を理解していないと問題点は見えないかも知れません。

  • セキュリティ対策(=リスク管理)とはリスクを変化させる全ての施策で、多くの場合はリスクを廃除/軽減させる施策だが、それに限らない。

このセキュリティ対策の定義はISO 27000/ISMSの定義をまとめたモノです。

 

TL;DR;

入力対策と出力対策は両方必要でエスケープの知識はセキュアなソフトウェア構築には欠かせません。アプリケーションの入り口で入力検証をしていないアプリはセキュアでない構造です。入り口以外に入力検証がないアプリもセキュアではない構造です。セキュアなアプリには最低限、入り口でのデータ検証と出口でのデータ無害化(エスケープ/API/バリデーション)が必須です。

“バリデーションには3種類のバリデーションがある 〜 セキュアなアプリケーションの構造 〜” の続きを読む

出力対策”のみ”のセキュリティはアンチプラクティス

「しっかり出力対策”だけ”するのがセキュリティ対策のベストプラクティス」とする考え方1があります。しかし、これはベストプラクティスどころかアンチプラクティスです。

アンチプラクティスをベストプラクティスと勘違いしている限り、満足のいくセキュリティ対策(=リスク管理)は不可能です。セキュリティ対策は総合的なリスク対策です。「これ”だけ”やれば良い」とするセキュリティ対策は大抵アンチプラクティス2です。

※ 今まで出力対策”だけ”がセキュリティ対策だと勘違いしていた方には確証バイアスが働きやすいようです。論理的/構造的にどうすればリスクを効果的に削減できるのか?を考えると理解るはずです。

“出力対策”のみ”のセキュリティはアンチプラクティス” の続きを読む

まだ誰も知らない脆弱性/攻撃に備える方法

セキュリティを考えると全ての入力データはアプリケーションがバリデーションすべきで、長さ/形式は厳格にバリデーションすべきです。1

厳格なバリデーションは開発者が意識/把握していない各種インジェクション脆弱性にも対応できること、インジェクション攻撃が持たらす被害が致命的であることが、その理由です。

適切なバリデーションは最強のセキュリティ対策の1つ2です。強いデータ型は弱いバリデーションの一種ですが、それでもセキュリティ対策として高い評価を得ています。にも関わらず強いバリデーションである厳格なデータバリデーションはコンピューターサイエンティストのセキュリティ専門家3以外にはあまり評価されていないように感じます。

今回は低レベルのライブラリにもコードインジェクション脆弱性のリスクがあること、その対策としてバリデーションが如何に効果的であるか紹介します。

“まだ誰も知らない脆弱性/攻撃に備える方法” の続きを読む

HKDF, HMACなどのハッシュ関数を使う場合に知っておくべきFS/PFS

PHPにHKDF関数、hash_hkdf()が追加されましたが、そのシグニチャは褒められるモノではありません。

出鱈目なシグニチャのhash_hkdf関数を安全に使う方法

hash_hkdf()が脆弱なAPI仕様になってしまった主な原因は、開発者がハッシュ関数を利用して鍵を導出する場合に知っておくべきFS/PFSの概念を知らなかったことにあります。(秘密鍵のセキュリティ維持にSaltが必須であるとの理解が足りなかったことも原因)

FS/PFSはハッシュ関数を利用した安全な鍵導出に必須の知識です。簡単な概念なので直ぐに理解できると思います。

“HKDF, HMACなどのハッシュ関数を使う場合に知っておくべきFS/PFS” の続きを読む

PHPとXML eXternal Entity(XXE)対策

2017年版OWASP TOP 10がリリースされました。新しくA4としてXXE、A10としてInsufficient Logging & Monitoringが入りました。今回はXXE対策を紹介ます。XXE対策は簡単です。

XXEは「リクエストのインジェクション」と考えると解りやすく、「リクエストのインジェクション」と理解すれば他の類似攻撃パターンにも応用できます。

自分で直接XMLモジュールのクラス/関数を使ってXML処理している場合は問題箇所は判り易いですが、ライブラリなどを使う場合は知らずにXXEに脆弱になりえます。外部XML文書を処理する場合、XML処理ライブラリは盲信するのではなく、XXEに脆弱でないか検証してから使わないとなりません。

“PHPとXML eXternal Entity(XXE)対策” の続きを読む

PHP用入力バリデーションモジュール – validate

ブログで紹介するのを忘れていました。PHP用の入力バリデーションモジュール validateを作りました。

https://github.com/yohgaki/validate-php

PHP開発MLでの議論用に作ったので、作りかけと言える状態ですが、一応動作し使えます。

関数名はvalidate()の方が良いのでは?という意見があったので、名前は変更する予定です。valid()にしていた理由は”validate”だとあまりに一般的過ぎて、同じ名前の関数を定義しているユーザーがいるだろう、と予想したからです。自分のアプリやライブラリには名前空間を使うべきなので、モジュール関数はvalidate()にします。

いろいろ意見があったのですが、やはり入力処理における入力バリデーションとロジック処理の混同がありました。

入力処理における「形式的バリデーション」とロジック処理における「論理的/仕様的バリデーション」は別処理とした方が、構造的に優れています。この理由はまたの機会に書きます。

 

2017年版OWASP TOP 10

追記: 8月現在では、OWASP TOP 10 2017はWAFのプロモーションになっている、OWASP Proactive Controlsの”全ての入力をバリデーションする”と重複している、などの点が議論になりRCはリジェクトされ11月にリリースを目指して調整中になっています。

追記2:正式版が2017年12月にリリースされました。ここで紹介している脆弱性はA10(10番目の脆弱性)「不十分なログとモニタリング」として登録されました。WAFが必要であるかのような記載が削減されましたが、脆弱性の本質(入力検証しない&対応しないアプリは脆弱なアプリ)は変わりありません。

 

このテーマついては既にブログは書いています。このエントリでは追加でQ&Aを記載しています。

2017年度版 OWASP TOP 10 で変るWebセキュリティのルール

元々はこのスライドは非公開にするつもりでしたが、公開可能な内容で公開することにしました。

開発会社としてはどうすれば良いのか?と質問を頂いたので追記します。

“2017年版OWASP TOP 10” の続きを読む

SQLインジェクション対策 総”習”編 – 第五回関西DB勉強会

第五回 関西DB勉強会でお話しさせて頂いた SQLインジェクション対策 総”習”編 の公開用資料をSlideShareにアップロードしました。私のセッションを気に入って頂けた方が多かったようで何よりです。

関西DB勉強会、面白かったです。久々にお会いできた方もいました。超満員でもう少しで入りきれないほどでした。また参加できれば、と思っています。

PDFはこちらからダウンロードできます。

 

勉強会で使ったスライドは、面白おかしく柔らかい(?)スライドでした。あまり公開用には向いていません。実際に勉強会で使った資料が欲しい方はFacebookかメールで連絡してください。個別にお送りします。