リスク分析とリスク対応をしよう

情報セキュリティ対策 ≒ リスクの分析、対応と管理、としても構わないくらい情報セキュリティ対策にとってリスク分析は重要です。体系的にまとめられたセキュリティ対策ガイドラインなら、どれを見ても記載されています。

情報システムは「モノ」(物と人)、「ネットワーク」、「ソフトウェア」で出来ています。それぞれリスクを分析、対応、管理する必要があります。

当然、ソフトウェアのリスク分析も重要です。しかし、多くの場合は「脆弱性対策」という形でリスク分析をせずにいきなり対応する、といったショートカットが開発現場で日常的に行われています。目の前にある問題に直ぐ対応しなければならない!といった場合も多いので仕方ない側面もあります。

しかし、問題は開発工程の早い段階で対応すればするほど、少ないコストで対応できます。システム開発に関わる人なら誰でも認識している事です。できる限り早い段階で早く問題に対応する、は情報システム開発の要求仕様のみでなく、セキュリティ要求仕様にも当てはまります。

※ このブログの説明はWebシステムを前提にしています。STRIDE、DREAD、リスクマトリックスなどのリスク分析手法はISO 31000等を参照してください。このブログでは単純なアタックツリー形のリスク分析を紹介しています。

“リスク分析とリスク対応をしよう” の続きを読む

究極のセキュリティ要求事項とは?

前のブログでリスク分析について書きました。リスク分析方法を書く前にセキュリティ要求について書きます。ISO 27000では6つのセキュリティ要素が情報セキュリティに必要であるとしています。

  • Confidentiality – 機密性
  • Integrity – 完全性
  • Availability – 可用性
  • Reliability – 信頼性
  • Authenticity – 真正性
  • Non-repudiation – 否認防止 (Accountability – 責任追跡性)

これらが基礎的な情報セキュリティの要求事項になります。以上です。

※ 2014年の改訂でセキュリティのCIAに信頼性、真正性、否認防止を加えたモノが情報セキュリティに必要な要素と定義されています。ISO 13335(古い情報セキュリティ標準)で定義していた要素に戻った形になりました。

これで終わってしまうと何の事なのか?究極の要求事項とは何なのか?となると思います。もう少し説明します。究極の要求事項を知って適用するだけ、でも大きな違いが生まれると思います。

“究極のセキュリティ要求事項とは?” の続きを読む

無視されているリスク分析

炎上プロジェクトの主な原因の1つに、システム要求定義が不明確であること、があります。何を作ったらよいのか、よく分らない状態で作って上手く行くのを願うのは、サイコロを振るのと変りありません。

これと同じことが情報セキュリティ対策でも起きています。

致命的な脆弱性が残っているシステムの主たる原因の1つに、セキュリティ要求定義が不明確、ならまだよいのですがセキュリティ要求定義なし、であることが少なくない数あります。IoTやスマートカーのセキュリティを見れば明らかです。セキュリティ要求定義が不明確か無い状態で作った、としか思えない事例が数えきれません。

漏れのないセキュリティ要求定義には漏れのないリスク分析が必要です。

  • ◯◯対策として△△を実施する

といったセキュリティ仕様をセキュリティ要求だと勘違いしているケースも数えきれません。

システム要求定義がないプロジェクトが簡単に炎上するように、セキュリティ要求定義がないシステムも簡単に無視することが不可能な脆弱性だらけのシステムになります。

特にソフトウェアの分野では「リスク分析」が不十分過ぎる、さらには全く無い、システムで溢れています。これでは十分な安全性を効率良く達成することは不可能です。

続きを読む

入力データのバリデーションを簡単に 〜 Validate for PHP 0.7.0

基本的にWebアプリへの入力データは全てバリデーションする必要があります。具体的には以下のような構造でバリデーションが必要です。

Webアプリへの入力データの種類は大抵の場合、数百程度です。Validate for PHPはこれらの入力仕様を定義すれば、アプリケーション内で繰り返し同じ入力仕様をバリデーションできるように作られています。

Validate for PHPのスクリプト版をPre Alphaとしてリリースします。このブログのGitHubリポジトリのリンクは0.7.0ブランチに向いています。開発版はmasterブランチを参照してください。

“入力データのバリデーションを簡単に 〜 Validate for PHP 0.7.0” の続きを読む

データフロー分析とセキュリティ

データフロー分析とはコールフローグラフ(CFG)を使ってプログラムを分析する手法です。ソフトウェアのセキュリティ対策にもデータフロー分析は広く利用されています。例えば、静的ソースコード検査ツールは静的(=プログラムを動作させず)にプログラム実行時のデータフローを分析し、問題を発見する手法です。

