REST API / Webサービスを保護するためのベストプラクティス[終了]


828

REST APIまたはサービスを設計するときに、セキュリティ(認証、承認、ID管理)を処理するための確立されたベストプラクティスはありますか?

SOAP APIを構築する場合、ガイドとしてWS-Securityがあり、このトピックに関する多くの文献が存在します。RESTエンドポイントの保護に関する情報が少なくなりました。

RESTにはWS- *に類似した仕様が意図的にないことを理解していますが、ベストプラクティスまたは推奨パターンが浮かび上がってきたことを願っています。

議論や関連文書へのリンクは非常に高く評価されます。必要に応じて、.NET Frameworkのv3.5を使用して構築されたREST API /サービスのPOX / JSONシリアル化メッセージでWCFを使用します。


1
githubのREST APIとwebServicesで良いパターンとプラクティスを使用した完全な実際のアプリケーションを知っていますか?
PreguntonCojoneroCabrón

回答:


298

微調整が言ったように、Amazon S3は作業に適したモデルです。それらのリクエスト署名には、偶発的および悪意のあるリクエストのリプレイの両方から保護するのに役立ついくつかの機能(タイムスタンプの組み込みなど)があります。

HTTP Basicの良いところは、事実上すべてのHTTPライブラリがサポートしていることです。もちろん、この場合はSSLを要求する必要があります。これは、プレーンテキストのパスワードをネット経由で送信することは、一般的には悪いことです。SSLを使用する場合は、ダイジェストよりもベーシックの方が適しています。これは、呼び出し元が資格情報が必要であることをすでに知っている場合でも、ダイスはnonce値を交換するために追加のラウンドトリップを必要とするためです。Basicでは、呼び出し元は資格情報を初めて送信するだけです。

クライアントのIDが確立されたら、承認は実際には単なる実装上の問題です。ただし、既存の承認モデルを使用して、承認を他のコンポーネントに委任することもできます。ここでも、Basicの良い点は、サーバーがクライアントのパスワードのプレーンテキストコピーで終わり、必要に応じてインフラストラクチャ内の別のコンポーネントに渡すことができることです。


3
SSLはセキュリティの重要な部分ですが、すべてのアプリケーションがそのレベルの暗号化を必要とするわけではありません。誰かがあなたがTwitterに公に投稿しようとしているものを転送中に盗んだ場合、それはそのような重大な欠点ですか?APIのSSL暗号化の大半が優先されます。SSLのインフラストラクチャ要件はプレーンテキストの場合よりもいくらか高く、中間(ここではエッジベース)キャッシュサーバーは繰り返しアクセスされるコンテンツのキャッシュに参加できません。提供される暗号化が絶対に必要な場合、スケーラビリティが低下する可能性があることに注意してください。
Norman H

36
@NormanH:私のTwitterへの投稿に使用するトランザクション全体を誰かが見ることができれば、私になりすまして自分のメッセージを自分の名前で投稿できるため、あなたの主張は疑わしいものです。
グレッグヒューギル2013年

3
ダイジェスト認証に関するウィキペディアから引用すると、「ダイジェストアクセス認証は、WebサーバーがユーザーのWebブラウザーと資格情報をネゴシエートするために使用できる合意済みの方法の1つです。ネットワーク経由で送信する前に、パスワードにハッシュ関数を適用します。プレーンテキストを送信する基本アクセス認証よりも安全です。」これは、上記で言及したことを達成するための1つの標準的な方法です。(詳細については、en.wikipedia.org / wiki / Digest_access_authenticationを参照してください)
Norman H

5
"sending plaintext passwords over the net is almost universally a bad thing"-「ほぼ」について詳しく説明できますか?それは悪い考えではありませんか?
toniedzwiedz 2014年

2
@GregHewgillはプライベートネットワークでも、ユーザーがお互いのパスワードを傍受できるようにしたくありません。私が考えることができる唯一の状況は、ネットワークを介してパスワードを送信しても問題ないというのは、ユーザーがネットワーク内にいるときだけです。このようなことが他の場所で発生するという事実は、それを許可する理由にはなりません。
toniedzwiedz 2014年

115

HTTP以外にRESTの標準はありません。そこには確立されたRESTサービスがあります。それらをのぞいて、それらがどのように機能するかを理解することをお勧めします。

たとえば、独自のサービスを開発する際に、AmazonのS3 RESTサービスから多くのアイデアを取り入れました。ただし、リクエストの署名に基づくより高度なセキュリティモデルを使用しないことを選択しました。より単純なアプローチは、SSLを介したHTTP基本認証です。あなたはあなたの状況で何が最もうまくいくかを決めなければなりません。

