REST APIについて3回のシリーズで解説します。本日は第2回目をお届けします。

第1回目の記事では、RESTful APIのセキュリティに関する課題をおおまかに説明しました。今日は、さらに詳しく掘り下げていきたいと思います。

まず、RESTがAPIのセキュリティに及ぼす影響をいくつか説明しましょう。

HTTP/Sの使用:RESTによるマシン間通信では、CORBA、Webサービス、RPCといった複雑なテクノロジではなく、シンプルなHTTPが使用されます。一部のAPIはHTTPSしかサポートしません。その結果、RESTfulサービスはアプリケーション層に存在するセキュリティ脆弱性の影響を受けることになります。これは、従来のWebアプリケーションが長年直面してきた課題(OWASP Top 10など)です。

HTTPメソッドを使ったCRUD:RESTベースのサービスは、CRUD(Create/Read/Update/Delete)オペレーションを、HTTPメソッド(PUT/GET/POST/DELETE)にそれぞれマッピングします。RESTでは、メソッドをリソースに限定する(/catalogではDELETEを実行しない、など)ことが設計上重要なポイントになっているのですが、正しく実装されないことがあります。これが、予期しない結果を招く恐れがあります。

VBAAC:一部のRESTフレームワークでは、VBAAC(Verb Based Authentication and Authorization Control:動詞ベースの認証および権限管理)が意図的に実装されています。このフレームワークでは、アクセス制限が各HTTPメソッド(動詞)に紐付けされています。たとえば、/adminへのGETとPOSTを特定のユーザのみに割り当てることで、そのユーザのみが実行できるようにします。ところがこのような実装では、ほとんどの場合セキュリティを確保できません。

XMLおよびJSONによるデータ交換:RESTでのデータ交換では、一般的にパラメータ、要求、応答の本文でJSONとXMLのいずれかを使用します。このデータは、バックエンドサービスやユーザのブラウザで使用されます。データを使用するには、データ形式を処理できる特殊なパーサが必要になり、さらには、悪意のある入力データからデータ形式を保護するセキュリティテクノロジが必要になります。

URLパスでのユーザ入力:一般的なHTTPはURLクエリやFORMで入力パラメータを渡すのに対して、RESTはさまざまな方法でパラメータを渡すことができます。たとえば、URLパスを使用する方法や、JSONやXMLをPOST要求本文で渡す方法があります。次に、ユーザの電話帳データを取得する要求の記述例(参照元はこちら)を示します。上から順に、従来のHTTPサービス、REST/JSONサービス、SOAPサービス(比較のため)です。わかりやすいように、UserIDパラメータを赤色で示しています。

GET /phonebook?action=GetUserDetails&UserID=12345 HTTP/1.1

HOST: www.acme.com

JSON/RESTの例:

GET /phonebook/UserID/12345 HTTP/1.1

HOST: www.acme.com

SOAP/Webサービスの例:

<?xml version="1.0"?>

<soap:Envelope

xmlns:soap="http://www.w3.org/2001/12/soap-envelope"

soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">

<soap:body pb="http://www.acme.com/phonebook">

<pb:GetUserDetails>

<pb:UserID>12345</pb:UserID>

</pb:GetUserDetails>

</soap:Body>

</soap:Envelope>

SOAP要求と比較すると、JSON要求が格段に軽量であることがわかります。

プログラムによるアクセスと「チャッティ」な特性

当然ながら、APIへのアクセスにはプログラムを使用します。また、RESTfulアプリケーションには「チャッティ」という特性があります。Webサービスでは階層構造を持つ複雑な情報が返されますが、RESTfulサービスでは、細分化されたオペレーションによってリソースに関するシンプルなデータが返されます。つまり、RESTでは必要な情報を高い精度で取得できるというメリットがある一方で、Webサービス/アプリケーションと同程度の情報を取得するには何回も呼び出しを実行しなければなりません。

RESTのセキュリティ保護の課題

従来のスキャナを使ったWebアプリケーションテストや侵入テストはなぜ、RESTへの対応に四苦八苦しているのでしょうか。理由をいくつか説明します。

攻撃対象(URL領域)を特定しにくい

従来のHTTPアプリケーションの場合、Webアプリケーションスキャナは、ページソース内でリンクされたURLを反復的にフェッチすることでURL領域全体をクロールすることが可能です。これに対してREST APIは、リソースとトランザクションオペレーションをAPI上で公開し、しかもほとんどのアプリケーションはサブセットのみを使用するので、URL領域全体と攻撃対象を特定する作業は困難になります。

Lack of out-of-band API metadata to guide

アウトオブバンドのAPIメタデータがない

When testing web services, scanners typically make use of WSDLs to determine the URLs and parameters, which makes fuzz testing easy. However, REST principals discourage such out-of-band schemas metadata.

Webサービスのテストでは、スキャナはWSDLを使用してURLとパラメータを特定するのが一般的であり、これによってファズテストを簡素化できます。ところがRESTでは、原則的にこのようなアウトオブバンドのスキーマメタデータは使用されません。

Hard to Determine Navigation Paths and User Input Locations

ナビゲーションパスとユーザ入力の発生場所を特定しにくい

Determining URL spaces is further complicated by the fact that REST often uses URL paths for input parameters, which could be injected with malicious data.

For example:

RESTでは、入力パラメータにURLパスを使用することが多いという点もURL領域の特定を難しくしている原因です。しかもURLパスは、悪意のあるデータのインジェクションに使用されることがあります。

次に例をあげます。

https://www.example.com/api/phonebook/UserID/12345

パラメータの名前(UserID)と値(12345)がURLパスで指定されています。これはRESTでよく使用される手法ですが、自動テストツールでは処理できません。ツールは、これを「ディレクトリ」として処理するべきか、パラメータとして処理するべきか迷ってしまうのです。

動的に生成されるURL

RESTベースのサービスは、共通のデザインパターンとしてAJAXを使用することがあり、特にインタラクティブなフロントエンドで多用されます。このサービスでは、クライアントでURLが動的に生成されます。したがって、応答コンテンツをパースしてURLとインジェクションポイントを検出するだけでは不十分です。脆弱性スキャナ(さらに大手検索エンジン)では、このようなコンテンツのクローリングは困難になります。

テストサイクルが長くなる

入力が長い場合、RESTベースのアプリケーションは、POST要求を使って複数のキー/値ペアを含むJSONまたはXMLデータを処理します。このようなデータをすべてテストするとなると、テストデータは膨大になり、ファズテストにかかる時間はかなり長くなってしまいます。

シリーズ3回目の次回は、このようなRESTセキュリティの課題を解決する上で、Barracuda Web Application Firewallが果たす役割を解説します。

※本内容はBarracuda Product Blog 2015年7月9日The Challenges in Securing REST APIsを翻訳したものです。

Neeraj Khandelwal

本稿は、バラクーダネットワークスのWebサイトに掲載されている『バラクーダラボ』7月23日付の記事の転載です。