API-Security-Checklist/README-ja.md at master · shieldfy/API-Security-Checklist · GitHub
というAPI を作成する際に確認しておくと良さそうなセキュリティチェックリストがあります。 気になって内容を確認したところ、「あれ、意外によくわからない」となったので個人的な補足説明を作成しました。チェック項目については引用で、補足説明については通常の文章で記載します。
認証
Basic認証
を利用せず、標準的な認証を利用する(例: JWT、OAuth)。
-
Basic認証
についてApache 等のHTTPサーバーで設定できる簡易な認証です。
ベーシック認証(Basic認証)とは?設定方法と注意点・エラーになる原因を解説 | Webmedia
nginx でも設定できるのか気になったのですが、以下の記事を見る限りできるようです。 Nginx で Basic 認証 - Qiita
認証
、トークンの生成
、パスワードの保管
の車輪の再発明を行わず、標準化されているものを利用する。
オレオレで独自作成せずに、一般によく知られた仕組みを使いましょうという意味です。
ログインでは最大リトライ回数(Max Retry)
とjail機能を利用する。
- jail機能
API Security Checklist に記載されていますが、ブラックリスト機能のようです。
以下のドキュメントに記載されている jail のことだと思われます。いわゆるアカウントロック機能ですFail2Ban jail 管理 | Plesk Onyx documentation
全ての機密情報は暗号化する。
ここは特に疑問点ありませんでした。
JWT (JSON Web Token)
jwt に関するチェック項目になります。
ブルートフォース攻撃を困難にするため、ランダムで複雑なキー(JWT Secret
)を使用する。
- JWT
JWTについて良く知らず、以下が参考になりました。
JSON Web Token(JWT)の紹介とYahoo! JAPANにおけるJWTの活用 - Yahoo! JAPAN Tech Blog
JWT Secret
セキュリティ視点からの JWT 入門 - blog of morioka12 に記載されている3.2. 脆弱な HMAC 鍵をブルートフォースによる特定
に関する内容を指しています。ブルートフォース攻撃に耐えられる秘密鍵の仕組みを使えと言っています。少し眺めたうくらいでは理解は難しいかもしれません。
その他以下の記事は参考になりそうです。
ペイロードからアルゴリズムを抽出してはいけない。必ずバックエンドで暗号化する(HS256
またはRS256
)。
JWT ハンドブック の5.1.1.1 鍵管理モード あたりの内容に思います。
以下は、5章の冒頭の抜粋です。
JSON Web Encryption (JWE) はデータを第三者に対 して不透明にする⼿段を提供します。この場合、不透明とは読み取れないことを意味します。暗号化されたトークンを第 三者が調べることはできません。この機能は、さまざまな⽤途に活⽤できます。
ペイロードを暗号化することで第三者の閲覧を防止するとあります。
トークンの有効期限(TTL
, RTTL
)を可能な限り短くする。
TTL
(time to live) RTTL
(reflesh time to live) について、
以下のドキュメントに記載の内容が参考になります。
どれくらいの長さにするかはサービスの要件に依存するので、検討、合意形成は必要に思いました。
JWTのペイロードに機密情報を格納してはいけない。それは簡単に復号できる。
ペイロードには、個人情報を設定すべきではなく、設定する場合は何故必要か?
漏洩した時のリスクなどを話しし合うべきだと思います。
個人情報とは何か?ですが、Google Analytics の個人情報の定義が参考になります。
OAuth
OAuth のチェックリストの理解には、OAuthの仕様理解が前提として必要になるなと思いました。
サーバサイドで常にredirect_uri
を検証し、ホワイトリストに含まれるURLのみを許可する。
これは以下のQiita記事で説明されている内容になります。
常にtokenではなくcodeを交換するようにする(response_type=token
を許可しない)。
"response_type=token
を許可しない” 理由が良くわかりませんでした。。
OpenID Connect ではresponse_type=token
を使用していない旨が以下の記事に書かれています。
英文で検索すると、Hacker News の以下の投稿がヒットします。 これはおそらくチェックリストから除外すべきでは?で除外すべき理由が記載されています。
state
パラメータをランダムなハッシュと共に利用し、OAuth認証プロセスでのCSRFを防ぐ。
以下の記事に、state パラメータの役割とOAuth における CSRF 攻撃について記載されています。
デフォルトのscopeを定義し、アプリケーション毎にscopeパラメータを検証する。
scopeパラメータの役割と、検証する意義は以下の記事を読むことで検証が必要な理由は理解できました。
アクセス
HTTP/HTTPS での通信に関するチェック項目です。
DDoSやブルートフォース攻撃を回避するため、リクエストを制限(スロットリング)する。
GCPのリクエスト制限に関する説明です。
Apache HTTPサーバー、nginx のDDos プラグインについてのリンクです。
以下は、Rate-Limiting を実現するライブラリのようです。
仕事ではJavaを使うので、JavaでRate-Limitingを実現するためのライブラリを調べたところ、 以下見つかりました。
bucket4j を用いた Rate-Limiting - Qiita
MITM(Man in the Middle Attack)を防ぐため、サーバサイドではHTTPSを使用する。
日本語だと、中間者攻撃と呼ぶようです。 以下、参考になりました。
SSL Strip attackを防ぐため、SSL化とともにHSTS
ヘッダを設定する。
以下、HSTS
に関するMDNの記事です。
SSL Strip attack については以下のPDFが参考になりそうでした。
以下はSSL Strip attack
での検索でヒットしたGithubに公開されているツールです。
入力
API のインプットとなるデータに対するチェックやチェック後の応答に関するチェック項目です。
操作に応じて適切なHTTPメソッドを利用する。GET(読み込み)
, POST(作成)
, PUT/PATCH(置き換え/更新)
, DELETE(単一レコードの削除)
。リクエストメソッドがリソースに対して適切ではない場合、405 Method Not Allowed
を返す。
この辺りは、Web API のお作法になるかと思います。 ピンとこない場合は、以下書籍を読んだりすると良いのかもしれません。
リクエストのAcceptヘッダ(コンテンツネゴシエーション)のcontent-type
を検証する。サポートしているフォーマット(例: application/xml
, application/json
等)は許可し、そうでない場合は406 Not Acceptable
を返す。
指定ミスの際に406エラーを返すのは良いとして、
Accept ヘッダの指定がない場合は、エラーとするかデフォルトで判断するのか迷います。
POSTされたデータのcontent-type
が受け入れ可能(例: application/x-www-form-urlencoded
, multipart/form-data
, application/json
等)かどうかを検証する。
このケースも、406
エラーを返す必要があります。
ユーザーの入力に一般的な脆弱性が含まれていないことを検証する(例: XSS
, SQLインジェクション
, リモートコード実行
等)。
以下の記事に少し詳細な説明が記載されています。
この辺りのチェックはOWASP で API 関連の脆弱性チェックツールないかなと思って検索したら、 存在しました。どのようなツールなのか気になるので動作確認してみようと思います。
URLの中に機密情報(認証情報
, パスワード
, セキュリティトークン
)を利用せず、標準的な認証ヘッダを使用する。
オレオレで独自作成せずに、一般によく知られた仕組みを使いましょうという意味と捉えました。
キャッシュ、Rate Limit policies(例: Quota
, Spike Arrest
, Concurrent Rate Limit
)を有効化し、APIリソースのデプロイを動的に行うため、APIゲートウェイサービスを利用する。
APIゲートウェイを導入すると、以下項目についてもチェックOKになりそうに思いました。
DDoSやブルートフォース攻撃を回避するため、リクエストを制限(スロットリング)する。
その他、以下記事が参考になりそうです。
- API gateway (API ゲートウェイ) とは - 機能と役割 | Red Hat
- API ゲートウェイ パターンと、クライアントからマイクロサービスへの直接通信との比較 | Microsoft Docs
処理
プログラミングに関するチェック項目です。
壊れた認証プロセスを回避するため、全てのエンドポイントが認証により守られていることを確かめる。
「認証の実装漏れのないエンドポイントがないのか定期的に確認する」ということかと思います。
ユーザーに紐付いたリソースIDを使用してはならない。/user/654321/orders
の代わりに/me/orders
を利用する。
個人情報に関わるリソースの場合、推測可能なIDは避けた方が良いです。
情報自体に価値があるケースも同様かと思います。
オートインクリメントなIDを利用せず、代わりにUUID
を利用する。
これも推測を難しくするための方法になります。
XMLファイルをパースする場合、XXE
(XML external entity attack)を回避するため、entity parsingが有効でないことを確認する。
以下の記事が参考になりました。
XMLファイルをパースする場合、exponential entity expansion attackによるBillion Laughs/XML bomb
攻撃を回避するためentity expansion が有効でないことを確認する。
Java では使用している XML Parser ごとの対策が必要に思いました。 以下の記事が参考になりました。
ファイルアップロードにはCDNを利用する。
API でのファイルアップロード方法は以下が参考になります。
CDN を利用した方が良い理由は、速度的なところでのメリットが大きいからに思います。
大量のデータを扱う場合、バックグラウンドでWorkerプロセスやキューを出来る限り使用し、レスポンスを速く返すことでHTTPブロッキングを避ける。
HTTPコネクション数にも上限があるので、大切に使おうということかと思います。 要求を受け付けるだけで処理を待つ必要がない場合は、すぐに結果を返した方が良いでしょう。
デバッグ・モードを無効にすることを忘れないでください。
API Security Checklist の説明が参考になります。
出力
X-Content-Type-Options: nosniff
をヘッダに付与する。
XSS を防ぐために付与しておいた方が良さそうです。
- X-Content-Type-Options - HTTP | MDN
- 知っていれば恐くない、XMLHttpRequestによるXSSへの対応方法:HTML5時代の「新しいセキュリティ・エチケット」(3)(2/2 ページ) - @IT
X-Frame-Options: deny
をヘッダに付与する。
IFrame での表示を拒否するヘッダ設定です。 API のResponse をIFrame で表示することは常識的になさそうなので、付与すべきと思いました。
Content-Security-Policy: default-src 'none'
をヘッダに付与する。
これはブラウザからの直接呼び出しがある場合は、付与すると動作しなそうに思いました。
BFFがあるような構成の場合、API側のヘッダーとして付与するようなイメージに思います。
フィンガープリントヘッダを削除する - X-Powered-By
, Server
, X-AspNet-Version
等。
これはAPサーバー側が付与するヘッダ類です。使用しているサーバーミドルウェアの情報が漏洩してしまうので削除した方が良いかと思います。
content-type
を必ず付与する。もしapplication/json
を返す場合、content-type
はapplication/json
にする。
クライアントプログラムや、ブラウザにレスポンスを正しく処理させるために必要な設定です。
認証情報
, パスワード
, セキュリティトークン
といった機密情報を返さない。
ストレートに返さないという当たり前の考慮と、SQLインジェクション等で漏洩しないかを確認する必要があると思いました。
処理の終了時に適切なステータスコードを返す(例: 200 OK
, 400 Bad Request
, 401 Unauthorized
, 405 Method Not Allowed
等)。
これも基本的な作法の話に思いますので、理解できていない場合は書籍などを見た方が良いです。
CI & CD (継続的インテグレーションと継続的デリバリー)
セキュリティとは直接関係しない開発の進め方に関するチェックです。
ユニットテスト/結合テストのカバレッジで、設計と実装を継続的に検査する。
自動テストを書くこと、APIはUIを持たないので比較的テストは自動化しやすいと思います。
コードレビューのプロセスを採用し、自身による承認を無視する。
コードレビューに関するチェック項目です。
プロダクションへプッシュする前に、ベンダのライブラリ、その他の依存関係を含め、サービスの全ての要素をアンチウイルスソフトで静的スキャンする。
Java のライブラリの依存関係チェックには、SonarQube の dependency-check-sonar-plugin が使用できそうです。 https://github.com/dependency-check/dependency-check-sonar-plugin
デプロイのロールバックを用意する。
リリース後に問題があった場合もすぐにリカバリーできる状態を準備しておくという意味だと思います。セキュリティバグが混入してもすぐに問題がないバージョンに戻すことができます。
「何故やるのか?」の部分をブレイクダウンして記載しました。 どのように実現するかは、企業やITプロジェクトの現場で異なるので都度検討する必要があります。
モニタリング
2022年11月に新たに確認したところ、内容が追記されていました。
APIやAPIの稼働しているサーバーに対しての監視やモニタリングについてのチェック項目です。
すべてのサービスとコンポーネントに集中ログインを使用します。
中央集権的な、認証、認可の仕組みを使っているかどうかを確認するチェック項目です。
認証、認可にどのような仕組みを使っているのか?
を確認したいのかなと思いましたが、もしかしたら監視システムに対する認証と、認可に対する観点かもしれません。
- そもそも監視システムを使っていない。
- 監視システムを使っているけど、認証認可が中央集権的ではない。
- APIの認証がない。
などの状態がありそうです。
すべてのトラフィック、エラー、リクエスト、およびレスポンスを監視ために、エージェントを使用します。
監視システムだと、エージェント形式の監視か、そうでないかという観点がありそうですが、おそらく以下の観点がちゃんとチェックに落とし込めているかを確認しているように思いました。
- エラー、リクエスト、トラフィック、レスポンスを監視しているか?
- 監視している監視システムはすべて同一か?
SMS、Slack、Email、Telegram、Kibana、Cloudwatch、などのアラートを使用します。
このチェック項目は、APIのエラーのアラートの通知を受け取るようにしているか?
という観点かと思います。
通知を受け取らない立場の場合ですと以下のような、考えで確認をすると良いかと思います。
* 通知の仕組みを理解しており、通知受信者の行動をプログラム実装がサポートできているか?
* エラー時の運用手順書の提供をしているか?
クレジット・カード、パスワード、PIN、などの機密データをログに記録していないことを確認します。
これは機密情報のログ出力についての観点になります。
各情報をログに出力していないことを確認すべきと思います。
APIリクエストとインスタンスを監視ためにIDSやIPSシステムを使用します。
IDSは、不正侵入検知システム
で IPSは、侵入防御システム
です。
それぞれの導入状況を確認するチェック項目になります。
アプリケーション開発担当と、インフラ担当で担当者が分かれる項目かも知れません。
以上です。
コメント