また、私はO'reillyの本RESTful Web Servicesを強くお勧めします。コアコンセプトについて説明し、いくつかのベストプラクティスを提供します。一般に、それらが提供するモデルを取得して、独自のアプリケーションにマップできます。


6
RESTful Webサービスは間違いなく素晴らしい本です。この領域を読む必要があります。それは実に刺激的でした。
EdgarVerona 2009年

6
@aehlkeが(1)REST仕様などのものがないこと、および(2)建築スタイルに関するフィールディング論文およびネットワークベースのソフトウェアアーキテクチャの設計について明示的にRESTについて言及していることを考慮して、そのコメントに対する多くの賛成票を受け取った理由および6.3のHTTP:RESTがHTTPに適用されました。

20
HTTPはRESTの要件ではありません。
nategood 2013年

1
RESTful Webサービスの本は、次のWebサイトから無料で入手できます:crummy.com/writing/RESTful-Web-Services
icc97

その本を読むつもりでしたが、主にXML形式を対象としていることに気付きました。JSONの人気を考慮して、この本を使用すべきですか?または、データ交換形式に依存していません。ガイダンスが必要です。
Bhargav Jhaveri 2018

72

また、特にhttp apiを対象とするトークンベースの認証のための新たなオープンプロトコルであるOAuthもご覧ください。

これは、flickrが採用するアプローチと非常によく似ており、牛乳の「レスト」API覚えています(必ずしもレストフルAPIの良い例ではありませんが、トークンベースのアプローチの良い例です)。


3
しかし、ここで必要なのは2-legged oAuthであり、3-legged oAuthほどカバーされていない(情報がない)ようです。
redben 2010

4
OAuthは認証の委任に関するものです。つまり、情報/アカウントの所有者であるサービスAにサービスBのデータを操作させます(たとえば、TwitterにFacebookに書き込みを許可します)。それは、ユーザーがリソース(データ、情報、サービスなど)に対して実行できることを制御することに関する、広い意味での承認ではありません。ここでXACMLがステップインします。XACMLでは、だれが何を実行できるかに関する承認ポリシーを定義できます。
David Brossard 2013

60

Githubに優れたチェックリストがあります。

認証

  • 認証、トークンの生成、パスワードの保存で車輪を再発明しないでください。標準を使用します。

  • 使用Max Retryして刑務所にはログインしていただけます。

  • すべての機密データに暗号化を使用します。

JWT(JSON Webトークン)

  • ランダムな複雑なキー(JWTシークレット)を使用して、ブルートフォースによるトークンの強制を非常に困難にします。

  • ペイロードからアルゴリズムを抽出しないでください。バックエンドでアルゴリズムを強制します(HS256またはRS256)。

  • トークンの有効期限(TTLRTTL)をできるだけ短くします。

  • 機密データをJWTペイロードに保存しないでください。簡単にデコードできます。

OAuth

  • redirect_uriホワイトリストに登録されたURLのみを許可するには、常にサーバー側を検証してください。

  • 常にトークンではなくコードと交換してください(を許可しないでくださいresponse_type=token)。

  • ランダムハッシュで状態パラメーターを使用CSRFして、OAuth認証プロセスを防止します。

  • デフォルトのスコープを定義し、各アプリケーションのスコープパラメータを検証します。

アクセス

  • DDoS /ブルートフォース攻撃を回避するためにリクエストを制限する(スロットリング)。

  • サーバー側でHTTPSを使用してMITM(中間者攻撃)を回避する

  • HSTSSSLヘッダーを使用してSSLストリップ攻撃を回避します。

入力

  • GET(読み取り)、POST(作成)、PUT/PATCH(置換/更新)、およびDELETE(レコードを削除する)操作に応じて適切なHTTPメソッドを使用し405 Method Not Allowed、要求されたメソッドが要求されたリソースに適切でない場合に応答します。

  • リクエストAcceptヘッダー(コンテンツネゴシエーション)のコンテンツタイプを検証して、サポートされている形式(など)のみを許可しapplication/xml、一致しない場合はapplication/json応答で406 Not Acceptable応答します。

  • 検証content-typeポストされたデータのあなたは(例えば受け入れるようapplication/x-www-form-urlencodedmultipart/form-dataapplication/json、など)。

  • ユーザー入力を検証して、一般的な脆弱性(XSS、SQLインジェクション、リモートコード実行など)を回避します。

  • URLでは機密データ(資格情報、パスワード、セキュリティトークン、またはAPIキー)を使用しないでくださいAuthorization。標準のヘッダーを使用してください。

  • API Gatewayサービスを使用して、キャッシング、Rate Limitポリシー(割り当て、スパイクアレスト、同時レート制限など)を有効にし、APIリソースを動的にデプロイします。

