January 10, 2018

API Security Checklist

Webアプリケーションには、機能、サービス拡張のためにサードパーティAPIが使用されていることが多い。しかし、Akana社による調査によると、使用されているものの内、65%以上もががセキュアなAPIのアクセスプロセスを取っていない。脆弱なAPIの使用により、多数のユーザーに一度に影響与えてしまうので、セキュリティは常にサービス提供側にとっては必ず安全にして抑えておきたい箇所だと思う。 そこで、この記事では、セキュアなAPIを設計するためのベストプラクティスを紹介する。

認証周り

認証(authentication)はサービスのユーザーがユーザー本人だということを証明する。そうしなければ、ハッカーが認証の脆弱性につけこみ、ユーザーのフリをして、個人情報といった機密情報を取得されてしまう。

Basic認証の使用をやめる

Basic認証とは、HTTP認証の内、最もシンプルなな認証形式です。各リクエストで、ユーザー証明証(クレデンシャル)をプレーンでかつ、暗号化されてないHTTPのフィールドとして送ってしまうかもしれない。なので、代わりとして、より安全な方法であるJWT or OAuthを使うべき。

自前の認証方法の使用はやめる

自前で設計したAuthシステム、トークン生成、パスワード保管は実装しないほうがいい。管理は行わないでください。自分のアプリケーションの言語やフレームワークによって、すでに安全と検証された方法があることが多い。自分の使用してる言語やフレームワークのドキュメントを読み、まずはそれらの実装方法を確認しよう。

アクセス最大試行回数とJail(ブラックリスト)システムの仕組みの実装

ハッカーはあらゆる証明情報を組み合わせて認証通過を試みてくる。そこで、最大施行回数を設定することで、その値を超えて認証を試み、失敗したユーザーはjail(ブラックリスト)に加え、ある一定時間経過しないと、同じIPからの認証をできないようにする。

全データを暗号化する

データ送信時には常に暗号化を行う。サービスとユーザー間でやり取りされるプレーンなHTTPリクエストを読み取ることは、ハッカーにとって容易である。そこで暗号化を行うことで、クレデンシャルや機密情報を盗む難易度を大きく上げることができる。

アクセス

アプリケーションを破壊するには、そもそも攻撃する側は認証される必要もない。

リクエストの制限

最もよくあるはサーバーに大量のリクエストを送信するDoS攻撃だ。サーバーがその膨大なリクエストに対応しようとし、不可がかかりすぎ、最終的にはサーバーの容量といったリソースを使い切ってしまう。 どこで、同一IPからのAPIに一定時間あたりに使用(アクセス)できる回数を指定し、DoS攻撃を軽減させる、また、ベンダーと連携し、アタッカーがサーバーにアクセスする前に、DoS攻撃を防ぐと良い。

暗号化を必須にする

暗号化されていないHTTPを使用すると、ユーザーが中間者攻撃(MITM)を受けやすくなってしまい、ハッカーやサードパーティのプログラムなどにユーザーネーム・パスワードなどの機密情報を取られてしまう。セキュアなHTTP(HTTPS)通信はクライアントとサーバーでのデータのやり取りを暗号化し、データを取られることを防ぐ。

Input

ユーザーがAPIにログインできるというだけでは、そのアクセスが信頼できるというけではない。ユーザーのinput情報を入力を正しくバリデーションを行わなければ、XSSやSQLインジェクションといったWebアプリケーションの脆弱性の原因となってしまう。

HTTPメソッドを強制する

各APIのエンドポイントはGET、POST、PUT、DELETEといった有効なHTTPメソッドリストを持っているはずで、これらはHTTPメソッドは、ユーザーが行おうとする操作と連動している必要がある。 例) GETはリソースの取得、DELETEは必ずリソースを削除する挙動)

これらのメソッドとマッチしない操作に対しては、405 Method Not Allowedを返そう。これにより、ユーザーが誤って(または意図的に)間違ったメソッドを使用することを防ぐことができる。

Content Negotiation(コンテンツネゴシエーション)を利用する

クライアントとサーバー間でデータをシェアする際は、送信されたContent-Typeをバリデートしよう。

