OAuth 1.0 required cryptographic signatures be sent with each API request to verify the identity and authorization of the client. Cryptography is challenging for the casual developer to grasp and also challenging for even highly skilled engineers to master. This led to plenty of developer frustration and, presumably, less adoption of APIs than could have been achieved with an easier authorization protocol.
When OAuth 1.0 was developed in 2007, it was decided that cryptographic signatures were necessary to support the security of APIs. At the time, many top API providers hosted their APIs at vanilla HTTP endpoints, without SSL/TLS protection. Over the years, SSL/TLS became a more common way of protecting APIs and the need for signatures decreased in the eyes of some members of the security community.
Combining the perception of low API adoption due to the complexity of cryptography in OAuth 1.0 and the greater prevalence of SSL/TLS support for APIs led to the development of the OAuth Web Resource Authorization Profiles (WRAP) specification. OAuth WRAP is the predecessor to OAuth 2.0—it eliminated the complex signature requirements and introduced the use of bearer tokens.
Even as OAuth 2.0 nears finalization in the standards community, there remains some strong individual opposition to not requiring the use of signatures, including by Eran Hammer-Lahav, the editor of the specification. Eran has written a blog post titled OAuth 2.0 (without Signatures) Is Bad for the Web, in which he acknowledges the complexity of signatures for some developers but defends their value. He mainly points out that removing signatures from OAuth 2.0 makes it easy for developers to make mistakes and accidentally send their credentials to a malicious API endpoint, which can then abuse these credentials to make additional requests because they’re not protected by a signature. While he argues that this isn’t likely today, he does believe it will become more critical as automated discovery is added for API and OAuth endpoints. Others identify cryptographic signatures as a feature that allows for greater confidence in the origin of API requests as the requests pass through multitiered architectures.
Engineers often have to strike a delicate balance between security and usability, and this case is no different.
One of the primary concerns with the elimination of signatures is that developers will not properly verify SSL/TLS certificate chains when making requests to the authorization and resource servers. This is required by the specification and addressed in the OAuth 2.0 threat model document, but the ease of disabling proper certificate and certificate authority validation in popular libraries, combined with the difficulty of fixing issues associated with it, has resulted in many developers taking shortcuts that threaten the security of their applications.
When implementing OAuth 2.0, calling any APIs, or using a library, you should verify that it properly handles SSL/TLS certificate chain validation by doing the following things:
Checking that the hostname on the certificate returned by the server matches the hostname in the URL being accessed
Verifying each certificate in the chain properly chains up to a valid and trusted certificate authority (CA)
Ensuring that the certificate authority bundle on your server is secure and not able to be modified by potential attackers
The MAC Access Authentication specification defines how clients can sign their OAuth 2.0 requests when signatures are supported or required by the API provider.
Author’s Note: If you’re thinking MAC only refers to a type of computer, you can understand why signatures are hard for many developers! You might want to find a good book on cryptography.
In order to sign requests using MAC authentication, the client
must first get a MAC key. This can be issued by the OAuth
authorization server. In this case, the key is returned each time an
access_token is returned by the
authorization server. This MAC key must be for use in either the
hmac-sha-1 or hmac-sha-256 algorithms. Alternatively, the MAC key can
be issued in an out-of-band process, such as when the developer
registers their application with the API provider. Regardless of how
the key is issued, it must always be issued over a secure SSL/TLS
channel and must be kept confidential.
When connecting to OAuth-enabled APIs that require signatures,
each API request must include a MAC signature in the
Authorization header of the request. The
process of generating this signature involves creating a normalized
request string (nonce, HTTP method, request URI, host, port, optional
body hash, etc.) and performing a cryptographic signature. It is
highly recommended that developers use a prebuilt library to handle
OAuth MAC signing if needed. If you need to build your own
implementation, please see the specification,
as the details are out of scope for this book.