Application Security: 実務者向けガイド

アプリケーション セキュリティとは、安全なアプリケーションを設計、開発、テスト、保守することです。セキュアなコーディングからランタイムの保護まで、ライフサイクル全体をカバーし、Web、モバイル、デスクトップ、クラウドネイティブのアプリに適用されます。

 

アプリケーション セキュリティの解説

アプリケーション セキュリティは、設計からデプロイメントに至るまでソフトウェアを防御する規律であり、理論的な脅威だけでなく、プレッシャーの下でシステムがどのように故障するかという現実からも防御するものです。ツールよりも可観測性を問うものであり、アプリケーションが何をしているのか、どのように公開されているのか、どこで仮定が崩れるのかを把握する試みです。

すべてのアプリケーションがアタックサーフェス

ソフトウェアが入力を受け入れ、データを保存し、他の何かに接続した瞬間、それはアタックサーフェスとなります。セキュリティの確保とは、通常の使用時、ストレス下、そして積極的な搾取下での振る舞いに責任を持つことです。その振る舞いにはコード以外のものも含まれ、カバーすべき範囲は、選択されたフレームワーク、インポートされたパッケージ、プロビジョニングされたインフラ、デフォルトで信頼されるサービスにまで及びます。

セキュリティは細部に宿る

セキュリティは、データがどのように検証され、IDがどのように管理され、シークレットがどのように扱われ、障害がどのように抑えられるかにかかっています。それは、自分の入力が安全であると仮定することと、それが武器化されないことを証明することの違いであり、自分の設定がロックダウンされていると信じるか、誰もデバッグポートを開けっ放しにしていないことを把握しているかの違いです。そして、実行されるコードと、敵に利用されるコードの違いでもあります。

クラウド ネイティブがすべてを変える

クラウド ネイティブ アーキテクチャでは、アプリケーション セキュリティは設計によって分散されます。サービスの拡張、移行、外部システムとの相互接続。信頼の境界は、API、コンテナオーケストレーションの層を超えて曖昧になっています。従来の境界ベースの防御は依然として重要とされているものの、今や制御はアプリケーション内部、そしてデリバリー パイプライン内部に存在しています。

安全なソフトウェア=予測可能なソフトウェア

セキュリティという言葉は、完璧を指すものではありません。意図的という意味をもちます。それは、何か問題が発生した場合でも、期待通りに動作するソフトウェアを構築することです。設計による予防、計測器による可視化、原則に基づくアーキテクチャによる回復力が、ここでは新たなベースラインとなります。

最初から開発者に関係

クラウド ネイティブ環境では、セキュリティは他人事ではありません。リリース フォームのチェックボックスではないのです。それは、アーキテクチャ、ワークフロー、日々の意思決定を形作る思考法です。これをうまく実践できるチームは、ただ安全なだけではありません。迅速に行動し、迅速に復旧し、大規模に信頼を獲得することができるからです。

 

組織が保護すべきアプリケーションの種類

アプリケーションはもはや単一のカテゴリーには収まらない存在です。最新の組織では、サーバーでレンダリングされたWebサイト、モバイルAPI、コンテナ化されたマイクロサービス、そしてクライアントの多いJavaScriptアプリが、CI/CDパイプラインによってつなぎ合わされており、これらがハイブリッド環境やマルチクラウド環境にデプロイされるからです。したがって安全保障上の決定は、その現実を反映したものである必要があります。攻撃者はタクソノミーを気にしません。彼らは弱点を探します。つまり、セキュリティ実務者の仕事とは、まずどこを見るべきかを知ることなのです。

Webアプリケーション セキュリティ

Webアプリケーションは依然としてほとんどのビジネス オペレーションの中心に位置し、敵対者にとって最大の標的であり続けています。何十年にもわたるガイダンスにもかかわらず、入力の検証、認証、セッションの処理、出力のエンコーディングなど、基本的なことは依然として重要です。しかし、より新しい複雑な問題にも注意を払う必要があります。

  • サードパーティのスクリプトやクライアントを多用するフレームワークは、オリジン サーバー以外にもアタックサーフェスを拡大する存在です。
  • 従来のビジネス ロジック、特にマルチテナント アプリケーションでは、より新しい保護をバイパスすることが起こり得ます。
  • CSPの設定ミス、緩いCORS設定、不適切なセッション トークンの保存は、技術的に健全なビルドであってもセキュリティ ギャップを生む可能性があります。

最近のWebアプリケーションは、ブラウザの機能、エッジ キャッシング、クライアント側の状態にも大きく依存しています。ブラウザで実行されるものを脅威のモデルとして見なしていない場合、絵の半分を見逃すことになります。開発者は、サーバーとクライアントの両コンポーネントを責任共有ゾーンとして扱うことが求められており、一方が安全保障を所有しているという前提はもう機能しないのです。

APIセキュリティ

APIは、システム、サービス、ユーザー間の主要なインターフェースとして、モノリスに取って代わりました。このシフトは、新たなパワーと新たな脆さの両方をもたらすものです。APIが技術的な失敗で壊れることはほとんどありませんが、濫用されることでその効力を失う可能性があるからです。

  • 不適切な承認ロジック(特にオブジェクト レベル)は、依然として広く存在する欠陥です。
  • あまりに冗長な応答は、構造、キー、内部メタデータを漏らす可能性があります。
  • 不適切な入力処理は、デシリアライズ攻撃、インジェクション、ネストされたクエリ ロジックの悪用を可能にします。

バージョン管理、認証、レート制限は始まりに過ぎません。チームはまた、スクレイピング、クレデンシャル スタッフィング、列挙攻撃のためのパブリック エンドポイントの悪用など、ビジネスの悪用についても考慮しなければなりません。すべてのAPIはミニチュアの信頼境界です。何が起こるべきかを定義しなければ、誰かが起こるべきでないことを見つけることになります。APIのセキュリティは最重要なのです。

クラウド ネイティブ アプリケーションのセキュリティ

