(Last Updated On: 2018年10月18日)

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

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

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

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

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

TL;DR;

できる限り簡潔に書こう、と思いましたが書いてみると長くなってしまいました。項目だけを挙げるなら簡潔になります。それならISO 27000/13335を直接読んで理解する方が良いでしょう。

考え方を知っているだけでもより良い開発ができると思います。ということで結論の、究極のセキュリティ要求事項=最も根本的なセキュリティ要求事項、は以下になります。

  • 情報システムが正しく動作することを確実にする

※ これはISO 27000の定義をまとめた定義です

要求定義/仕様定義/実装を行う際に、これを徹底して実施すると自然とセキュアなモノになっていきます。(ブラックリスト型になると、正しく実行することを確実にするのは構造的に無理になります。ホワイトリスト型が基本です)

正しいのか簡単に検証します。

p : 情報システムが安全に動作する
q : 情報システムが確実に正しく動作する

p ⇒ q は成り立ちます。q ⇒ p は、成り立ちません。

q ⇒ p が成り立つには以下の条件が必要です。

  • システム要求定義/仕様定義/実装が正しい場合

実装は仕様により決まり、仕様は要求によって決まります。”正しい”要求定義が重要です。ここから間違えると後で取り返すのは無理です。取り返すには要求/仕様を無視するか、定義されていない要求/仕様を実装する、必要があります。

システム機能要求とセキュリティ要求

情報セキュリティの要求事項を説明する前に、セキュリティ要求とシステム機能要求の違い、を明確にします。

まず基本として、

  • セキュリティ要求 はシステム機能要求の部分集合

です。セキュリティ要求はシステム機能要求のサブセット、つまりセキュリティ要求はシステム機能要求の一部です。

同じモノを別々に考えるのは「単純」にする為です。セキュリティ要求はアプリケーションに必要とされるシステム機能要求とは”別々”に考えても問題ありません。

  • システム機能要求 – システムが実装すべき機能(システムを構築する目的)
  • セキュリティ要求 – システムが実装すべきセキュリティ機能

※ ISOの定義では「リスクを変化させるモノ」全てがセキュリティ機能で管理対象

システム機能要求 + セキュリティ要求 に分割することにより、それぞれを単純化できます。

  • システム機能要求 → 基本的にアプリケーション処理ロジック
  • セキュリティ要求 → 基本的にシステム機能に追加すべきセキュリティ処理

システム機能仕様とセキュリティ仕様を定義する際にも、分割している方が単純化でき解りやすく、管理しやすくなります。セキュリティ要求は実装するシステム機能に関わらず共通する部分も多く、再利用/標準化が容易なのでシステム構築の効率化も可能です。

近年ではアクセシビリティが重要視されています。アクセシビリティ要求もセキュリティ要求と同じく、別の要求事項としてまとめた方が解りやすく、管理しやすい要求事項になります。

究極のセキュリティ要求

究極のセキュリティ要求とは最も根源的なセキュリティ要求のことを指します。

ISO 27000が定める情報システムが持つべきセキュリティ要素は、既に記載した通り

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

です。同じくISO 27000のリスクの定義から、上記の不確実性(リスク)を緩和/排除/管理することがセキュリティ対応(=セキュリティ対策)の目的になります。

理想的には、上記のセキュリティ要素の不確実性(リスク)を確実に無くす、ことが目的になります。これを一言で表すと

  • 情報システムが正しく動作することを確実にする

となり、これが究極のセキュリティ要求になります。

要求通り情報システムが正しく動作しているのであれば、そこに脆弱性やその他の問題が発生することはありません。これ以上包括的な要求事項は無いでしょう。

情報システムが正しく動作することを確実にする

ISO 27000やCERT Secure Codingを「情報システムが正しく動作することを確実にする」ことを目的としていると理解した上で読むと、ISO 27000、CERT Secure Codingの内容/指針が「正しく動作することを確実にする」為の記述になっていることが解ります。

話を簡単にするためアプリケーション開発のセキュリティ要求に限定して説明を続けます。

今のアプリケーション開発のセキュリティ要求はほぼ全てが欠陥品

多くのアプリケーションは、

  • アプリケーション出力やAPI呼び出しの奥深くで、”致命的な誤作動”が起きない様に処理する

ように作られています。これがセキュリティ要求定義になっているからでしょう。しかし、残念ながらこれでは「正しく動作することを確実にする」要求定義になっていません。不完全で欠陥のあるセキュリティ要求です。

例えば、この不完全な要求に従いSQLインジェクション対策をしているケースを取り上げます。

PostgreSQLのSQL実行にプリペアードクエリだけを使ってリスクに対応したとします。