処理

  • 認証プロセスの破損を防ぐために、すべてのエンドポイントが認証の背後で保護されているかどうかを確認してください。

  • ユーザー独自のリソースIDは避けてください。/ user / 654321 / ordersの代わりに/ me / ordersを使用します。

  • IDを自動インクリメントしないでください。代わりにUUIDを使用してください。

  • XMLファイルを解析する場合は、XXE(XML外部エンティティ攻撃)を回避するために、エンティティ解析が有効になっていないことを確認してください。

  • XMLファイルを解析する場合は、エンティティ展開が有効になっていないことを確認して、指数エンティティ展開攻撃によるBillion Laughs / XML爆弾を回避してください。

  • ファイルのアップロードにはCDNを使用します。

  • 大量のデータを処理する場合は、ワーカーとキューを使用してバックグラウンドでできるだけ多くの処理を行い、HTTPブロッキングを回避するために応答を高速で返します。

  • DEBUGモードをオフにすることを忘れないでください。

出力

  • X-Content-Type-Options: nosniffヘッダーを送信します。

  • X-Frame-Options: denyヘッダーを送信します。

  • Content-Security-Policy: default-src 'none'ヘッダーを送信します。

  • -指紋ヘッダを削除しX-Powered-ByServerX-AspNet-Versionなど

  • content-type応答を強制します。戻るapplication/json場合、応答のコンテンツタイプはapplication/jsonです。

  • 資格情報、パスワード、セキュリティトークンなどの機密データを返さないでください。

  • 完了した操作に応じて適切なステータスコードを返します。(例えば200 OK400 Bad Request401 Unauthorized405 Method Not Allowed、など)。


1
いいリストですが、少し意欲的です-そして、それは意味のない言い回しで始まります。Basic Authよりも標準的なyを取得することはできません。特に、クライアントがブラウザーではないAPI(ブラウザーの場合、JWTがより適切です)の場合は、その場所があります。一方、OAuthは、認証に他のすべての妥協案を使用しており、Basic AuthやJWTに実際には匹敵しません。
johndodo 2017

あなたHTTPSとしている権利、にBasicAuthが一般的ですが、それが熱く議論される- security.stackexchange.com/questions/988/...。とにかくこの点は削除します。
Andrejs

43

クライアント証明書を使用したSSLはまだ言及されていないので、ちょっと驚いた。確かに、このアプローチが本当に役立つのは、証明書によって識別されるユーザーのコミュニティを信頼できる場合だけです。しかし、多くの政府/企業がユーザーにそれらを発行しています。ユーザーはさらに別のユーザー名とパスワードの組み合わせを作成する必要はありません。IDは接続ごとに確立されるため、サーバーとの通信は完全にステートレスであり、ユーザーセッションは必要ありません。(言及された他のソリューションのいずれか/すべてがセッションを必要とすることを意味するものではありません)


実際には、これを一部の統合と暗号化されたVPNトンネルに使用して、https経由で通信できない制御できない古いシステムをサポートします。
ケーシー

負荷分散が必要な場合、クライアント証明書は問題を引き起こす可能性があります...それは可能ですが、それほど単純ではありません。
Jeremy Logan、

2
@fiXedd-クライアント証明書は本当にステートレスであるため、私の経験はクライアント証明書とは逆です。クライアント証明書で認証された接続は、クライアントとサーバー間で共有状態をまったく必要としないため、接続スティッキ性に関係なく、ダムロードバランサーで負荷分散できます。
stinkymatt 2012年

4
ああ、あなたはそれをすることができます...ロードバランサーにTCPトラフィックを転送させるだけですが、たとえば、ロードバランサーをSSLの終点にすることはできません。
Jeremy Logan

クライアント証明書とそのルート証明機関が自己署名されている場合でも、安全ですか?ルート認証局は、クライアントの信頼されたルート認証局にインポートされます。
ジョイス

38

これらの回答の誰もが、真のアクセス制御/承認を見落としました。

たとえば、REST API / Webサービスが医療記録のPOST / GETに関するものである場合、誰がデータにアクセスできるか、およびどのような状況でアクセス制御ポリシーを定義することができます。例えば:

  • 医師は、ケア関係にある患者の医療記録を取得できます
  • 誰も練習時間外に医療データを投稿することはできません(例:9から5)
  • エンドユーザーは、自分が所有する医療記録または保護者である患者の医療記録を取得できます
  • 看護師は、看護師と同じユニットに属する患者の医療記録を更新できます。