クラウド ネイティブ スタックにおけるセキュリティは、構成の観点から考える必要があります。アプリケーションを保護するといった視点を離れて、疎く結合されたサービスや宣言型インフラ、エフェメラルなコンピュート、分散アイデンティティからなるダイナミックなシステムを保護するのです。

  • コンテナ イメージは、そのベースレイヤーや依存関係とともに、アタックサーフェスの一部となります。
  • Kubernetesの設定ミスは、オープンダッシュボード、寛容すぎるRBAC、ネットワークポリシーの欠如など、すぐにエスカレートします。
  • サイドカー、サービス メッシュ、シークレット マネージャーは、新たな信頼の仮定とツールの複雑さをもたらすものです。

アイデンティティが制御プレーンになります。すべてのワークロード、ポッド、サービスアカウントには、明確にスコープされたロールが必要とされており、開発者は、「何が動いているのか」から「誰が誰と、なぜ対話しているのか」にシフトする必要があります。クラウド ネイティブ セキュリティは警戒に報いるものではなく、明確さに報いるものです。曖昧なままにしておくと悪用されます。

オペレーティング システム(OS)セキュリティ

OSレベルの問題はプラットフォーム チームに任されることが多いものの、アプリケーションを書く開発者、特にローカル リソース、システム コール、ファイル ストレージを管理する開発者は、OSのハードニングの基本を理解している必要があります。

  • ファイル パーミッション、環境変数のスコープ、およびプロセス特権はすべて、攻撃者が制御する入力によって悪用される可能性があります。
  • ワークロードの分離に失敗すると、コンテナの脱走や特権の昇格を許すことにつながります。
  • ロギングや遠隔測定機能は、機密データを誤ったユーザーやシステムに漏らす可能性があります。

サーバーレスやコンテナ ファーストのアーキテクチャでは、オペレーティング システムは抽象化されることもありますが、存在しないわけではありません。組織のコードがシェルとやりとりしたり、バイナリを呼び出したり、ローカル システム リソースに依存したりする場合は、リモート接続と同じ精査が必要となります。

最新のアプリケーションには、階層化された適応性のある防御が求められます。何を保護するのか、そして攻撃者がそれぞれのサーフェスについてどのように考えているのかを理解することは、単に機能するだけでなく、プレッシャーの下でも耐えうるシステムを構築するための第一歩なのです。

 

責任範囲 – 担当者は、開発者かセキュリティか?

アプリケーション セキュリティは、以前はセキュリティ チームの肩にかかっていました。セキュリティ チームはプロジェクトの終わりにやってきて、コードを監査し、依存関係をスキャンし、修正のパンチリストを提出します。このモデルの失敗は、セキュリティ チームに専門知識がなかったからではなく、コンテキストが欠けていたことに原因があります。セキュリティ チームは、システムが実際にどのように機能しているのか、ビジネスロジックが予期せぬ方向に曲がっているのか、ひとつの変更がどのようにスタック全体に波及しているのか、といった細部を見ることができなかったのです。そして、チームが意見を述べたときには、決定的なものを壊さずに軌道修正するには遅すぎるといった状況でした。

手遅れのセキュリティは戦場と化します。脅威は進化し、ソフトウェアはかつてない速さで変化。開発者は1日に何度も配信を行い、アーキテクチャはモノリスから分散サービス、そしてエフェメラルなワークロードへと移行する。そのような世界では、セキュリティがゲートキーパーとしてしか機能しないのであれば、規模を拡大することはできません。とはいえ、すべてを開発者に丸投げするわけにもいきません。

開発者によるサーフェスのコントロール

開発者がコードを書くということは、彼らがアタックサーフェスを形成するということです。あらゆるライブラリ、あらゆるパラメータ、あらゆるインターフェースなど、あらゆる設計上の決定が、攻撃者が取る可能性のある道を狭めるか、広げるかのどちらかです。開発者は脆弱性を防ぐための最善の立場にいますが、何を防ごうとしているのか、なぜそれが重要なのかを理解してこそこうした予防は機能します。セキュリティは、ワークフローを邪魔するのではなく、ワークフローの内側という、彼らがいる場所で満たされなければならないのです。

監査役からイネイブラーへと進化するセキュリティ チーム

セキュリティ プロフェッショナルも無関係ではありません。その役割は監査役からイネイブラーへと進化しています。彼らの仕事はデプロイメントを阻止することではなく、チームがより良い決断を下せるようにすることにあります。ツールを構築し、ポリシーを設計し、開発スピードを落とすことなく安全性を担保できるガイダンスを提供するといった仕事が求められています。あるサービスの欠陥が他のサービスにどのような影響を与えうるか、漏洩したクレデンシャルが環境全体の信頼にどのように悪影響するか、誤った設定のIDポリシーが横方向の動きへとどのように悪用されるか、といったシステミック リスクに関するより広範な理解を扱います。開発者は目の前にあるものを見ることが多く、セキュリティはボード全体を見渡すのが仕事です。

明確な境界線が責任の共有を生む

オーナーシップとは、すべてをやるということではありません。それは、何が自分のもので、何がそうでないかを知るということです。セキュアな設計と実装は開発者自身が行います。そしてセキュリティは戦略、可視性、ガバナンスを担います。両者の境界線は固定されてはいないが、曖昧でもありません。責任分担が機能するのは、責任が明確に定義され、相互に尊重される場合のみだからです。

正しい質問は「How」から始まる

機能性の高いチームでは、「誰がセキュリティに責任を持つのか?」という議論は交わされません。問うべきは「すべてのレイヤーで安全な決断を下すにはどうすればいいか」です。この質問には、機能ごと、サービスごと、リリースごとに異なる答えが返ってきます。それこそがあるべき姿なのです。

アプリケーション セキュリティへの視点: 開発者 vs.アナリスト

