はじめに
昨今複数の大規模システムでセキュリティインシデントが発生し、社会全体でセキュリティへの感度が高くなっているのを感じています。
普段はアプリケーション部分の機能開発を担当している私もセキュリティへの感度をより高めていくために、セキュア・バイ・デザインという書籍を読んで勉強しました。
この記事では、この本の中でも特に重要な考え方・トピックをざっくり紹介しつつ、その中での自分の疑問・感想を述べたいと思います。
セキュリティを機能(feature)として捉える問題
自分も含めてなのですが
セキュリティに対して普段から考えていないと、どうしてもセキュリティは「インストールするもの」「機能として実装するもの」であるという認識をしてしまいがちです。
確かにそういう類のセキュリティ対策も必要な場面はあり、筆者もそれを否定しているわけではありません。
しかしながら、セキュリティを機能として捉えることで以下のような懸念が発生します。
セキュリティに関する実装と、じっさいの機能を並列で考えてしまう
一見問題が無いようにも思えますが、じっさいの機能とセキュリティに関する実装を並列で並べた場合、大抵の場合セキュリティの優先度のほうが低く設定されることになりがちです。
開発者がセキュリティの専門家と同等の知識を持つことを求められる
専門家かどうかを問わずセキュリティへの感度が上がっていることは確かですが、すべての開発者がセキュリティの専門家と同じだけの知識を持つのは現実的ではありません。
将来起こり得るすべての脅威を把握することが求められる
仮にセキュリティの専門家チームと一緒にセキュアな機能開発ができたとしても、それはその時点で専門家が知っている範囲での対策にとどまってしまいます。
機能は大抵成長して変化していくため、変化した先の脅威をある時点でのセキュリティ対策で完全に予測、対応するのは不可能です。
設計(design)による安全性の向上
前述したような「セキュリティを機能として捉える」ことの問題点へのアプローチとして、この本では設計(design)設計によって安全性を高めることを主張しています。
このコンセプトは本書の骨子となる内容であり、端的にまとめると以下のような形となります。
- セキュリティを意識するとしないとにかかわらず、設計は常に行うものであるため、機能開発とセキュリティの関心ごとの垣根をなくすことになる
- それによって、ビジネスにおける関心事とセキュリティにおける関心事が同等の優先度をもって扱われることになる
- ドメインを正確に表現する設計を行うことで、通常のバグとともに、セキュリティ上の問題につながる不正な状態や誤用も減らしていく
ここまでが大体1章の内容で特に3点目が、本書で述べたい要旨だと考えています。
では、本書における安全なデザインとは?
本書はソースコードの設計から、デプロイパイプライン・インフラストラクチャの設計まで広範なトピックを扱ってはいるのですが
メインとなるのはやはりアプリケーションコードの設計であるため、その観点に絞って本書が主張する安全なデザインのアイデアをかいつまんで紹介したいと思います。
- 【4章】契約を使って速やかに失敗させる(fail-fast)、オブジェクトを不変にする(immutable)
- 【5章】データを表現する最小単位をプリミティブに頼るのではなく、ドメイン・プリミティブ(ビジネスロジックにとって意味のある値)を最小の要素とする
- 【6章】可変の状態をもつオブジェクト(Entity)の場合、オブジェクトの生成・状態の変更時に完全性(integrity)を保つようにする
- 【7章】状態遷移をオブジェクトとして切り出して、状態遷移の完全性を担保しやすくする
このあたりのプラクティス、見覚えがある方も多いと思うのですが
この本における安全なデザインは、基本的にDDDに立脚しています。
(じっさい3章ではガッツリDDDの種々の概念について総ざらいしています)
~~~~~ここから感想~~~~~
本書をある程度読み進める中で最初に疑問に思ったのは
アプリケーションの中核部分で入力値を検証したところで、その前段階で悪意のある入力への対策が必要なのであれば、ドメインモデルで検証することにどれほどセキュリティ上の意味があるのだろうか?
という感想でした。
また、そういった悪意のある入力の混入を防ぐ役割は現代ではフレームワークが一定程度吸収してくれていると考えており、その先でいくら安全性を担保してもそんなに効果はないのではないか、とも思いました。
個人的にはドメインモデルを中心とした設計を否定するわけではなく、むしろソフトウェア設計において重要なものであると考えているのですが
それを徹底することで自然とセキュリティを担保することになる、という筆者の主張には正直まだピンとは来ていませんでした。
本書における「セキュアな状態」に対する認識とのズレ
読み進めるうちに、本書が「セキュリティ」という言葉を特別に広い意味で使っているというよりも、自分自身がこれまでセキュリティを狭く捉えていたのではないかと思うようになりました。
自分はこれまで、SQLインジェクションやXSSなど、具体的な攻撃手法に対して防御できていることを「セキュアな状態」として強くイメージしていました。
一方で、情報セキュリティには機密性・完全性・可用性といった観点があり、IPAでは完全性(Integrity)について「情報や情報の処理方法が正確で完全である」と説明されています1。
そう考えると、本書で繰り返し登場する「不正な状態を作れないように設計する」という考え方も、セキュリティとは別の話なのではなく、システムの完全性を設計によって守るためのアプローチとして捉えることができます。
つまり、本書を読む中で変わったのは「セキュリティ」という言葉の定義そのものというよりも、自分がその言葉から想像していた範囲だったのだと思います。
防御を多層で行うことの意味
もう一つ、自分が読み飛ばしてしまってたのにあとから気づいたのですが、第1章の中の「多層セキュリティ」というセクションではセキュリティを一つの壁に頼り切るのではなく、多層で設けることの意義について書かれていました。
最初の方にも述べた通り、点によるセキュリティの対策というのはその時点で知りうる中での対策にとどまってしまい
いつかは突破されるようになる可能性もあります。
そうなったときにその一点のみで対策していたのでは、その後の被害はさらに大きくなってしまうかも知れません。
だからこそ防御的な仕組みは多層で行うことに意義があるのだ、という点もこの書籍の論旨を補強していると感じました。
さいごに
この本を読んだことで、自分がセキュリティ対策というものをいかに点で捉えてしまっていたかということを思い知りました。
今後は専門家と協力してセキュリティに対する要所要所での防御には気を配りつつ
設計を行う中でも不正な状態を発生させないよう意識することで堅牢なシステムを作っていけるようにしたいと思いました。