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

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

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

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

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

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

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

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

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

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

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

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

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

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

なぜWebセキュリティはここまでダメなのか?

インターネット上に16億件の企業ユーザーのメールアドレスとパスワードが公開されている、とニュースになっています。ほとんどの漏洩元はこれらの企業ではなく、他の一般公開されているWebサービスなどのアカウント情報漏洩※だと考えられています。

この事例から、非常に多くのWebサービスが情報漏洩を伴うセキュリティ問題を抱えているにも関わらず、気がつくことさえも出来ていないという現状があると考えるべきでしょう。(もしくは気付いていても公開していない)

侵入されたことを検知/対応する技術の導入も重要ですが、ここではなぜWebセキュリティはここまでダメになっているのか?を考えます。

※ 情報漏洩にはベネッセのケースのように内部の人による持ち出しも含まれていますが、外部の攻撃者が盗んだ情報も少なくないと考えるべきでしょう。

“なぜWebセキュリティはここまでダメなのか?” の続きを読む

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

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

私なら

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

を挙げます。

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

もう一つ追加するなら

  • 多層防御(縦深防御)

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

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

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

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

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

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

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

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

”形式的検証”と”組み合わせ爆発”から学ぶ入力バリデーション

形式的検証とは

形式的検証(けいしきてきけんしょう)とは、ハードウェアおよびソフトウェアのシステムにおいて形式手法数学を利用し、何らかの形式仕様記述やプロパティに照らしてシステムが正しいことを証明したり、逆に正しくないことを証明することである

英語ではFormal Verificationとされ

formal verification is the act of proving or disproving the correctness of intended algorithms underlying a system with respect to a certain formal specification or property, using formal methods of mathematics.

と説明されています。形式手法として紹介されることも多いです。

参考: 形式検証入門 (PDF)

形式的検証は、記述として検証する方法から数学的にプログラムが正しく実行されることを検証する仕組みまで含みます。数学的な形式的検証では、可能な限り、全ての状態を検証できるようにしてプログラムが正しく実行できることの証明を試みます。

参考:ソフトウエアは硬い (日経XTECHの記事)

契約プログラミング(契約による設計 – Design by Contract, DbC)も形式的検証の1つの方法です。

形式検証の仕組みを知ると、厳格な入力バリデーションが無いと”組み合わせ爆発”により、誤作動(≒ セキュリティ問題)の確率も爆発的に増えることが解ります。

“”形式的検証”と”組み合わせ爆発”から学ぶ入力バリデーション” の続きを読む

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

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

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

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

ソフトウェアはセキュリティの原理・原則から間違っている「入り口ノーガード設計」のままで良いのか?

現在のWebアプリケーションのほとんどは「入り口対策」がない「入り口ノーガード設計」です。

※ アプリケーションの入力処理、つまりMVCアーキテクチャーならコントローラーレベルで「入り口対策」がない設計が「入り口ノーガード設計」です。

このような設計になっているので、本来は自然数だけのハズのHTTPヘッダーのContent-Length(やContent-Type/Content-Disposition)にプログラムが書けてしまったStruts2 Webアプリにより国内ではクレジットカード情報が何十万件も盗まれる、米国では1億4千万件以上の信用情報が漏洩する、といった事件が発生しています。

幸い、「入り口対策」がない「入り口ノーガード設計」でもこういった大規模インシデントになるような脆弱性の攻撃は多くありません。しかし、話題にならないだけで多数のインシデントが世界中で発生していると考えられます。

先の事例はStruts2/フレームワークのセキュリティ問題、と捉えられていることが多いと思います。しかし、これは本質的にセキュリティ原則を無視した「入り口ノーガード設計」の問題です。

コード検査していると「入り口対策」をしていて、本当に良かったですね!というケースに出会うことが少なくありません。

2018年5月からEUでGDPRが施行されます。GDPR違反となると2000万ユーロまたは全世界売上の4%のどちらか高い方が罰金(組織によっては1000万ユーロまたは全世界売上の2%)となります。GDPRには様々な要件が要求されていますが、国際情報セキュリティ標準であるISO 27000で”普及している”とされた”セキュアプログラミング技術”の原則さえ採用しないシステムで個人情報漏洩が起きた場合の被害は、簡単に会社を潰すレベルの損害になる可能性があります。

“ソフトウェアはセキュリティの原理・原則から間違っている「入り口ノーガード設計」のままで良いのか?” の続きを読む

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

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

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

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

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

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

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

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

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

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

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

TL;DR;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

ソフトウェア開発環境のセキュリティ対策

ソフトウェアの開発環境は通常の環境と違う対策が必要です。その理由は開発環境には

  • 他人が書いた未検証のモノ
  • 自分が書いた実験用のモノ
  • 他人または自分が書いた作りかけのモノ
  • 制御された環境での利用を前提としたモノ
  • 意図的に利用している新しいモノ(リリース前のソフトウェアなど)
  • 意図的に利用している古いモノ(古いシステムサポートためなど)