機能 開発者から見たアプリケーション セキュリティ セキュリティ アナリストから見たアプリケーション セキュリティ
主な焦点 セキュリティを要件と制約条件として考慮しながら、機能的なアプリケーションを構築する。 アプリケーション内のセキュリティ脆弱性の特定、評価、緩和。
パースペクティブ 開発プロセスに組み込み、セキュアなコードの記述と開発中のセキュリティ対策の統合に重点を置く。 アプリケーション セキュリティのテスト、監査、改善提案に重点を置く。
主な活動 セキュリティを考慮したコードの記述、セキュリティ上の欠陥に対するコードレビューの実施、SASTツールの使用、テスト中に発見された脆弱性の修正、セキュリティ要件の理解。 セキュリティ評価(脆弱性スキャン、侵入テスト)の実施、セキュリティ レポートの分析、セキュリティ ポリシーの策定、セキュリティ インシデントへの対応。
目標 セキュリティ要件を満たし、脆弱性を最小限に抑えた機能的なアプリケーションを提供する。 アプリケーションの攻撃耐性、データ保護、セキュリティ標準および規制への準拠を確保する。
ツール セキュリティ プラグインを備えたIDE、開発パイプラインに統合されたSASTツール、コード レビュー・プラットフォーム、バージョン管理システム。 DASTツール、脆弱性スキャナ、侵入テスト フレームワーク、SIEMシステム、レポーティング ツール。
時間枠 主に設計からデプロイメントまでの開発ライフサイクル。 設計、開発、デプロイメント、継続的なメンテナンスなど、アプリケーションのライフサイクル全体。
ナレッジ ベース プログラミング言語、ソフトウェア アーキテクチャ、開発方法論、一般的なセキュリティ脆弱性(OWASP Top 10)、セキュア コーディング プラクティス、セキュリティ ツールの基本的な理解。 セキュリティ脆弱性、攻撃ベクトル、セキュリティ テスト方法論、セキュリティ フレームワーク(OWASP、NISTなど)、コンプライアンス基準、インシデント対応に関する深い理解。
連携 他の開発者、QAエンジニア、時にはセキュリティ アナリストとの密接な協力、およびセキュリティ機能の実装とテストの実施。 開発者と協力して脆弱性を修正し、セキュリティ ガイダンスを提供し、インシデント対応チームと協力する。
成功の指標 コードに発見されたセキュリティ脆弱性の数、セキュア コーディング ガイドラインの遵守、セキュリティ機能の統合の成功。 特定され、是正された脆弱性の数、セキュリティ評価の結果、セキュリティポリシーの遵守状況、インシデントの発生頻度および影響度。

表1: 開発者とセキュリティ アナリストで異なるセキュリティ観

従って、これらは本質的に以下の通りまとめられます。

  • 開発者は、アプリケーションを一から安全に構築することに集中し、セキュリティを、コードに実装する必要のある一連のベストプラクティスや要件と見なします。
  • セキュリティ アナリストは、アプリケーションの防御をテストし、弱点を特定し、その修正方法について専門的なガイダンスを提供することで、アプリケーションの安全性を確保することに重点を置いています。

それぞれの視点や焦点は異なりますが、安全なアプリケーションを構築し維持するためには、どちらの役割も必要です。アプリケーション セキュリティは、ソフトウェア開発ライフサイクル全体を通じて、開発者とセキュリティ アナリストの間のコラボレーションとコミュニケーションを必要とします。

 

セキュリティに関心のある開発者のための実践的ガイド

セキュリティが成功するのは、デプロイ後に上塗りするのではなく、設計に組み込まれたときです。2024年版OWASP Top 10プロアクティブ コントロールズは、精査に耐えるソフトウェアを作りたい開発者に実用的なフレームワークを提供するものです。各コントロールは、実際のインシデントから学んだ手痛い教訓を反映し、それらの教訓を、開発者がビルドプロセス中に行動できるガイダンスに変換します。クラウド ネイティブの複雑さを克服しようとするチームにとって、これらの管理策は、持続可能かつ適切な方法でセキュリティをシフトするための青写真となります。

アクセス コントロールの導入

アクセス コントロールでは、ユーザーやサービスに何ができるかを定義します。ほとんどのデータ侵害は、漏洩した認証情報を伴うものではありません。その反面、広すぎる許可は悪用されており、細かさが重要となっています。

  • ロール、パーミッション、スコープを明示的に定義する。
  • UIロジックやクライアント側の強制に隠れた「ソフトな」アクセス制御は避ける。
  • マイクロサービス アーキテクチャでは、一元化されたIDプロバイダーを通じてポリシーを実施し、サービス レベルできめ細かな制御を適用する。
  • denylistsではなくallowlistを使い、ロジックはサーバーサイドで管理する。
  • パーミッションは、テスト可能で、追跡可能で、監査可能でなければならない。

暗号化の正しい使い方

暗号技術が失敗するのは、アルゴリズムの欠陥によるものよりも、悪用によるものの方が多いとされています。

  • カスタム暗号を試さない。
  • 暗号化をハンドロールしない。
  • よく吟味され、あなたの言語に適した、よく整備されたライブラリを使う。
  • 対称暗号をいつ使うか、非対称キーをいつ使うか、なぜハッシュは暗号化ではないのかを把握する。
  • クラウド ネイティブ システムでは、AWS KMSやHashiCorp Vaultのようなマネージド サービスを使用してシークレットを保護する。
  • トランスポート レイヤー セキュリティはオプションではない。
  • 常に証明書を確認する。
  • 静止時と転送時の暗号化の意味を理解し、鍵のローテーションを危機対応ではなく、通常の運用タスクとして扱う。

すべての入力を検証し、例外を処理

