OAuth 1.0 のほうが OAuth 2.0 より安全なの？

# **1. OAuth 2.0 and the Road to Hell**

OAuth 1.0 と OAuth 2.0 の違いを調べていると、そのうちに「[OAuth 2.0 and the Road to Hell](http://hueniverse.com/2012/07/26/oauth-2-0-and-the-road-to-hell/)」(by Eran Hammer氏) という文書にたどり着きます。この文書は、OAuth 仕様策定作業で精力的に頑張っていた方が OAuth 2.0 を批判して怒りの脱退宣言をするという衝撃的な文書です。

「OAuth 2.0 は OAuth 1.0 よりも安全ではない」というのが彼の一番の主張です。そのため、OAuth サーバーの実装を検討している人がこの文書を読むと、OAuth 2.0 の採用をためらい、OAuth 1.0 の方を選択してしまうことがあります。

実際、[Open Bank Project](https://openbankproject.com/) というプロジェクトの実装である [OBP-API](https://github.com/OpenBankProject/OBP-API) では、[Wiki](https://github.com/OpenBankProject/OBP-API/wiki) で次のように述べて、OAuth 1.0 の採用を高らかに宣言しています。

> We're sometimes asked about OAuth 1 and 2. So far **we stick with OAuth 1.0a** because it's stable ([RFC](https://tools.ietf.org/html/rfc5849)) is used by the likes of Twitter and Mastercard and according to the lead author of OAuth is more secure than OAuth2. For more info, see [OAuth 2 and the road to hell](http://hueniverse.com/2012/07/26/oauth-2-0-and-the-road-to-hell/) or [this stack overflow article](http://stackoverflow.com/questions/4113934/how-is-oauth-2-different-from-oauth-1)

上記の引用文中に OAuth 1.0a という a 付きの OAuth 1.0 が出てきて、どれが新しい仕様なのか分かりにくいですが、[RFC 5879](https://tools.ietf.org/html/rfc5849) の [Introduction](https://tools.ietf.org/html/rfc5849#section-1) によると、順番は次のとおりです。

| 策定月 | 仕様 |
|:--|:--|
| 2007 年 12 月 | [OAuth Core 1.0](http://oauth.net/core/1.0/) |
| 2009 年 6 月 | [OAuth Core 1.0 Revision A](http://oauth.net/core/1.0a/) |
| 2010 年 4 月 | [The OAuth 1.0 Protocol](https://tools.ietf.org/html/rfc5849) &nbsp; (RFC 5849) |

以降、OAuth 1.0 は RFC 5849 を指すものとします。


# **2. 実際のところはどうなのか？**

では「実際のところはどうなのか？」というのは、一次ソースを見ないと正確には分からないので、[RFC 5849](https://tools.ietf.org/html/rfc5849) を改めて読み直してみました。

分かったことは、私の解釈が間違えていなければ、**OAuth 1.0 のセキュリティーは「クライアントアプリケーションに埋め込まれている秘密鍵 <sup>※1</sup> は盗み取られない」という前提に立っている**ということです。しかしながら、この前提はナイーブです。

&nbsp; &nbsp; &nbsp; <sup>※1: ここで秘密鍵 (secret key) とは、シグネチャーの計算に [HMAC-SHA1](https://tools.ietf.org/html/rfc5849#section-3.4.2) を使うのであれば共有鍵 (shared key)、[RSA-SHA1](https://tools.ietf.org/html/rfc5849#section-3.4.3) を使うのであればプライベート鍵 (private key) を指します。</sup>

OAuth 2.0 ([RFC 6749](https://tools.ietf.org/html/rfc6749)) では、このようなナイーブな前提に立つクライアントアプリケーションのことを「confidential クライアント」と呼んでいます。一方、秘密鍵を秘密にしておくことが難しい環境に置かれているクライアントアプリケーションのことは「public クライアント」と呼んでいます。スマートフォンアプリケーションや Web ブラウザーで動くアプリケーションは、public クライアントに分類されます。これらのクライアント種別については、RFC 6749 の [2.1. Client Types](https://tools.ietf.org/html/rfc6749#section-2.1) に記述されています。

このような意味において、OAuth 1.0 は、confidential クライアントのみを対象にした仕様と言えます。

「[OAuth 2.0 and the Road to Hell](http://hueniverse.com/2012/07/26/oauth-2-0-and-the-road-to-hell/)」では OAuth 2.0 は OAuth 1.0 よりも安全ではないと言っていますが、OAuth 1.0 クライアントと OAuth 2.0 confidential クライアントの間には、そのセキュリティーレベルにおいて実質的な違いはほとんどありません。OAuth 1.0 はシグネチャーの計算を要求しますが、既に秘密鍵を秘密に保っておけることが保証できているのであれば、シグネチャーによってセキュリティーがより高められるということはないでしょう。ある意味、シグネチャーの計算は、実質的なセキュリティー向上を伴わないただの面倒くさい計算にしか過ぎません<sup>※2</sup>。 ・・・語弊があるので補足しますと、あれほど厄介な署名処理であるにも関わらず、OAuth 2.0 の confidential クライアントが TLS で接続して `client_id` と `client_secret` を提示するだけで済んでいることと比べ、セキュリティー的により良くなっているわけではない、という意味です。

&nbsp; <sup>※2: だから OAuth 2.0 からはシグネチャーの計算がドロップされたのでは？と個人的には思っています。実際に行われた議論については知りませんが。</sup>

加えて、[RFC 5849](https://tools.ietf.org/html/rfc5849) (OAuth 1.0) では、[RFC 6749](https://tools.ietf.org/html/rfc6749) (OAuth 2.0) が言及している[オープン・リダイレクター](https://tools.ietf.org/html/rfc6749#section-10.15)について何も言及していません。つまり、もちろんサーバーの実装によりますが、OAuth 1.0 の `oauth_callback` パラメーターはセキュリティーホールになりえます。

上記の私の見解については、[Stack Overflow にコメント](http://stackoverflow.com/a/35775049/1174054)してありますので、よろしければ Upvote をお願いします。

# **3. OAuth の未来**

[RFC 6749](https://tools.ietf.org/html/rfc6749) (OAuth 2.0) の Abstract には下記の引用にあるように、「この仕様は OAuth 1.0 を置き換え、廃止するものである」と書いてあります。

> The OAuth 2.0 authorization framework enables a third-party application to obtain limited access to an HTTP service, either on behalf of a resource owner by orchestrating an approval interaction between the resource owner and the HTTP service, or by allowing the third-party application to obtain access on its own behalf.  **This specification replaces and obsoletes the OAuth 1.0 protocol described in [RFC 5849](https://tools.ietf.org/html/rfc5849).**

また、[RFC 5849](https://tools.ietf.org/html/rfc5849) (OAuth 1.0) の HTML 版の先頭には、次のように「6749 により廃止」と書かれています。

> **Obsoleted by: [6749](https://tools.ietf.org/html/rfc6749)**

そのため、OAuth 関連の追加仕様は、OAuth 1.0 ではなく OAuth 2.0 を中心に作られていきます。

例えば、スマートフォンアプリケーションがリダイレクト URI にカスタムスコープを使っている場合に起こりうる「認可コード横取り攻撃 (authorization code interception attack)」の対応策は [RFC 7636](http://tools.ietf.org/html/rfc7636) (Proof Key for Code Exchange by OAuth Public Clients) ([図解](https://www.authlete.com/documents/article/pkce)) として策定されましたが、その仕様の Abstract は「OAuth 2.0 public clients utilizing...」という書き出しとなっており、OAuth 2.0 を前提とした仕様であることが分かります。OAuth 1.0 に対しては、このようなセキュリティー仕様が追加されることはないので、コールバック URL にカスタムスコープを使用している OAuth 1.0 スマートフォンアプリは、認可サーバーが独自仕様を策定・実装しない限り、認可コード横取り攻撃に対して脆弱性を抱えたままとなります。

# **4. 結論**

上記のような理由から、「OAuth 2.0 は OAuth 1.0 よりも安全ではない」とは言えないでしょう。むしろ、OAuth 1.0 でクライアントアプリケーションを作る方こそ安全ではないと思います。そういうわけで、OAuth 1.0 ではなく OAuth 2.0 を採用するのが良いでしょう。