※モノにはコード/ライブラリ/ツール/アプリ/システム などがあります。

などがある為です。開発環境はその他の環境に比べ「とにかく危険なモノがいっぱい」です。

更に最近ではソーシャルコーディングが当たり前になり、他人が書いた未検証のコードがどんどん実行される状態も当たり前です。それも1つ2つのライブラリではなく、依存性から何百、場合によっては何千というライブラリなどが自動的にダウンロードされ実行されています。

これがどういう状況かというと「PCがやっと使えるくらいのユーザーが、インターネットからプログラムをダウンロードしまくって実行している状況」とあまり変わりません。

参考: SOHO・家庭の安全なネットワーク環境2018

“ソフトウェア開発環境のセキュリティ対策” の続きを読む

なぜセキュリティ対策はリスクの増減として考えるのか?

ITセキュリティ標準ではセキュリティ対策(リスク対応)はリスクの増減に着目して対策を行います。(最初のリスクアセスメントが正しく実行されていれば、リスクの増減を見るだけで管理/対策できる)概念的な部分は理解しづらいようなので、なぜセキュリティ対策をリスクの増減として考えるのか解説します。

ここで紹介していることはリスク管理の基本的な概念です。リスク対策はITセキュリティ対策に対して上位互換、つまりより広い範囲のリスク/セキュリティ対策です。

“なぜセキュリティ対策はリスクの増減として考えるのか?” の続きを読む

セキュアプログラミング第一位の対策、入力バリデーションはセキュリティ対策ではない?!

セキュアコーディング/セキュアプログラミングにおける最も重要なセキュリティ対策は「入力バリデーション」です。国際標準ではセキュリティ対策か否かは「リスクの変化」によって決り、※多くのセキュリティ専門家が「入力バリデーションをNo1のセキュリティ対策である」と結論づけています。(※ 対策の目的が何か?などの主観に基く評価はセキュリティ対策か否か、を決める指標ではありません)

どういう論理なのかは全く理解できないのですが、これに異論を唱える方も居るようです。実際のセキュアコーディング/セキュアプログラミングのガイドラインなどがどうなっているのか?紹介します。

このブログを継続して読んでいる方にはただの繰り返しなので読み飛ばしてください。そもそもセキュアコーディング/セキュアプログラミングとは何か?は過去のブログをご覧ください。

“セキュアプログラミング第一位の対策、入力バリデーションはセキュリティ対策ではない?!” の続きを読む

ほぼ全てのインジェクション攻撃を無効化/防止する入力バリデーション 〜 ただし出力対策も必須です 〜

入力バリデーションはセキュリティ対策として最も重要なセキュリティ対策です。なぜセキュリティ対策であるのか?を理解していない方も見かけますが「ほぼ全てのインジェクション攻撃を無効化/防止する入力バリデーション」の効果と拡張方法を見れば解るのではないでしょうか?

ソフトウェア開発者が知っておくべきセキュリティの定義/標準/ガイドで紹介しているセキュリティガイドラインでは入力バリデーションが最も重要なセキュリティ対策であるとしています。

厳格な入力バリデーションを行うと、開発者が意識しなくても、非常に多くの脆弱性を利用した攻撃を防止できます。今回は比較的緩い入力バリデーション関数でも、ほとんどのインジェクション攻撃を防止できることを紹介します。

重要:セキュア/防御的プログラミングでは入力と出力のセキュリティ対策は”独立”した対策です。どちらかをすれば良い、ではなく入力と出力の両方で対策を行います。よく誤解されるので注意してください。

重要 その2:ホワイトリストの基本中の基本は”デフォルトで全て拒否する”であることに注意してください。全て拒否した上で、許可するモノ、を指定しないとホワイトリストになりません。ホワイトリストによる入力バリデーションは”無害化”ではありません。”妥当性の検証”です。

重要 その3あまり広く理解されていませんが、セキュアコーディングの第1原則は「全ての入力をバリデーションする」、第7原則が「全ての出力を(エスケープ/API/バリデーションで)無害化するです。セキュアコーディングはISMS/PCI DSSなどの認証規格の要求事項です。

なぜこのようなブログを書いたか?というと入力バリデーションしていても、”ほぼ全てのインジェクション攻撃を無効化/防止できる入力バリデーション”でない場合、入力時のセキュリティ処理だけでは”残存リスク”としてインジェクション攻撃が可能になる、という事を理解して欲しいからです。

参考:

“ほぼ全てのインジェクション攻撃を無効化/防止する入力バリデーション 〜 ただし出力対策も必須です 〜” の続きを読む