ユーザーフィールドからAPIコールに至るまで、アプリケーションが取り込むものはすべてバリデーションが必要です。データがユーザー、サードパーティのAPI、内部サービスのいずれから来たものであっても、型、フォーマット、長さ、文字の制約など、常に厳密なバリデーションを適用します。入力の検証は単なる見栄えの防御ではありません。下流のコンポーネントがどのように振る舞うかを形作るのものなのです。

  • 型、フォーマット、長さ、文字制約を検証する。
  • デシリアライズ、XMLパーサー、ファイルアップロードには特に注意を払うこと。
  • 例外処理を一元化し、スタックトレースの漏洩を防ぐ。
  • 詳細なエラーを抑制する - 一般的なレスポンスをユーザーに送信するが、内部的には完全なコンテキストを記録する。
  • クラウド ネイティブ システムでは、内部ロジックやインフラを公開することなく、サービスを予測可能に劣化させる。
アプリケーション開発ライフサイクルを保護するセキュリティ対策

図1: アプリケーション開発ライフサイクルを保護するセキュリティ対策

最初からセキュリティに取り組む

セキュリティ債務はすぐに膨れ上がります。セキュリティをその場しのぎのレビュー項目ではなく、設計要件として扱うことが求められます。計画段階の早い段階で、資産、脅威モデル、信頼の境界を特定します。ユーザーデータがアプリケーションをどのように流れ、どこに保存され、誰がアクセスできるかといったデータフローを理解する必要があります。

  • セキュリティに特化したストーリーを、別のチェックリストではなく、バックログとスプリント計画に追加します。
  • 新しいサービスやコンポーネントごとに、早期の脅威モデリングを実施する。
  • 役割を超えた連携 — アーキテクトや開発者とセキュリティ チャンピオンのタッグを作成する。
  • クラウドネイティブのビルドでは、最初のコンテナが出荷される前に、IAMポリシー、公開される情報、サードパーティ サービスのデフォルトの動作などを考慮する必要があります。

セキュア バイ デフォルト設定

デフォルト設定への過度な信頼は危険です。多くのセキュリティ障害は、管理パネルが開いたままになっている、デバッグフラグが有効になっている、CORSポリシーが寛容である、ストレージバケットが大きく開いているなど、サービスの誤った設定に起因しています。

  • コードとコードとしてのインフラでデフォルトを固める。
  • 必要のない機能はオフにする。
  • 強力なパスワードを要求し、MFAを有効にし、安全でないプロトコルを無効にし、スタック全体で最小特権を適用する。
  • Kubernetes環境では、ポッドの権限を制限し、ネットワーク ポリシーを定義し、有効期限の短いシークレットを設定する。
  • 設定を定期的に監査し、CI/CDパイプラインの一部としてベースラインの実施を自動化する。

コンポーネントを安全に保つ

サードパーティのコードは機能の拡張に役立つものの、同時にアタックサーフェスも拡大する存在です。オープンソースの依存関係は、自身のコードと同じように慎重に扱う必要があります。

  • 使用中のすべてのパッケージ、ライブラリ、コンテナのマニフェストを管理する。
  • 脆弱性やライセンスの問題を検出するツールを使用する。
  • 可能な限り、依存関係のグラフを浅くしておくこと。
  • パッチ適用が不可能な場合は、コンテナ化やサービス境界を通じてリスクの高いコンポーネントを分離する。
  • 宣言されたバージョンと本番で実際に実行されるバージョンとの間のドリフトを監視する。
  • スキャンして忘れるだけでなく、修復から解決までを追跡する。

デジタル アイデンティティの導入

アイデンティティは、あらゆる信頼の決定を支えるものです。明確で一貫性のある認証メカニズムを定義する必要があります。

  • 適切な場合には、OIDC、SAML、OAuth2などの連携IDを使用するが、それぞれのプロトコルが提供するものとしないものを把握しておく。
  • bcryptやArgon2のような適応型ハッシュ関数を使ってパスワードを保存する。
  • トークンの管理は重要。
  • JWTに正しく署名し、検証し、有効期限を設定し、機密データをJWTに入れないようにする。
  • 分散環境では、短命トークンを発行し、クレデンシャルを定期的にローテーションする。
  • 人間と機械のアイデンティティを明確な役割にマッピングし、自動化されたツールでアイデンティティ ハイジーンを実施する。

ブラウザのセキュリティ機能を使う

最新のブラウザは強力な防御機能を備えていますが、それは開発者が機能を有効にしている場合に限った話です。

  • コンテンツ セキュリティ ポリシー(CSP)を使用して、実行可能なスクリプト、スタイル、リソースを制限する。
  • サードパーティ資産のSRI(Subresource Integrity)を有効にする。
  • X-Content-Type-Options、X-Frame-Options、Referrer-PolicyなどのHTTPヘッダーを設定する。
  • HttpOnly、Secure、SameSiteフラグが適切に設定された、安全なクッキーを優先する。
  • セキュリティ上重要なことはクライアントに任せにしない。
  • シングル ページ アプリケーションでは、セッション ストレージ、トークンの失効、エラー メッセージの発行を、ユーザー間でステートが漏れないように細心の注意を払って処理する。

セキュリティ ログとモニタリングの導入

見えないものを守ることはできません。有益なイベントをキャプチャし、分析と検出をサポートする集中型システムにルーティングする必要があります。

  • ログインの失敗、権限の昇格、機密リソースへのアクセスなど、セキュリティ関連のイベントをログに記録する。
  • ログのフォーマットは構造化され、検索可能で、トレース識別子と相関していなければならない。
  • クラウド ネイティブ環境では、ログ、メトリクス、トレースを共通のプラットフォームに送信し、セキュリティ インシデントを再構築できるようにする。
  • シークレット、トークン、PIIのロギングを避ける。
  • アラートだけでなく、リクエストのバースト、横方向の動き、不意に現れる新しいサービスなどのパターンも監視する。
  • ロギングはIRのためだけのものではありません。検出エンジニアリングの中核をなすものです。

サーバー側リクエスト フォージェリ(SSRF)の停止