pg_query_params($db, ‘SELECT * FROM table WHERE col = $1’, [$_GET[‘col’]]);

これでcolに対する”致命的な誤作動”であるSQLインジェクションは防げます。しかし、これだけではSQL実行時にエラーになってしまう/不正な値を保存してしまう不確実性には対応できません。

  • colが数値の場合
    • 整数なのに浮動小数点、またのその逆
    • 範囲外
  • colが文字列などの場合
    • 不正な長さ
    • 不正な文字エンコーディング
    • 不正な文字
    • 不正な形式

SQL文実行時に構文エラー/制約エラーになってしますと、エラー発生が遅すぎてシステムとして上手く対応できないことも少なくありません。

しかし、エラーになってデータベースにデータが保存でないケースはまだ良い方です。不正なデータが保存できてしまった場合、その不正なデータが取り出されて利用される場合の不確実性まで増加します。

不正なデータが取り出されて利用されるケースの不確実性を考慮する以前に、

  • 不正なデータが保存できてしまう

この動作は「正しく動作することを確実にする」要求を満たしていません。つまり、セキュリティ要求として

  • アプリケーション出力やAPI呼び出しの奥深くで、”致命的な誤作動”が起きない様に処理する

とするのは欠陥品です。「プリペアードクエリ/プレイスホルダだけ使っていれば良い」といったセキュリティ”仕様”となってしまうようなセキュリティ”要求”ではダメである、となります。

※ 「プリペアードクエリ/プレイスホルダだけ使っていれば良い」とするセキュリティ仕様は不正なデータ保存を許してしまうだけではなく、不正なSQL操作まで許してしまいます。

安全なアプリケーション開発のセキュリティ要求

安全なアプリケーションセキュリティ要求を定義するには、究極の要求事項である「正しく動作することを確実にする」必要があります。どのような要求事項が必要でしょうか?

ISO 27000のセキュリティ要素とCERT Top 10 Secure Coding Practicesが役立ちます。これらを考慮した安全なセキュリティ要求は以下のようになります。

  • 信頼できない全ての入力データの妥当性を検証する。妥当でないデータは受け入れない。なお検証は可能な限り早い時点で行う。(セキュアコーディング原則1、完全性、信頼性、可用性)
  • データを利用する場合、信用の範囲内(検証の範囲内)で利用する。必要な場合は追加の検証を行う。(セキュアコーディングの基礎、完全性、信頼性、可用性)
  • 処理を実行するエンティティがその処理を実行する権限および許可を持っていることを保証する。(機密性、真正性、信頼性)
  • データ変更時に原子性(Atomic)が必要な場合は原子性を保証する。(完全性、信頼性)
  • データ操作を記録し、後から記録を参照可能にする。(否認防止)
  • 全ての出力データが出力先に対して妥当な形式(正しい形式)であることをそれ以前の処理から独立して保証する。(セキュアコーディング原則7、信頼性)

上記のどれが欠けても「正しく動作することを確実にする」ことが出来なくなります。当たり前ことばかり、と感じた方も少なくないと思います。

不完全で危険な要求定義である

  • アプリケーション出力やAPI呼び出しの奥深くで、”致命的な誤作動”が起きない様に処理する

  • 全ての出力データが出力先に対して妥当な形式(正しい形式)であることを、それ以前の処理から独立して保証する。(セキュアコーディング原則7、信頼性)

が相当します。

不完全で危険な要求定義は記述方法(考え方)にも問題があります。

「”致命的な誤作動”が起きない様に処理する」はダメなモノを定義するブラックリスト型 の記述です。ブラックリスト型のセキュリティ対策は漏れ/間違いが発生しやすくなります。

「妥当な形式(正しい形式)であることを、それ以前の処理から独立して保証する」はホワイトリスト型の記述です。正しく動作することを保証する(良いモノを定義しそれに限定する)と結果的に不正な動作の可能性を排除/緩和できます。

ホワイトリスト型の思考を行う、は全てのセキュリティ対策に共通する基本です。セキュリティ要求を定義する場合も同じです。

共通言語としてのセキュリティ標準/ガイドライン

そもそもセキュリティ標準やガイドラインは関係者の間で円滑なコミュニケーションが取れる共通言語としての役割も持っています。

セキュリティ標準やガイドラインの要求事項を当たり前のこと、として関係者の間で理解していれば、当たり前の要求は省略することが可能です。当たり前のことを繰り返し定義書に書くと、無用に定義書のボリュームが増え、複雑性が増します。複雑性の増加は不確実性を増加させます。

