誰が確認するかで分類したAPIセキュリティテストチェックリスト
自動化された機能検証でカバーできる項目
これらは振る舞いの検証です。拒否すべきリクエストに対してAPIが正しく応答するか、という確認にあたります。通常のテストスイートに含め、変更のたびに実行すべき項目です。
認証なしのアクセスが拒否されること。 保護されたすべてのエンドポイントが、認証情報なしで呼び出された場合にデータではなく適切な拒否応答を返します。
オブジェクト単位で認可が適用されること。 ユーザーAが、パス内の識別子を書き換えるだけでユーザーBのレコードを読み取ったり変更したりできないこと。これは実際のAPIで最も多く悪用される欠陥でありながら、単純な振る舞いの検証で確認できます。
ロールの境界が守られること。 読み取り専用のロールが書き込みを行えず、期限切れまたは失効したトークンが拒否されます。
入力検証が範囲外の値を拒否すること。 ドキュメントに記載されていないものも含め、すべてのパラメータの境界値。
エラーが内部情報を漏らさないこと。 スタックトレース、クエリの断片、内部ホスト名がレスポンスに含まれません。
スキャナーや専用ツールが必要な項目
依存関係とライブラリの脆弱性。
インジェクション系:SQL、コマンド、テンプレート、デシリアライゼーション。
TLSの設定と証明書の取り扱い。
自社スタックに対する既知CVEの調査。
人間が必要な項目
ビジネスロジックの悪用。数量をマイナスにして注文する、割引を再利用する、順序を前提としたワークフローの手順を飛ばす、といったものです。
脅威モデリング、そして何が実際に機密データなのかを判断すること。
自社製品がどう悪用され得るかについて、創造性を要するもの全般。
見落とされがちな項目
オブジェクトレベルの認可は、最も抜け落ちやすく、しかも最も簡単に確認できる項目です。アカウントを2つ作り、一方でレコードを作成し、もう一方のトークンでそれを読み取ってみてください。そこでデータが返ってくるなら、業界で最も一般的な重大なAPIの欠陥を抱えていることになります。しかも、それを見つけるのに必要なテストは1つだけです。
この検証を自動化するだけで取り組み全体の元が取れます。新しいエンドポイントが増えるたびに同じ確認を繰り返す必要があり、人間がそれを覚えていられることはないからです。
自動化できる半分を実際に動かす
生成されるAPIテストプランには認可と境界値のカテゴリが含まれるため、これらの検証は、誰も予定を組まない独立したセキュリティ施策としてではなく、機能面のカバレッジと同じ場所に存在します。
ターミナル
npm install -g @testsprite/testsprite-cli
testsprite setup
ローカルへのインストールを避けたい場合は、ダッシュボードでも同じ範囲をカバーできます。そして、コマンドの全体像をすべて掲載しているのが CLIリポジトリ。
詳しい仕組みをまとめているのが APIテストのドキュメント。
常設しておくべき2つのアカウント
このリストにある振る舞いの検証項目は、そのほとんどが2人のユーザーを必要とします。そして最も低コストな対策は、テストごとにアカウントを作るのではなく、各環境にテスト用アカウントを2つ常設しておくことです。
自社製品にとって意味のある違いを持たせてください。所有者を分け、ロールがあるならロールも分け、できれば所属組織も分けます。そうすれば、認可の検証はどれもセットアップ作業ではなく2行のテストで済むようになり、実際に書かれるようになります。
うまくいかないのは、テストごとにアカウントを作成するやり方です。処理が遅く、データが残り、しかも検証がサインアップフローの正常動作に依存します。サインアップが壊れれば、本来とは無関係な理由ですべての権限テストが失敗します。一度だけ投入する常設アカウントにすれば、こうした問題はすべてなくなります。
グループごとの実行頻度
振る舞いの検証は変更のたびに。スキャナーは定期的に、そしてリリース時に。人によるレビューは脅威モデルが変わったとき、つまり新しい種類のデータや新しい種類のユーザーを追加したときに実施します。
ダッシュボードからリポジトリを接続すれば、すでに行っているデプロイを起点にテストが実行されます。あるいは、自前のワークフローにステップを追加する方法もあります。
TestSpriteが自動化可能な3分の1をどうカバーするか
生成されるAPIテストプランには認可と境界値のカテゴリが含まれます。そのため、このリストの振る舞いに関する項目は、誰かが予定を組まなければならない別施策としてではなく、機能面のカバレッジと同じ場所に存在します。
つまり、認証なしのアクセス、オブジェクトレベルの認可、ロールの境界、期限切れトークン、範囲外の入力が、変更のたびに、稼働中のサービスに対して、先週追加されたものも含むすべてのエンドポイントについて検証されます。Auto-Authenticationは実行中のセッションを維持し、Dynamic Variablesは呼び出し間で値を引き継ぎ、Dependency Chainsは各ケースが必要とするものと生成するものから実行順序を導き、Auto-Cleanupはその実行で作成されたものだけを削除します。
価値があるのは巧妙さではなく頻度です。これらの検証は書くこと自体が難しいのではなく、40個目のエンドポイントで思い出すことが難しいのです。自動生成して継続的に実行する仕組みがあってはじめて、誰かが守らなければならないプロセスを増やすことなく、実際のAPIで最も多く悪用される穴を塞げます。
これはペネトレーションテストの代わりになりますか?
いいえ。継続的にカバーするのは振る舞いの半分です。その分、ペネトレーションテストが見つけるべき対象が減り、コストのかかる依頼の価値が高まります。
TestSpriteは脆弱性スキャンを行いますか?
いいえ。検証するのは振る舞いであり、認可や境界値のケースも含まれます。脆弱性スキャンは別の道具です。
振る舞いの検証はどのくらいの頻度で実行すべきですか?
変更のたびに実行してください。新しいエンドポイントは次々に増え、そのどれもが直前のものと同じ認可の検証を必要とします。
どこから始めるべきですか?
識別子を受け取るすべてのエンドポイントに対する、オブジェクトレベルの認可からです。最も見つかる確率が高く、手間は最も小さい項目です。
これにはセキュリティチームが必要ですか?
脅威モデリングとビジネスロジックの悪用については必要です。上記のチェックリスト項目は、通常のエンジニアリング作業の範囲です。