SSRF攻撃は、サーバーを操作して意図しないHTTPリクエストを行わせるもので、多くは内部サービスが標的となります。クラウド ネイティブ環境では、SSRFはファイアウォールを突破してメタデータ エンドポイントに到達し、認証情報や内部設定のエクスポージャに発展する恐れがあります。

  • ユーザーが提供したURLを信用しない。
  • 宛先ホストを明示的に検証し、オープンリダイレクトを避け、内部インフラを含むIP範囲へのリクエストをブロックする。
  • 可能であれば、allowlistとDNS pinningを使用する。
  • ワークロードをセグメント化することで、侵害されたコンポーネントであっても、認証と承認なしでは重要なサービスにアクセスできないようにする。
  • コンテナ化されたシステムでは、ネットワーク ポリシーを設定して、イグレス パスを制限する。

このようなセキュリティ管理は完璧を求めるものではありません。規律を守り、文脈を認識し、継続的に洗練させることが求められます。ひとつひとつを注意深く実装することで、チームはバイ デザインのアプローチで自らを守るソフトウェアを実現することができます。

 

アプリケーション セキュリティ テストの種類

アプリケーション セキュリティは、開発から生産に至るまで、ソフトウェアのアタックサーフェスを減らすように設計された一連の戦略とツールに及びます。その実践において、セキュリティはチェックリストではありません。SDLCに組み込まれた継続的な規律であり、あなたが選択するツールは、あなたの環境のアーキテクチャ、ベロシティ、および脅威のエクスポージャを反映したものであることが求められます。以下の各カテゴリは全体的な防御に貢献するものですが、クラウドネイティブ環境で効果的に実装するにはニュアンスを含んだ理解が必要とされます。

SDLCのための侵入テスト

侵入テストは、実際の攻撃をシミュレートし、敵対的な状況下でアプリケーションがどのように失敗するかを明らかにするものです。そのためには、熟練した人間のオペレーター、つまり攻撃者の思考を持ちながらもシステムの内部構造を理解している人間が必要です。クラウドネイティブ環境では、侵入テストの範囲はコードベースだけでなく、アイデンティティの誤設定をはじめ、過剰なパーミッション、CI/CDパイプラインで露出されたシークレット、マネージド サービスの不適切な使用なども網羅します。

カギを握るのはタイミングです。開発の後期段階やメジャーリリースの直前にペンテストを行うことで、自動化ツールが見逃してしまう潜在的なアーキテクチャ上の欠陥を発見することができます。しかし、それをチェックボックスのように扱ってはいけません。早期に統合し、インフラの進化とともに反復的に改良していくことが、最も価値あることだからです。

動的アプリケーション セキュリティ テスト(DAST)

DASTが機能するのはランタイム時です。実行中のアプリケーションを外側からプローブし、敵対的な入力の下でどのように動作するかを分析します。コードにアクセスする必要がないため、DASTは設定ミス、不完全な認証、悪用可能なビジネス ロジックに対して効果的であることが証明されています。しかし、伝統的なDASTは、最新のマイクロサービスやAPIでは苦戦を強いられています。

クラウド ネイティブのエコシステムでは、開発者はコンテナ化された環境やオーケストレーションされたシステムでテストできるツール、つまりエフェメラルなサービスを理解し、デプロイメントと並行して拡張できるツールを必要としています。DASTは、正しくチューニングされれば、本番環境にマージする前のリグレッションゲートとして機能し、静的ツールでは推測できない現実の問題をキャッチすることができます。

静的アプリケーション セキュリティ テスト(SAST)

SASTは、アプリケーションのソースコード、バイトコード、またはバイナリをレビューし、安全でない動作の既知のパターンについて調べます。その強みは、特にカスタムコードを分析する際の正確さにあります。深いロジックの欠陥、安全でないAPIの使用、ランタイムツールでは決して到達できないようなレース コンディションなどを発見することができます。しかし、チューニングは必要です。インテリジェントなフィルタリングがなければ、SASTは開発者が無視したくなるノイズを生み出し始めるからです。クラウド ネイティブのシフトにおいて、SASTツールは最新の言語やフレームワーク、CI/CD統合、バージョン管理されたベースラインをサポートしなければなりません。静的解析は、コードのどの部分がシークレットやユーザー入力を扱うかなど、文脈的なシグナルと組み合わせることで特に強力になります。これにより実際のリスクに沿った検出結果を優先することができるようになります。

インタラクティブ アプリケーション セキュリティ テスト(IAST)

IASTはSASTとDASTの間に位置するもので、通常、機能テスト中に実行されるアプリケーションを内部から分析します。コードベースを計測することにより、IASTは入力がアプリケーションをどのように流れるかを観察し、コードレベルの理解と動作を関連付けを行います。リアルタイムで脆弱性を特定し、悪用可能なパスにフラグを立てることに優れており、静的ツールや動的ツールだけよりも誤検出を抑えることができます。DevSecOpsを採用するチームにとって、IASTは、テスト スイートをセキュリティ監査に変えるという継続的なフィードバックへの道を提供します。クラウドネイティブ アーキテクチャでは、IASTはサービス全体の脆弱性を追跡し、コンテナ内の安全でないライブラリを検出し、API同士が予期せず会話したときに悪用可能なロジックを明らかにすることができます。

APIのファジング テスト

ファジング テスト(ファズテスト)は、不正な、予期しない、あるいはランダムなデータをAPIに供給することで、安定性やセキュリティの問題を明らかにするものです。スクリプトによるテストとは異なり、ファザーは予想していなかった振る舞いを発見するのに効果的とされ、例外を引き起こしたり、サービスをクラッシュさせたり、機密情報を漏えいさせたりするエッジケースを見つけるのがその目的です。APIが内部境界としても外部インターフェースとしても機能する最新のアプリケーション スタックでは、ファジングが不可欠とされています。よくチューニングされたファザーは、OpenAPIやgRPC定義のようなAPI仕様をターゲットとし、探索しながら学習し、以前の実行からのフィードバックに基づいて動的に入力を変化させることができます。APIを製品として扱うチームは、特に新しいエンド ポイントをパートナーや一般に公開する前に、パイプラインでのファジングテストを優先することが求められます。