これらのきめの細かい承認を定義して実装するには、XACMLと呼ばれる属性ベースのアクセス制御言語、eXtensible Access Control Markup Languageを使用する必要があります。

ここでの他の標準は、次のものです。

  • OAuth:ID。承認のフェデレーションと委任。たとえば、サービスが別のサービスに代わって自分に代わって動作できるようにする(Facebookが私のTwitterに投稿できる)
  • SAML:IDフェデレーション/ Web SSO。SAMLは、ユーザーが誰であるかについて非常に重要です。
  • WS-Security / WS- *標準:これらはSOAPサービス間の通信に重点を置いています。これらはアプリケーションレベルのメッセージング形式(SOAP)に固有であり、メッセージングの側面(信頼性、セキュリティ、機密性、整合性、原子性、イベントなど)を扱います。アクセス制御をカバーするものはなく、すべてSOAPに固有です。

XACMLはテクノロジーに依存しません。Javaアプリ、.NET、Python、Ruby ... Webサービス、REST APIなどに適用できます。

以下は興味深いリソースです。


2
本質的に同じものであるユーザーと彼の権限を取得するトークンシステムを実装できないのはなぜですか?
スタン

トークンベースのアプローチを取ることができます。これもうまく機能しますが、ユーザーが取得するアクセス許可、つまりトークン内に挿入するアクセス許可を定義するロジックが必要です。これが、XACMLが実現するのに役立つものです。また、トークンの膨張を回避します。
David Brossard、2014年

2
補足として、「9から5」はセキュリティにどのような影響を与えますか?攻撃者が夜だけ活動しているように?まるで医師が「9から5」しか働かないかのように、深刻な使用の影響については言わないでください。
ローランド

これは、ヘルスケアシナリオの一般的な要件です。たとえば、HL7をチェックしてください。医師が営業時間外にアクセスする必要がある場合に備えて、ガラス破りのシナリオもあります。ハッカーに関しては、彼らがすべての賭けになったら、それは無効になります
David Brossard

1
私の同僚の何人かは実際にそれを調査しています。@SimplyGに感謝します。
デビッドブロ

25

私はOAuthを数回使用し、他のいくつかの方法(BASIC / DIGEST)も使用しました。私は心からOAuthを提案します。次のリンクは、OAuthの使用に関して私が見た中で最高のチュートリアルです。

http://hueniverse.com/oauth/guide/


これはOAuth 1.0に関連する非常に古い回答ですが、引用したリンクの作成者がOAuth 2.0についてこのことを述べたことは注目に値します。「OAuth 2.0は悪いプロトコルであるという結論に達しました... 1.0、2.0仕様はより複雑で、相互運用性が低く、有用性が低く、不完全であり、最も重要なこととして、安全性が低くなっています。」。明確に言うと、私が引用しているコメントは、回答を投稿してから数年後に作成されたものです。
skomisa

17

RESTに関連するセキュリティに関して私がこれまでに出会った中で最高の投稿の1つが1 RainDropで終わりました。MySpace APIはセキュリティのためにもOAuthを使用し、RestChessコードのカスタムチャネルに完全にアクセスできます。これはMixでデモされたもので、ここに投稿があります


それはREST vのSOAPに関連するセキュリティの非常に興味深い議論-リンク(1雨滴)のおかげで
ネイサン

15

素晴らしいアドバイスをありがとう。RESTful APIとMicrosoftの今後のZermatt Identityフレームワークを統合する準備として、カスタムHTTPヘッダーを使用してクライアントからサービスにIDトークンを渡しました。ここで問題とここでの解決策を説明しました。また、私はtweaktのアドバイスを受けて、RESTful Webサービスを購入しました。これは、あらゆる種類のRESTful APIを構築する場合に非常に優れた本です。


1
このアプローチは私には怪しげに聞こえます。攻撃者がIDトークンを使用してクライアントを偽装するのを防ぐものは何ですか?前回チェックしたとき、HTTPSはURLまたはヘッダーを保護しません...
Gili

2
うーん...あなたがそれについて正しいのかわかりません。どのような暗号化が必要かを理解するために必要ないくつかのヘッダーを除いて、他のすべてのヘッダーは暗号化されていると思います。
ネイサン、

51
それは間違いです。HTTPSはすべてを保護します。TCPハンドシェイク... TLSハンドシェイク... <ENCRYPTED> GET / foo 200 OK ... teardown </ ENCRYPTED>。
Mark Renouf、