例) クライアントからJSON形式のデータが送信されることを想定している際、Content-Typeヘッダーがapplication/jsonと設定されているリクエストのみを許可する

もし送信されたContent-Typeが違う、サポートされていない場合、406 Not Acceptableを返す。

ユーザーのinputのバリデーション

ユーザーインプットの不正形成における、最も一般的な脆弱性の原因:

これらの攻撃は、サーバー上で処理する前にHTMLタグ、JavaScriptタグやSQL文をユーザーinputを検証して取り除いたり、変換することで減少させることができます。TemplarbitはXSSから守るためのコンテンツセキュリティポリシーを導入する支援をします。フリートライアルはこちらから。 関連記事: Content Security Policyの導入によるクロスサイトスクリプティング対策方法

コンポーネントの脆弱性について

使われていないdependencies、モジュール、不必要な機能、コンポーネント、ファイルやドキュメントを削除しよう。そして、既知の脆弱性に対応するため、依存モジュールのバージョンを定期的に確認するべきだ。Githubで、あるリポジトリに対しては、この機能を使用できる。また、既知のの脆弱性のためにモジュールなどの削除やアップデートを行うだけでなく、メンテナンスがされていなかったり、古いバージョンに対してセキュリティパッチされていないライブラリやコンポーネントを随時確認することも考慮すべき。

信頼性の高いソースか確認する

新しいモジュールなどを選ぶ際は、公式のリースのセキュアなリンクがらのコードを追加すべき。さらに、署名されたパッケージが理想だ。というのも、修正されていたり悪意のあるコンポーネントを含んでいる可能性が低くなる。

データ処理

ユーザーinputの検証だけでは、攻撃から守れない場合もある。特別に作られたデータ(ペイロード)は、サーバー上でコードを実行したり、DoS攻撃を引き起こしたりできてしまう。

機密性の高いエンドポイントの保護

機密情報へアクセスできるエンドポイントには、必ず認証を行う。これにより、認証されていないユーザーからのアプリケーションのセキュアな部分のアクセスを防ぎ、また匿名ユーザーとして操作することを防ぐことができる。

Auto Incrementing(オートインクリメント)されたidの使用を避ける

Auto-Incrementingされたidを使うと、攻撃する側がアクセス権のないリソースのURLを簡単に予想できる。なので、代わりに、リソースの識別には、UUIDを使おう。

バックグラウンドでのデータの処理

同期的に大量のデータの処理を行うと、APIのレスポンスが遅れてしまう。クライアントを待たせないためにも、大量なデータ処理のある部分ではできるだけ非同期で行うべき。

デバッグモードをオフにする

当たり前だが、デプロイ前にアプリケーションがプロダクションモードになっているかを確認しよう。プロダクションでデバッグ状態のままのAPIがあると、パフォーマンスに関するトラブルが起きたり、テストエンドポイント、不正なエンドポイントへ意図せずアクセスしてしまう操作が行われたりし、組織や開発チームの機密データが流出する可能性がある。

ロギングとモニタリングについて

全てのログイン情報、アクセス制御エラー、サーバーサイドでのインプットバリデーションの際のエラーのログを疑わしい、悪意のあるアカウントを特定するのに十分なユーザーコンテキストで取ると良い。 また、後から法的な部分からも分析ができるように、十分な期間保存しよう。 ここで、吐かれるログは、ログ管理システムで簡単に使用できるフォーマットになっているべきだ。

Templarbit (テンプラービット) 社について

Webアプリケーションのセキュリティにこれだけ使えばいいという特効薬のようなものはありません。Templarbit (テンプラービット) 社では、Webアプリをセキュアにする際のよくある問題点をよく理解しています。我々のゴールは、開発者にセキュリティのコンセプトとベストプラクティスを理解してもらい、悪意のある行為からソフトウェアを守るために最良のセキュリティーツールを導入してもらうことです。

コンテンツセキュリティポリシー(CSP)の導入から始めたい方は、ぜひこちらからフリートライアルをお試しください。



出典:
OWASP Top 10
Shieldfy’s open source security checklist