アプリケーション セキュリティ体制管理(ASPM)

ASPMは単なるツールではありません。考え方の転換であり、すべてのセキュリティ発見事項にわたる可視性、相関性、実行可能性に重点を置いたものです。組織が何十ものツールを採用し、ツールそれぞれがコードからランタイムまで脆弱性を表面化させる中、ASPMはそれらをつなぎ合わせる存在です。ASPMは、ソフトウェア ライフサイクル全体のセキュリティを統一し、運用するために構築されています。

現代のアプリケーション環境は、あらゆる方向からシグナルを生成しています。これにはSAST、DAST、SBOM、ランタイム テレメトリ、アイデンティティの誤設定などが含まれ、それらはしばしば断片化され、重複し、ビジネスの優先順位とずれて届きます。ASPMは、調査結果を取り込み、それを実際のアプリケーション アーキテクチャにマッピングし、所有権、エクスポージャ、潜在的影響と関連付けます。その結果、単なる脆弱性のリストではなく、今、何が、誰にとって、なぜ重要なのかという優先順位がつけられます。

セキュリティ テストの概要

セキュリティ タイプ 主な機能 メリット デメリット
ペン テスト アプリとインフラで起こる実際の攻撃を、人間主導の手作業でシミュレーション
  • 実際の攻撃者の行動を模倣
  • ビジネスロジックの欠陥と連鎖的悪用を特定
  • 時間と費用がかかる
  • 継続的ではない
  • テスターのスキルに大きく依存
DAST HTTP/Sリクエストによる実行中のアプリケーションのブラックボックス テスト
  • 言語にとらわれない
  • ランタイムの問題を検出
  • Webアプリに効果的
  • コードパスの可視性が限定的
  • 近代化への追従が困難
  • APIと認証フロー
SAST ソース、バイトコード、またはバイナリを実行前に静止状態で解析
  • コードレベルの深い問題を検出
  • シフトレフト テストに対応
  • アプリの起動が不要
  • 多数の誤検出
  • ランタイム コンテキストの欠落
  • ノイズを減らすチューニングが必要
IAST インプロセス エージェントが機能テスト中のコード動作を監視
  • リアルタイム、コード認識型検出
  • 誤検知の減少
  • CI/CDインテグレーションに最適
  • ランタイム環境が必要
  • エージェントによるパフォーマンスへの影響あり
  • 言語サポートに制限あり
ファジング APIやインターフェイスに不正な入力や予期しない入力を送信
  • エッジケースと安定性の欠陥の発見
  • 入力処理のバグに有効
  • 言語に依存しない
  • 予測不能なカバレッジ
  • 優れたコーパスとターゲットモデルが必要
  • ロジックの欠陥を見逃す可能性あり
ASPM ツールやステージにまたがるセキュリティ調査結果を一元化し、関連付ける
  • インサイトの統合
  • リスクに応じた優先順位付け
  • クラウド ネイティブ スタックに対応
  • 統合の質に依存
  • 単体では検知機能なし
  • 強力なコンテキスト マッピングが必要

表2: アプリケーション セキュリティ テスト アプローチの比較

 

アプリケーション セキュリティ ツールとソリューション

セキュリティ テストは欠陥を発見します。敵対的な状況下でアプリケーションがどのように破壊されるのか、攻撃者はどこで力を得ることができるのかを明らかにすることができます。しかし、テストだけではシステムは安全ではありません。保護には検出以上のものが必要だからです。何を実行しているかを可視化し、どのように構築するかをコントロールし、どのように公開するかをガードレールするツールが必要です。

環境が刻々と変化するクラウドネイティブ アーキテクチャでは、セキュリティ ツールは単に拡張するだけでなく、レイヤー間のコンテキストを統合する必要があります。スキャナーだけでは、脆弱なコンポーネントが悪用可能になっても表面化できません。しかし、包括的なプラットフォームでは可能です。

Webアプリケーション ファイアウォール(WAF)

WAFは、インターネットとアプリケーション間のHTTPトラフィックを監視し、フィルタリングする機能です。SQLインジェクションの試み、クロスサイト スクリプティングのペイロード、プロトコル違反など、悪意のあるパターンを探し、バックエンドに到達する前にブロックします。WAFを使用することで、時間を稼ぐことができ、日和見的な攻撃を鈍らせることができます。しかし、根本的な欠陥は治りません。クラウド ネイティブのセットアップでは、WAFは複数のイングレス ポイントで動作し、gRPC、WebSocket、APIゲートウェイなどの最新のアプリ パターンをサポートしている必要があります。WAFを主要な防御手段として頼ることは、チームが脆弱性を発見するのが遅すぎることを意味します。

脆弱性管理

脆弱性管理はスキャナーではありません。これは、ソフトウェア スタック全体のリスクを特定し、優先順位を付け、是正するプロセスです。ツールは、オペレーティング システム、コンテナ イメージ、アプリケーション ライブラリ、および構成ベースライン内のCVEを表面化します。効果的なプログラムは、これらの発見を、オーナーシップ、状況、修正スケジュールに結びつけるものです。クラウド ネイティブ環境では問題は複雑化します。サービスが行ったり来たりし、コンテナは毎日リビルドされ、ドリフトは無言のリスクをもたらしています。課題は検出ではありません。相関付けなのです。どの脆弱性が本番環境で悪用可能な経路に影響を及ぼすかを知るには、スキャナー、ソース管理、CIパイプライン、ランタイム時の観測可能性を統合する必要があります。

ソフトウェア部品表(SBOM)

SBOMはインベントリであり、アプリケーションで使用されるすべてのコンポーネント、ライブラリ、依存関係の機械可読リストです。「私たちは実際に何を実行しているのか?」というシンプルかつ強力な問いに答えるものです。攻撃がますますサプライチェーンを標的にするようになる中、SBOMは可視化の基盤を提供します。脆弱性を検出する機能こそ持たないが、脆弱性が明るみに出たときに、その脆弱性にさらされているかどうかを教えてくれる存在です。強固なSBOM戦略は、SPDXやCycloneDXのようなフォーマット標準をサポートし、ビルドに自動的に統合するものです。これはゼロデイ対応時の影響分析への最短経路となります。