1
トークンを(カスタムヘッダーの代わりに)Cookieとして渡すこともできます。これは、ほとんどのツールキットとアプリケーションで標準の動作をするHTTPヘッダーを使用するため、ブラウザーで適切に動作します。サービス側では、Cookieはセッションに関連付ける必要はありません。これを使用して、任意のトークンを通信できます。
Bruce Alderson

11
Wayback Machineは美しいものです。問題の説明解決策
cjc343 '23



6

私は安静なwsセキュリティについてたくさん検索しましたが、クライアントからサーバーへのCookieを介してトークンを使用してリクエストを認証することにもなりました。すでにDBにある指定されたセキュリティポリシーに基づいて各リクエストを認証および承認する必要があったため、サービスでのリクエストの承認にSpringセキュリティを使用しました。


6

SOAPの世界がセキュリティ標準でかなりカバーされているという事実は、それがデフォルトで安全であることを意味しません。そもそも、規格は非常に複雑です。複雑さはセキュリティのよい友ではありません。XML署名のラッピング攻撃などの実装の脆弱性は、ここでよく見られます。

.NET環境については、あまり役に立ちませんが、「JavaでWebサービスを構築する」(10人程度の作者によるブリック)は、WS- *セキュリティアーキテクチャ、特にその癖を理解するのに大いに役立ちまし


4

REST自体にはセキュリティ標準がありませんが、OAuthやSAMLなどが急速にこの分野の標準になりつつあります。ただし、認証と承認は、考慮する必要があることのほんの一部です。Webアプリケーションに関連する既知の脆弱性の多くは、REST APIに非常に当てはまります。入力の検証、セッションのクラッキング、不適切なエラーメッセージ、内部の従業員の脆弱性などを考慮する必要があります。大きなテーマです。


4

追加したい(stinkeymattに合わせて)、最も簡単な解決策は、SSL証明書をサイトに追加することです。つまり、URLがHTTPS://であることを確認してください。それはあなたのトランスポートセキュリティをカバーします(ドルのための強打)。RESTful URLを使用すると、(WS *セキュリティー/ SAMLとは異なり)シンプルに保つことができ、oAuth2 / openID接続または基本認証(単純な場合)を使用できます。ただし、SSL / HTTPSは引き続き必要です。ここでASP.NET Web API 2のセキュリティを確認してください:http : //www.asp.net/web-api/overview/security(記事とビデオ)


3

@NathanはどちらがシンプルなHTTPヘッダーであるかを示し、一部のユーザーはOAuth2とクライアント側のSSL証明書を言っていました。その要点はこれです... REST APIは実際にはAPIのスコープ外であるため、セキュリティを処理する必要はありません。

代わりに、Webプロキシの背後にあるHTTPヘッダー(SiteMinder、Zermatt、またはApache HTTPdのような一般的なアプローチ)であるか、OAuth 2のように複雑であるかに関係なく、セキュリティ層をその上に置く必要があります。

重要なことは、エンドユーザーの操作なしでリクエストが機能することです。必要なのは、REST APIへの接続が認証されていることを確認することだけです。Java EE userPrincipalでは、で取得できるの概念がありHttpServletRequestます。また、URLパターンが安全であるため、REST APIコードでチェックする必要がないこともデプロイメント記述子で管理されます。

WCFの世界ではServiceSecurityContext.Current、現在のセキュリティコンテキストを取得するために使用します。認証を要求するようにアプリケーションを構成する必要があります。

上記のステートメントには例外が1つあります。それは、ナンスを使用してリプレイ(攻撃または誰かが同じデータを2回送信するだけ)を防ぐことです。その部分は、アプリケーション層でのみ処理できます。


3

Webアプリケーションセキュリティについては、さまざまなセキュリティ攻撃のチートシートを提供するOWASP(https://www.owasp.org/index.php/Main_Page)をご覧ください。アプリケーションを保護するために、できるだけ多くの手段を組み込むことができます。APIセキュリティ(承認、認証、ID管理)に関しては、すでに述べたように複数の方法があります(基本、ダイジェスト、OAuth)。OAuth1.0にはループホールがあるため、OAuth1.0aを使用できます(OAuth2.0は、仕様の関係上、広く採用されていません)。


2

久しぶりですが、質問はまだ関連性がありますが、答えが少し変わった可能性があります。

API Gatewayは、柔軟で高度に構成可能なソリューションです。私はKONGをかなりテストして使用し、私が見たものを本当に気に入りました。KONGは、ユーザーの管理に使用できる独自の管理REST APIを提供します。

Express-gateway.ioはより新しいAPIゲートウェイでもあります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.