コールフローグラフ

データフロー分析の基礎知識はハーバード大学コンピューターサイエンス学科の講義資料(PDF)が参考になります。こちらを参考にしてください。英語の資料ですが容易な内容です。

“データフロー分析とセキュリティ” の続きを読む

ゼロトラストとフェイルファースト

今のプログラムに足りないモノでセキュリティ向上に最も役立つ考え方のトップ2つ挙げなさない、と言われたらどの概念/原則を挙げるでしょうか?

私なら

  • ゼロトラスト
  • フェイルファースト

を挙げます。

極論すると、この2つ知って実践するだけでセキュアなソフトウェアを作れるようになるからです。この2つだけでは十分ではないですが、これを知って、実践しているだけでも開発者は今のコードより段違いにセキュアなコードが自分で書けるようになります。

もう一つ追加するなら

  • 多層防御(縦深防御)

を加えます。これはゼロトラストとフェイルファーストから導き出せる概念です。ゼロトラストとフェイルファーストで検証を行うと自然と多層防御になります。多層防御はセキュリティ対策の基本ですが、特にソフトウェアでは実践されている、とは言えない状況です。

これら3つはとても有用な概念で単純明解な概念ですが、知られていなかったり、誤解されていたりすることが多い概念/原則と言えるかも知れません。

“ゼロトラストとフェイルファースト” の続きを読む

セキュアコーディングの構造/原理/原則

セキュアコーディング/セキュアプログラミングはコンピューター動作の基礎的原理から構築されています。初めてプログラムが書かれた時から現在に至るまで、全てのプログラムは同じ基本構造を持っています。

基本原理/基本構造に合わないセキュリティ対策/構造では満足できるセキュリティ状態の達成は不可能です。残念ながら大半のWebアプリが原理に反する脆弱な構造を持っています。

IPAが出鱈目なセキュアプログラミングを啓蒙していた責任は大きいと言わざるを得ないでしょう。昨年、修正しましたが誤りを訂正すべく十分な啓蒙を行っているとは言えないように見えます。

“セキュアコーディングの構造/原理/原則” の続きを読む

攻撃可能面の管理 – セキュリティの基本

Attack Surface (攻撃可能面=攻撃可能な箇所)の管理はセキュリティ対策の基本中の基本です。あまりに基本すぎてあまり語られていないように思います。

攻撃可能面を管理するには先ず攻撃可能な箇所がどこにあるのか分析(=リスク分析)します。その上でできる限り攻撃可能な箇所を削減(=リスク削減)します。攻撃可能面の分析と管理とはリスク分析と管理です。セキュリティ対策そのものと言える、基本的な管理です。

Attack Surface (攻撃可能面)

The attack surface of a software environment is the sum of the different points (the “attack vectors“) where an unauthorized user (the “attacker”) can try to enter data to or extract data from an environment.[1][2] Keeping the attack surface as small as possible is a basic security measure.

出典:Wikipedia

日本語訳すると以下のようになります。

ソフトウェア環境における攻撃可能面は不正なユーザー(攻撃者)がデータを攻撃対象に入力または取り出し可能な様々箇所(アタックベクター)の集合である。攻撃可能面を可能な限り小さくするのは基本的なセキュリティ対策である

“攻撃可能面の管理 – セキュリティの基本” の続きを読む

開発者の自由を許容するセキュリティ、自由を束縛するセキュリティ

アプリケーション開発におけるセキュリティ対策は大きく別けて、自由を制限するセキュリティ対策と自由を許容するセキュリティ対策の2種類に分けられると思います。

「セキュリティ対策の為に自由を制限する対策”だけ”でなければならない」とする意見を時々見かけます。しかし、これでは必要な仕様を満すソフトウェアが作れなかったり、不必要なコストが要るソフトウェアになったりします。

“開発者の自由を許容するセキュリティ、自由を束縛するセキュリティ” の続きを読む

プログラミングを覚えたら先ず知るべきコーディングプラクティス

プログラミングを覚えたら先ず知るべきコーディングガイドラインを紹介します。このブログではこれらのガイドラインを時々紹介していましたが、まとめて紹介するのは初めてだと思います。これから紹介するガイドラインはセキュアプログラミング/防御的プログラミング/セキュアコーディングと呼ばれる考え方に基づいたガイドラインです。

ここで紹介する考え方や基本はコンピューターサイエンティストらによって原理/論理から導き出された概念/考え方です。