ソフトウェア構成分析(SCA)

SCAツールは、オープンソースの依存関係をコードベースでスキャンし、既知の脆弱性、ライセンスの問題、および遷移的なリスクにフラグを立てます。コンポーネントがどのように使用されるかを分析することで、SBOMよりも深く掘り下げることが可能です。強力なソフトウェア構成分析により、脆弱な関数がアプリケーション ロジックから到達可能かどうかを検出することができます。サービスが複数の言語にまたがる何千ものパッケージに依存する可能性があるクラウドネイティブ アプリケーションでは、SCAが不可欠です。しかし、それが価値をもたらすのは、発見が実用的である場合だけである。 最終的にトリアージされ、所有者にマッピングされ、開発ワークフローに組み込まれる必要があるのです。

クラウド ネイティブ アプリケーション保護プラットフォーム(CNAPP)

CNAPPは、ワークロード保護クラウド セキュリティ体制管理、アイデンティティ分析、CI/CD統合といった複数のセキュリティ分野を、クラウド ネイティブ システム向けに構築された統合型プラットフォームに統合するものです。インフラから、出荷時のコード、実行時の動作に至るまで、レイヤーを横断してアプリケーションをチェックします。ゴールは脆弱性や設定ミスを検出するだけではなく、それらがどのように交差しているかを理解することです。ハードコードされシークレットは、単独ではリスクが低いかもしれませんが、特権昇格の経路と公衆の面前に晒されることで、それは緊急の課題となるからです。CNAPPは、チームがシグナルの断片化を解消し、ノイズではなく悪用可能なリスクに焦点を当てるのを支援することができます。

単一の能力でアプリケーションを保護することはできません。そして、どれもアーキテクチャーの規律や安全なコーディングの習慣に取って代わるものではありません。しかし、意図的に使用することで、すべての開発者とセキュリティ エンジニアが把握できる視野を広げることができます。これにより推測ではなく、自信をもった取り組みを進めることができるようになります。

 

コンプライアンスはセキュリティではないが、オプションでもない

PCI DSS、HIPAA、GDPR、SOC 2、FedRAMPといった規制の枠組みは、ソフトウェアをセキュアにするものではありません。最低限のバーを定めているだけです。構造を押し付け、期待を標準化しているに過ぎず、安全を保証するものではないのです。コンプライアンス監査に合格したシステムでも、侵入されることは起こり得ますし、要件定義書に従った開発者でも、安全でないコードを作成することは起こり得るのです。

とはいえ、コンプライアンスは重要です。ソフトウェアが生きるエコシステムの一部だからです。それが指導者の疑問を駆り立て、顧客やパートナーの期待につながります。コンプライアンスは、データがどのように扱われ、誰がアクセスでき、どのような監査証跡が残されるかについて制約を設けるものです。それは単なる事務的な問題ではなく、アーキテクチャやデプロイメント、日々の開発の選択に影響を与えています。

実務者にとっては、コンプライアンスと実際のセキュリティ上の意思決定がどこで交わるかを理解することが重要です。

  • PCI DSS4.0がクライアント サイドスクリプトの整合性監視を義務付けている場合、これは単なるチェックボックスではなく、Magecartスタイルのサプライチェーン攻撃に対する真の防御策となります。
  • SOC 2がアクセス レビューとロギングを要求するのは、誰が何に触れることができるのか、そして何か問題が発生した場合にそれをどのように知ることができるのかを明確にするためです。
  • GDPRによるデータの最小化の要求は、より小さな影響範囲とよりクリーンなデータ境界を実現する後押しとなるものです。

コンプライアンスは強制的なものでもあります。安全なデフォルトを採用し、決定を文書化し、再現可能なコントロールを構築するよう、チームを後押しすることができる存在です。しかし、安全保障の成熟度を担保する代用品として扱われると危険です。監査に合格したからといって、システムが回復力を持つとは限らないからです。それは、システムが多くの場合、組織特有の脅威モデルを念頭に置くことなく、誰かが定義したベースラインを満たしていることを意味するからです。

目標は、コンプライアンスとセキュリティを一致させることであり、混乱させることではありません。正しく行えば、コンプライアンスは自らを守るソフトウェアを構築するための副産物になり得ます。しかし下手をすると、偽りの安全を謳うPDFの山になります。

 

アプリケーション セキュリティ FAQ