ISO 27000やCERT Top 10 Secure Coding Practicesといったセキュリティ標準/ガイドラインの概念は関係者の共通認識/共通言語として共有すると、セキュリティ要求の記述を簡素化できます。結果として確実性(=安全性)が増します。

  • 信頼できない全ての入力データの妥当性を検証する。妥当でないデータは受け入れない。なお検証は可能な限り早い時点で行う。(セキュアコーディング原則1、完全性、信頼性、可用性)
  • データを利用する場合、信用の範囲内(検証の範囲内)で利用する。必要な場合は追加の検証を行う。(セキュアコーディングの基礎、完全性、信頼性、可用性)

上記のセキュリティ要求(=「正しく動作することを確実にする」要求)は当たり前の要求事項とし、ISO 27000やCERT Top 10 Secure Coding Practicesで要求事項されているモノは含まれていることを前提にした方が良いです。

※ 実際にはこれが出来ていないアプリケーションが非常に多い。特にWebアプリではほとんど出来ていないと言える程多い。

セキュリティ要求とリスク分析

セキュリティ要求はセキュリティ上の脅威が存在するので生まれる、と捉えることが可能です。この為、セキュリティ上の脅威を把握していないとセキュリティ要求は定義できずリスク分析もできない、と考えられていることが多いように思います。

しかし、実際にはセキュリティ要求とリスク分析は”鶏と卵”のような関係です。リスク分析からセキュリティ要求が生まれ、それらを更にリスク分析すると更にセキュリティ要求が生まれるからです。

「正しく動作することを確実にする」が究極のセキュリティ要求、とする理由は”鶏と卵”の関係のルートに当たるモノだからです。少し長い説明になってしまいますが、どうぞお付き合いください。

「正しく動作することを確実にする」をリスク分析(リスク把握、不確実性把握 – リスク、不確実性の分類)すると

  • 外部から妥当でないデータが入力される
  • プログラムに不正なコードがある
  • 外部へ(複雑な処理を含む)妥当でないデータを出力してしまう

といったリスク(不確実性)を把握できるはずです。

※ できる限りざっくりと大きな範囲のリスクに分類することが重要です。そうしないと漏れが発生しやすくなります。

「外部から妥当でないデータが入力される」をリスク分析すると

  • 仕様として妥当でないデータが送信される
  • 意図的に妥当でないデータが送信される

の2種類に分けられます。

今までの簡単なリスク分析をまとめると

正しく動作することを確実にする → リスク分析 → 外部から妥当でないデータが入力される → リスク分析 → 仕様として妥当でないデータが送信される

といった流れになります。これは

卵(要求) → 鶏(分析) → 卵(要求) → 鶏(分析)

のような構造です。

あるリスクを分析 → より具体的なリスクに分割 → さらにリスクを分析 → さらに具体的なリスクに分割

セキュリティ要求の分析/把握はドリルダウン形式で分類/細分化できます。その最上位のセキュリティ要求となるのが

  • 「正しく動作することを確実にする」

です。

セキュリティポリシーとセキュリティ要求

究極のセキュリティ要求である

  • 「正しく動作することを確実にする」

だけを求めてリスク分析を行い、それぞれのリスクに対応する、といったことは不可能です。リソースは有限で、避ける事がほぼ不可能なリスクも少なくないからです。

セキュリティ要求事項としては、全てのリスクを網羅する必要があります。しかし、実際には全てのリスクに対して対応することができません。実際にリスクに対応するのか取捨選択(リスク許容)しなければなりません。

そこでセキュリティポリシーが必要になります。セキュリティポリシーはリスクに対してどのような考え方で対応するのかまとめた物です。セキュリティポリシーによって、リスク許容を含め、リスクへの対応を決めます。

リスク分析を行う場合には常に「正しく動作することを確実にする」を意識する必要があります。しかし、これだけは決して完全に達成できないセキュリティ要求となる点に注意が必要です。情報システムは利用可能なリソースの限界などの現実的な制約やセキュリティポリシーによりほぼ必ず何かのリスクを許容することになります。

ISO 27000では対応しないリスク(許容したリスク)も”管理対象”です。対応しないリスクであっても、しっかり識別し管理する(定期レビューなど)必要があります。許容するリスクだからと単純に無視するとセキュリティ問題の原因になります。

実例: SQLのプレイスホルダのみでSQLクエリの無害化を行う。識別子が変数となるケースは少ないので”リスクを無視”する。⇒ ソートカラム、抽出カラムがユーザー入力の場合など、SQLインジェクションで攻撃されるにも関わらずリスクを無視する。

この実例の様に許容したリスク(残存リスク)を識別し、必要な場合は対応するよう管理しないと致命的な結果(上記の場合はSQLインジェクション)になります。許容したリスク(残存リスク)の識別と対応/管理は見逃されがちなので要注意です。