論理的に出鱈目なセキュリティの考え方が当たり前かのように啓蒙され、脆弱なアプリケーションの作成を助長しています。最後にアンチプラクティスの例として紹介します。

“プログラミングを覚えたら先ず知るべきコーディングプラクティス” の続きを読む

「フェイルセーフ」とは何なのか?

「フェイルセーフ」よく聞く言葉です。最近では「フェイルセキュア」1と言われることもありますが、基本概念は同じです。よく聞く言葉&簡単な概念ですが、割と広く誤解されている概念の1つに見えます。

フェイルセーフを一言で言うと

何かに失敗しても致命的な問題に至らないよう安全に失敗させる

これがフェイルセーフです。可能ならば「失敗/故障しても、失敗/故障の影響を受けないようする」場合もあります。ITシステムならRAID5や失敗時のリトライなどがこのケースです。

Wikipediaの定義では

フェイルセーフ(フェールセーフ、フェイルセイフ、英語fail safe)とは、なんらかの装置・システムにおいて、誤操作・誤動作による障害が発生した場合、常に安全側に制御すること。またはそうなるような設計手法で信頼性設計のひとつ。これは装置やシステムが『必ず故障する』ということを前提にしたものである。

となっています。

こんな単純な概念は間違いようがないでしょ?

と思うかも知れません。しかし、ソフトウェア開発では当たり前に誤解されています。

“「フェイルセーフ」とは何なのか?” の続きを読む

セキュリティを論理的に構築する方法

セキュリティの原理、原則、ベストプラクティスに自分でコメントを追加しました。以前、論理的にセキュリティ対策を検証する方法論理的なセキュリティ対策の評価方法は書いたのですが、論理的にセキュリティを構築する方法は書いていないことを思い出しました。追加したコメント欠陥だらけのソフトウェアセキュリティ構造を紹介したブログをベースにセキュリティを論理的に構築する方法を紹介します。

このエントリの解説はCERT、つまり米カーネギーメロン大学、の資料をベースにしています。

“セキュリティを論理的に構築する方法” の続きを読む

セキュリティの原理、原則、ベストプラクティス

「セキュリティの」と付けていますが、どの分野でも共通することだと思います。

何事でも論理的に何かのガイドライン/ルールを作る場合、まず変えることのできない

  • 原理 – 事物・事象が依拠する根本法則

を見つけ、その原理から導き出される

  • 原則 – 多くの場合に共通に適用される基本的なきまり・法則

を作り、さらに特定の条件下の具体的な事例として

を作ります。原理、原則、ベストプラクティスを理解していないと様々な問題がおきます。これらの基本的関係は

原理 > 原則 > ベストプラクティス

です。しかし、適用範囲の広さは

原理 < 原則 < ベストプラクティス

です。例えば、ベストプラクティスは”例外的”に原則に反した方法が”最善の方法”となる場合も少なくないからです。よく混乱や誤解の元になりますが、条件を絞った場合(例外的なケース)のベストプラクティスも在ります。

例外的なケース(一般的で無いモノ=例外的な物)をベストプラクティスにすることには異論もありますが、結構狭い条件でしかベストプラクティスにならないモノが”ベストプラクティス”と呼ばれていることは多いです。1

“セキュリティの原理、原則、ベストプラクティス” の続きを読む

出力対策の3原則 + 1原則

ソフトウェアの不具合/脆弱性を無くすためには、出力先に対して無害であることを保障する出力対策が重要です。どんな出力でも3つの方法で無害化できます。

このブログでは基本として、セキュアコーディングの概念に基き説明しています。先ずはよくある入力対策と出力対策の区別がついていない誤りから紹介します。

参考:IPAは基礎的誤りを明示し、正しい原則を開発者に啓蒙すべき

“出力対策の3原則 + 1原則” の続きを読む

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

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

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

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

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

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

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

  • 入力データはバリデーションはできない!
  • どんな入力でもWebアプリは受け付けて”適切”に処理しなければならない!
  • 入力バリデーションにホワイトリスト型は無理、適用できない!
  • ブラックリスト型とホワイトリスト型のバリデーションは等しいセキュリティ対策!
  • 入力バリデーションはソフトウェアの仕様でセキュリティ対策ではない!
  • 脆弱性発生箇所を直接または近い個所で対策するのが本物のセキュリティ対策である!

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

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

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

TL;DR;

何事も原理と基本が大切です。基礎的な事ですがプログラムの基本構造と動作原理を正しく理解しておく必要があります。

セキュアコーディングの構造/原理/原則

入力対策と出力対策は両方必要でバリデーションはセキュアなソフトウェア構築には欠かせません。

