「もらったものはありがたく受け取れ」という古い格言を聞いたことがありますか? この格言は放課後のおやつや誕生日のプレゼントには当てはまるかもしれませんが、ソフトウェアセキュリティには当てはまりません。ソフトウェアの著作権者は新しいソフトウェア機能をただ受け入れるだけではなく、デプロイする前に評価し、根拠を示し、解析するという戦略的プロセスを経る必要があります。お客様のチームも同様にセキュリティは細心の注意を払って取り扱う必要があります。セキュアなソフトウェアはどこからともなく生じるものではなく、戦略的開発プロセスの要件として定義する必要があります。セキュアなソフトウェアを効果的にデプロイするには、明確で一貫性があり、テスト・測定可能なソフトウェアセキュリティの要件定義が求められます。
従来の要件では機能または状態を定義します。ハンマーは釘を打ち込む必要があります。ドアの錠には鍵で開けるまでドアを閉めておく機能が必要です。車はA地点からB地点まで道路を通って人を運ぶ必要があります。また、最新のガソリン燃料に対応している必要があります。この種の要件定義は物理的なオブジェクトには適していますが、ソフトウェアには不十分です。
さらに、これらのオブジェクトは、意図した目的以外の使い方をされる可能性もあれば、ユーザーが本来の目的を完全に回避する可能性もあります。たとえば、ハンマーが窓を割るために使われたり、ドアの錠がピッキングで開けられたり、車が盗難品の運搬に使われる可能性もあります。同様に、ソフトウェアも悪用されたり、脆弱化されたりする可能性があります。ただし、重要な違いは、車が逃走車に使われても自動車メーカーは責任を負わないのに対し、ソフトウェアの機能やアクセス権がハッキングされた場合にはソフトウェア著作権者であるあなた自身が災難に遭うという点です。
ソフトウェアの脆弱性は、開発者が意図しない方法でソフトウェアが悪用される可能性をもたらします。釘を打つことしかできないハンマーが設計可能だと考えてみてください。堅牢なソフトウェア・セキュリティ要件定義を作成することにより、意図した用途以外では使用できないようにソフトウェアの用途を制限(ロックダウン)することができます。
幸いにも、OWASP Top 10の影響を受けないソフトウェアを構築することは、釘以外のものを打つとマシュマロに変わるハンマーを作るより簡単(恐らく作れませんが)です。
セキュリティ要件とは、アプリケーション開発の開始時に設定する目標です。すべてのアプリケーションはニーズ、すなわち要件に対応します。たとえば、お客様がカスタマー・サービスに問い合わせずに操作を行うことを許可する必要があるアプリケーションがあります。最終製品となるアプリケーションの目標としてその操作や結果を設計するのと同様に、セキュリティの目標も設計に含める必要があります。
減量するという新年の抱負が、ひと振りすれば簡単に願いが叶う魔法の杖ではないのと同様、「ハッカーに侵害されるな」とアプリケーションに命じるセキュリティ要件を定義しても願いを叶える魔法の杖にはなりません。減量したいという抱負と同様、漠然とした目標は失敗の元です。何キロ減量するのか? 減量の方法は? 運動か、食事療法か、その両方か? どのようなマイルストーンを提示するか?
セキュリティの場合も同様の質問事項があります。対策をとる脆弱性の種類は? 要件が満たされていることを評価する方法は? 脆弱性がコードに組み込まれないようにするためにとる予防措置は?
ソフトウェアセキュリティ要件定義を作成する場合は、対策をとる脆弱性の種類を具体的に明記してください。たとえば、「ユーザーがコマンドを埋め込んだデータを提供することにより、アプリケーションに本来の意図とは異なる操作をデータベース・テーブルに対して行わせようとした場合、[アプリケーションX]はそのコマンドを実行しない」という要件があるとします。これはSQLインジェクション攻撃に対する脆弱性を防ぐようアプリケーションに指示する優れた方法です。これらの攻撃はユーザーからの不正な入力の拒否またはスクラブの組み合わせで予防することが可能であり、それにはデータに対し、操作を実行するコマンドではなく、データとしてのフラグを設定する熟慮されたデータベースクエリーを用い、データベース呼び出しの出力を変更して、不正なデータが機能を攻撃することを徹底的に防ぎます。その後、ソースコードとコンパイル済みアプリケーションの両方において特定種類のソフトウェアテストによってこの要件をテストすることができます。
優れた要件定義を作成するには、要件に関する質問事項に答えていることを確認する必要があります。ソフトウェアセキュリティ要件の定義は、機能要件の場合と同様、あいまいであったり、実現不可能であったりしてはなりません。開発チームからの質問を予想し、先取りして答えを出します。その方法を以下に示します。
要件を定義するときは、それは誰かが必ず実現しなければならない目標であるということを念頭に置いてください。具体的で実現可能な要件を定義しなければ、設計者や開発者はアプリケーションのセキュリティ目標を達成できません。
要件定義あるいは請け負いの業務に携わっている方は、基本的な要件の種類(機能、非機能、派生)を既にご存知でしょう。ソフトウェアセキュリティ要件にも同じ分類が当てはまります。パフォーマンス要件が仕様に従ったパフォーマンスを実現するためのシステムの動作と状態を定義するものであるのと同様に、セキュリティ要件はセキュアなパフォーマンスを実現するためのシステムの振る舞いと状態を定義します。
非セキュリティ機能要件を定義する場合、たとえば「スキャンボタンを押すとレーザーが作動し、バーコードを読み取る」といった記述になります。これはバーコード・スキャナーがやらなければならないことです。同様に、セキュリティ要件は、セキュリティを実施するために必要なシステムの動作を定義します。例:「キャッシュレジスターで売上を処理する前には、レジ係が磁気ストライプカードと暗証番号でログインする必要がある。」
機能要件はシステムの動作を定義します。機能セキュリティ要件は、セキュリティを実施する機能の動作を定義します。機能要件は、直接テストして観察することができます。アクセス制御、データインテグリティ、認証、不正なパスワードのロックアウトなどに関する要件が機能要件に該当します。
非機能要件はシステムの状態を定義します。可監査性とアップタイムに対応する記述がこれに該当します。非機能セキュリティ要件は、たとえば「監査ログはフォレンジックに対応するために十分に詳細であること」といった記述になります。可監査性は直接的な機能要件ではなく、適用される可能性がある法令から生じる可監査性要件に対応するものです。
派生要件は機能要件と非機能要件から派生したものです。システムにユーザーIDと暗証番号の機能要件がある場合、派生要件にはアカウントをロックアウトするまでの間違った暗証番号の推測回数の上限を定義することができます。監査ログの派生要件では、ログインジェクション対策などログの整合性に対応することが考えられます。
派生要件は悪用ケースから派生しているため厄介です。要件設計を行う場合はユーザーや顧客の立場で考えるだけではなく、攻撃者の目線でも考える必要があります。ユーザーに提供する機能は、どの部分も攻撃者によって悪用される可能性があるからです。たとえば、ログイン機能はパスワードの推測に使用される可能性があり、ファイルのアップロード機能によりシステムがマルウェアのホスティングにさらされる可能性があります。また、テキスト受信の機能はクロスサイト・スクリプティング(XSS)やSQLインジェクションの攻撃に利用されるかもしれません。
ソフトウェアセキュリティ要件は、要件定義内のさまざまなソースや設計の早期フェーズから生じる場合があります。機能を定義する場合、その機能のセキュリティを定義するか、ビジネスロジックのセキュリティを確保するための補足要件を定める必要があります。業界のベストプラクティスと規制要件からの一般的なガイダンスを、個別のアプリケーション要件に合わせてカスタマイズする必要があります。
悪用ケースは攻撃者の目線で考えるための1つの手段です。設計者は、ユースケースの発想を逆転させて、機能がどう悪用されるかを解析します。ユーザーが重要データを使用してレポートを作成できるようになっている場合、不正なユーザーはそのレポートと重要データにどうアクセスするか? 悪用ケースに対する答えの多くは業界のベストプラクティスの中にあり、こうしたベストプラクティスはアプリケーションによる特権データへのアクセス方法に関する要件の定義に利用できます。
ソフトウェアセキュリティ要件は、アーキテクチャ・リスク分析による設計の分析から得られる場合もあります。Webアプリケーションが特定のフレームワークまたは言語を使用している場合、攻撃パターンと脆弱性に関する業界の知識を適用する必要があります。フレームワークがクロスサイト・スクリプティング(XSS)対策が状況によって機能しないような場合、非セキュアな状況で開発者がクロスサイト・スクリプティング対策をどう処理するかを規定する要件を定義する必要があります。
各セキュリティ要件は個別のセキュリティニーズに対応する必要があり、アプリケーションに存在する可能性がある脆弱性に関する知識が不可欠です。一般的なガイダンスや知識では不十分です。個別のセキュリティ要件は個別のアプリケーション要件から発生します。
ソフトウェアを内製するか、サードパーティー・ベンダーにアウトソーシングするかにかかわらず、堅実なセキュリティ要件定義を作成することにはメリットがあります。早期の段階でセキュリティを定義することにより、後になってたちの悪い不意打ちに遭わずに済みます。堅実なセキュリティ要件は、開発者に明確なロードマップを示すことで、内部的な利点をもたらします。また外的な規制条件の充足にも役立ちます。ソフトウェアがハッキングされないように対策を実装することは優れた戦略であり、セキュリティ要件定義は良いものを得るための素晴らしい第一歩です。
ソフトウェアセキュリティ要件を早い段階で定義しておけば、後はセキュアな環境で構築されたソフトウェアが守ってくれます。