影響範囲を決めるのはコンテキストです。未使用のコードにある深刻度の高いCVEではありません。公開API上で認証されていないユーザーが到達可能な中程度の深刻度の問題は、深刻な問題となり得ます。到達可能性、悪用可能性、エクスポージャ、インシデント時の影響範囲を重視します。実行パスになかったり、悪用するための周辺条件が欠けていたりする場合は、優先順位を下げます。ランタイム シグナル、アセットのオーナーシップ、ビジネス ロジックのマッピングを使用して、ノイズと真のリスクを分離することが大切です。
抑制が安全なのは、次の2つの条件が満たされている場合です。1)脆弱性が文脈上悪用可能でないこと、2)将来のレビュアーのために理由が文書化されていること。静的な発見がデッドコード パスにぶつかったり、DASTの問題が上流のコントロールのために到達できなかったりした場合は、沈黙ではなく、正当な理由とともにフラグを立ててください。アーキテクチャや依存関係を変更するたびに再評価を行ってください。
信頼の境界線はすぐに移動します。内部APIは、機能拡張や設定ミスによって外部に公開されることがよくあります。なので内部APIは潜在的に敵対的な環境として扱う必要があります。「内部専用」のステータスに基づく、身元、レート制限、入力検証に関する仮定は避けてください。いずれインターネットに公開されることが予想されるからです。
Doppler、1Password CLI、または開発モードのクラウド ネイティブなシークレット マネージャなどのツールを通じて配布される、短命でスコープ付きのシークレットが最も安全なパスです。ドットファイルやシェルの履歴にシークレットを保存することを避け、完全なコミットは避けてください。可能であればローカル エミュレータやモック クレデンシャルを使用し、プレコミット フックやCIパイプラインにシークレット スキャンを統合してください。
すべてのSDKは誰かのサプライチェーンの一部になるものです。そのため使用だけでなく、誤用についても考える必要があります。サイレント エラーを避けてください。安全でない設定を明確に示してください。TLSを強制し、機密データのログを避け、すべての入力を検証します。たとえそれが「信頼できる」開発者から提供されたものであってもです。SDKがマルチテナント、高信頼環境で使用されることを想定し、それに従って行動します。
自動化は意思決定支援であって意思決定ではありません。スキャナーは既知の問題をキャッチすることができます。リンターは方針を強制することができます。シグネチャはドリフトを防ぐことができます。しかし、自動化では文脈を理解することも、ニュアンスの優先順位をつけることも、影響を評価することもできません。ゴールは人間のレビューに取って代わることではなく、誤検出を減らし、リグレッションを防ぎ、フィードバックをシフト レフトすることにあります。完全な自動化が機能するのは、既知で反復可能なものに限られます。
デプロイ後の脅威モデリングは、「何がうまくいかなかったか」から、「これまでどのように進化してきたかを考えると、今何がうまくいかないか」にシフトします。これを使用して、信頼境界を再評価し、新しいデータフローを特定し、アーキテクチャのスプロールを追跡します。継続的な脅威のモデリングは単一の成果物ではなく、製品のベロシティと結びついた適応的なプロセスです。何かが壊れたときだけでなく、システムが変わったときにモデルを見直すことが求められます。
信頼は、透明性、対応、実績によって得られるものです。活動的なメンテナ、シグネチャ入りのリリース、明確な依存関係ツリー、正式なリリースノートがあるプロジェクトを選ぶようにしてください。また、ステージングで自動アップデートを実行してください。他律的な依存関係を監視し、メンテナンス担当者のバーンアウトや異動を監視します。導入前には検査を行い、その後ロックし、監視をしてください。
スピードは時間を生み、正しさは安全を生みます。エクスポージャが大きく、インシデントの爆風半径が大きい場合は、たとえパッチが完璧でなくても、迅速に緩和することを優先してください。しかし、こうした応急処置を長期的な解決策として扱ってはいけません。早く直して、正しく直す。緊急緩和策を一時的なインフラとして扱い、撤去期限のある技術債務のように追跡することが大切です。
修復を通常のエンジニアリング サイクルに組み込んでください。セキュリティ債務がサイロ化されたり、見えなくなったりすると、管理できなくなります。他の技術的負債と同じように、所有者、タイムライン、リスクの正当性を追跡する必要があります。コンプライアンス指標ではなく、実際のビジネス インパクトに結びつけます。「セキュリティだけ」のスプリントは避け、小規模でインパクトのある修正を長期的な取り組みに入れることが求められます。
セキュリティの観測可能性とは、潜在的な悪用や侵害を示す異常な振る舞いを検出、相関、理解できることを意味します。従来のログは何が起こったかを記録します。観測可能性は、それらの出来事を意図に結びつけるものです。「これは期待された振る舞いなのか」と問うための視界と、当て推量なしにそれに答えるための文脈を与えてくれます。
セキュリティを開発プロセスに組み込んでください。チームにオーナーシップ、ガードレール、迅速なフィードバックを与えます。チェックリストを自動化に置き換えると共に、コンテキストに富んだアラートを提供します。信頼できるパターン、再利用可能なセキュアコンポーネント、事前承認されたライブラリを確立します。「No」ではなく、「その方法ではなく、代わりにこれを試してみてください」と提示できることが大切です。
以下の条件を満たすものです: すべての入力を検証することができる。すべてのアクセスを認証する。コード外でシークレットを保管している。機密データを静止時および転送時に暗号化している。構造化されたログを出力する。オーナーがはっきりしている。フェイルセーフである。パッチをサポート。どのバージョンが動いていて、その中にどんなコードがあるのかを証明できる。環境を信用していない。クライアントが正直であることを前提としていない。
一時停止し、影響を評価してください。到達可能性を判断します。エクスポージャ経路をマッピングします。脆弱なコードがどこにあり、どのように使われているかを特定します。騒ぎが起きている場所ではなく、使用状況に基づいて修正の優先順位を決めます。必要であればパッチを当て、可能であれば隔離を行います。対応を文書化し、SBOMを更新します。依存性監視パイプラインにカバレッジを追加することで、将来性を確保できます。
次のような開発者による仮定です: 入力がすでに上流で検証されていると仮定すること。内部システムはデフォルトで安全であると仮定すること。TLSがすべてを解決するものだと仮定すること。ユーザーがリクエストを操作しないと仮定すること。オープンソースを安全なものだと仮定すること。攻撃者がその隠されたエンドポイントを見つけられないと仮定すること。この3つの些細な問題が連鎖して重大な問題に発展することはないだろうと仮定すること。
CSPは、スクリプト、スタイル、画像、フォントなど、ページ上でロードまたは実行できるリソースを制限するブラウザの機能です。明示的なロードルールを強制することで、XSSやサプライチェーン攻撃の影響を軽減します。強力なCSPは、インライン スクリプトをブロックし、noncesまたはハッシュを要求し、オリジンを信頼できるソースに限定します。正しく導入されれば、ブラウザは単なるレンダラーではなく、エンフォースメント レイヤーとして機能するようになります。
OWASP(Open Worldwide Application Security Project)は、ソフトウェアのセキュリティ向上を目的とした非営利財団です。Webアプリケーション セキュリティの分野で、自由に利用できる記事、方法論、文書、ツール、技術を作成しています。