アプリケーションの入り口で入力バリデーション(入力検証)をしていないアプリはセキュアでない構造です。

入り口以外に入力検証がないアプリもセキュアではない構造です。セキュアなアプリには最低限、入り口でのデータ検証と出口でのデータ無害化(エスケープ/無害化API/バリデーション)が必須です。

  • プログラムは妥当なデータでしか正しく動作できない入力バリデーションは原理的に必須
  • 出力対策は必須の物とフェイルセーフ対策の物があるフェイルセーフ対策の場合は下層の多層防御です。そもそも”データが妥当でない場合”(=フェイルセーフ対策)のエラーは起きてはならない。当然ですが出鱈目なデータを処理するのもNG。

多層防御 3 は重要なのに勘違いされているソフトウェアセキュリティ要素の1つです。

バリデーションには3つの種類があります。

  • 入力バリデーション正しく動作する為に必須(主に形式検証)
  • ロジックバリデーション正しく動作する為に必須(主に論理検証)
  • 出力バリデーション –  大半が上の2つに失敗した場合のフェイルセーフ対策(追加の対策 – 安全な特定形式のみ許可の場合)

※ 出力時のエスケープ/エスケープが不必要なAPIの利用によるデータの無害化は、必須の対策が半分、フェイルセーフ対策が半分です。

※ “入力ミスの確認”を”バリデーション”と考えたり、言ったりすると混乱の元です。”入力ミス/論理的整合性の確認エラー”は処理の継続、”あり得ないデータによるバリデーションエラー”では処理の中止、が必要なので区別する方が良いです。

※ ソフトウェア基本構造の入力処理では”あり得ないデータによるバリデーションエラー”、ロジック処理では”入力ミス/論理的整合性の確認エラー”、になります。

※ リスク分析の経験があれば自然にセキュアな構造を思い付くことも可能だと思います。

リスク分析とリスク対応をしよう

イメージ図:

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

実は知られていない?リスク対策の原則?

ISO 31000(リスクマネジメント標準規格)はa)からk)まで、11のリスク管理の原則を定めています。

ITエンジニアであればISO 27000(情報セキュリティマネジメント標準規格)を一度は読んだことがあると思います。少なくとも名前くらいは知っていると思います。リスク管理の基礎/基本を理解していればISO 27000だけでも十分ですが、ちょっと自信がない、体系的には学んだ事がない方はISO 31000も参考にすると良いです。

情報セキュリティマネジメントはリスクマネジメントの一分野です。一般論としてのリスク管理の基礎知識は役立ちます。

リスク対策の原則が知られていない?ことも、間違ったセキュアコーディング理解の原因かもしれません。間違いだらけのセキュアコーディング解説も紹介します。

“実は知られていない?リスク対策の原則?” の続きを読む

信頼境界線の引き方と防り方 – セキュリティの構造と設計

信頼境界線Trust Boundary)と境界防御はITセキュリティに限らず、セキュリティ対策の基礎中の基礎です。基礎中の基礎かつ最も重要な概念ですが習わないことが多いです。これが原因で「正しいセキュリティ対策」(≒効率的なセキュリティ対策)ができていないケースが多数あります。残念ながら”セキュリティに詳しい”とされている人でも全く理解していないケースが散見されます。

このエントリでは主に、ソフトウェアセキュリティに於ける信頼境界線の概念と引き方(≒セキュリティ構造/設計)、ついて紹介します。かなり長いエントリになりましたがお付き合いください。

“信頼境界線の引き方と防り方 – セキュリティの構造と設計” の続きを読む

完全なSQLインジェクション対策

不完全なSQLインジェクション対策だけで、SQLインジェクション対策は万全、と誤解しているケースが少なくないです。

  • プリペアードクエリ/プレイスホルダを使ったSQLインジェクション対策でOK

は誤りです。「とにかくプレイスホルダを使おう」では脆弱性は無くなりません。

簡単な証明:プリペアードクエリ”だけ”では、識別子(カラム/テーブル等)を使うソートクエリ、特定カラム抽出クエリを”原理的”に無害化できない。識別子のエスケープ/バリデーションが必須。(問題はコレだけはありません)

似たような間違いに「出力対策をするのがセキュリティ対策」だとする考え方があります。こういう考え方になる原因はセキュリティ設計や原則を理解していないことにあると思われます。

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

アンチプラクティスであっても正しく動作するならまだ良い方です。しかし、論理的・原理的に出力対策”だけ”では正しく動作するアプリケーションは作れません

参考:

“完全なSQLインジェクション対策” の続きを読む