究極のセキュリティ要求と情報セキュリティ対策の目的

全ての不確実性を考慮した上でセキュリティ要求を決める必要あります。セキュリティ要求の策定には「正しく動作することを確実にする」ことを目的とした分析が欠かせません。しかし、これ自体は情報セキュリティ対策の目的ではないです。ここを勘違いしないようにしないとならないです。

ISO 27000 の定義では「正しく動作することを確実にする」は情報セキュリティ対策の目的として設定されていません。「正しく動作することを確実にする」はほぼ実現不可能だからです。実現不可能な目的を設定すると無理と無駄が発生します。

ISO 27000では、リスクは全て排除するモノではなく、緩和、許容、移譲、管理するモノです。ISO 27000の情報セキュリティ対策の目的を一言にまとめると

  • 許容可能な範囲内にリスクを抑えて情報システムを利用できるようにする

となります。

これを達成するためには「許容したリスクが受け入れ可能範囲内であるか?」確認&管理が必要になります。

設計/実装レベルでもよく、許容したリスク、が見落されています。設計/実装時にもどんなリスクを許容しているのか?把握しながら作らないと、致命的な問題を作りやすくなります。

セキュリティ問題が法制度で制裁される時代

セキュリティ要求の話でなぜ法制度?と思ったかも知れません。情報システムの「正しい動作」は法律でも定められます。関連する法制度も理解しないと漏れのないセキュリティ要求を作れません。

2018年5月にGDPRが施行されました。高額な制裁金が課されるのでほとんどの方が聞いたことがあると思います。

海外の法制度ですが、日本にも影響します。特にEU個人データの持ち込みが事前手続きなしで行えるようになる予定である点は重要です。こうなると、自社ではEU個人データを扱っていないつもりでも、事前確認/通告なしでEU個人データを含むデータを受け取ってしまうケースが発生します。知らずにEU個人情報を受け取り、個人情報漏洩のインシデントが発生し、制裁対象となるリスクが増加します。(誰の責任になるのか?は実際に事例が発生しないと分かりません)

GDPRの基になっているのはOECDのプライバシー勧告です。そもそもプライバシー勧告はITシステムでプライバシー情報を取り扱う上での問題に対応する為に作られています。当然、情報セキュリティにも注意するように記述されています。

OECDは情報セキュリティ勧告も出しています。基本としてこの情報セキュリティ勧告に従うとGDPRで要求される情報セキュリティ管理ができることになります。このセキュリティ勧告を基にしてISO 27000が作られています。つまりISO 27000に準拠するようなセキュリティ管理であれば、少なくとも管理体制としてGDPRにも対応できる管理体制になっていると言えます。

ソフトウェア開発者にとって特に注意が必要な事は、ISO 27000ではセキュアプログラミング技術の採用が求められている点です。セキュアプログラミング/セキュアコーディングの概念が広く正しく理解され、導入されているのであれば良いのですが、現実はあまり普及している、とは言えません。

GDPRのような法律にキチンと対応するには、どこから手をつければ良いのか分らない、といった場合はOECDの勧告、法制度、関連するISO標準、ISO標準が要求する技術、の順番に理解していくと体系的な理解が可能になります。

セキュリティ要求を作ってみよう

一般的なアプリケーションのセキュリティ要求を作るのは難しいことではありません。難しいことではないので、詳細なセキュリティ要求定義なしでシステム構築をしている場合も多いです。この場合、直感や今迄の事例に則ったセキュリティ要求になっていると思います。

体系的な情報セキュリティ管理の概念から外れていなければ、直感や今迄の事例に頼っても大きく外しません。しかし、セキュリティ標準で推奨するセキュリティ要求は今まで作られてきたソフトウェアのセキュリティ要求とは大きく異なります。今あるアプリケーションのセキュリティ要求定義とセキュリティ標準で求められるセキュリティ要求定義は根本的に異なる、と言い切っても構わないくらい状態です。

ISO 27000とCERT Top 10 Secure Coding Practicesを理解した上で、自分のアプリケーションのセキュリティ要求を作ってみると、足りていないモノが見えてくると思います。

ISO 27000はJIS検索(キーワード:セキュリティ)を利用するとJIS Q 27000としてオンライン参照可能です。

今は(昔からですが)ISO 27000を無視したシステム開発ではシステム開発のリスクが高過ぎる状態です。ITシステムの開発者全てが少なくとも基礎・基本をおさえて置く必要があります。

セキュリティ要求を作るにはリスク分析が必要です。

関連:

投稿者: yohgaki