Saturday, April 9, 2016


OAuth - Why it doesn't work, and how to Zero-day attack existing services



Since this article is extremely long, it is also available in a PDF version. This article also has a companion website.

 Intro

What is OAuth?

Let me begin with a quick run down on what we're discussing. OAuth is a family of proposals that is being used for designing different kinds of authorization and authentication systems, and framing the usage for APIs and how different systems are integrated.

OAuth exists in many flavors, version 1, 1a, 2, and other specifications based on top of parts of it. Its exact usage also greatly differs across the many different implementations out there.

Disclaimer

I've written about OAuth in the past, and I've gotten a lot of feedback from readers all over. To avoid some criticism my past article received, I'd like to point out that this article will be focusing on how OAuth is typically used, and most of the points discussed here are true of nearly every major service which leverages OAuth in some way.

To put this differently, not every platform utilizing OAuth is necessarily broken. Due to the various flavors of OAuth, and the 76-page document on different possibilities with OAuth 2.0, it is possible to create something secure and sane to use which conforms to something OAuth based. Therefore your favorite flavor and design with OAuth may escape some or all of the problems discussed herein, even though the odds are that it does not.

Some of you may also argue that some things done with OAuth are misusing the specifications, or that OAuth doesn't specifically mandate things be done the way they are. Whatever the case may be, I'm not here to write about a particular OAuth based specification, but how OAuth is currently utilized by major players in the market, regardless if what these organizations are doing conforms with the specifications or not. This will impact many readers, either because they use services making use of OAuth in these ways, or they're maintaining OAuth-based services, and are building platforms similarly to how many others are building them.

Article structure

This article is going to be a long one, and in fact most sections in this article cover topics with enough material to make an entire article themselves, so let me give a brief outline on what this article is about and how it will be organized.

This article is the presentation of the culmination of research into what is currently being done in the market with OAuth. Not everything in this article is consistent with every product making use of OAuth, but this article will present what was found to be common practice and the biggest culprits behind insecure or useless services.

After this introduction, I'm going to begin by analyzing security flaws with OAuth. The general principles behind some of these flaws are well known by those in the security community, and already briefly analyzed in existing publications. However, I'm going to be covering some cases that have not yet been publicized, and also elaborating upon some points of well known flaws to make them easier to understand to the average developer or manager and emphasize why they need to be concerned.

After that I'm going to present an analysis of how some key components of OAuth are popularly implemented and how the popular implementations cripple services which choose to use OAuth by severely, inappropriately, and undesirably limiting what can be accomplished with them. Some techniques will be discussed that can be used as the basis for workarounds in a limited amount of cases, with a focus on the absurdity involved in implementing such. As part of the above, it will be frequently pointed out how those using OAuth are hurting themselves and their business.

Lastly I will briefly cover a few cases for when and how OAuth can be used properly, along with viable alternatives to OAuth which are currently in use. I will provide a survey of alternative techniques that will include what serious companies like Amazon and others are doing to achieve secure, usable, and reliable APIs.

Responsible Disclosure

Several of the flaws with OAuth as is it popularly used today can be exploited to carry out strong attacks against major services. Attacks against OAuth are nothing new, as IBM, Oracle, and other concerned members of the IETF issued a 71-page document describing 50 classes of attacks against OAuth based services over three years ago, and I already discussed some of these points in my previous article. Despite this though, major security flaws with OAuth-based systems are extremely common.

I've spoken to executives and developers at several major corporations to point out security flaws with their OAuth-based systems (in one case, 4 years ago), and not one of them has done anything to fix their systems. It seems as though, given the popularity of OAuth, they haven’t heard of any of the alternative viable solutions, and they therefore assume that OAuth must be the most secure thing available. It also seems as if they either have not heard or shrug off the information documenting the demonstrated attacks against the core principals of OAuth. I'm hoping that wider public dissemination of this information will give those affected the proper kick in the pants that they need, and serve as a wake up call to those designing or maintaining services.

Therefore, if you investigate and find that some or all of these flaws exist in your service which either provides or makes use of something OAuth-based, please act responsibly in dealing with this information. Update your services appropriately, or apply appropriate pressure to your business partners to address the relevant issues.

Although the various information mentioned here and linked to from here can be used to exploit existing services today, please be responsible and aim to improve and not destroy what belongs to others. This article is meant as a wake up call for those implementing their services improperly and an appeal to improve them, not a how-to guide for hackers looking to exploit them.

Usage Scenarios

For this article, I'm going to focus on two usage scenarios and see how OAuth stacks up with them and why it doesn't work. It is important to keep these scenarios in mind, as I will be constantly returning to them throughout this article.

Let us imagine an Exciting Video Service (or EVS), where users can upload videos and share those videos with their friends, providing either public or restricted access to their uploads. EVS also provides OAuth-based APIs for uploading and deleting videos, and managing permissions regarding who can view those videos.

While I will be focusing on this imaginary service for sake of example, the issues under discussion will apply to any service, whether it's for file and document storage, calendar management, online meetings, discussion groups, resource management, or anything else that provides an OAuth-based API. Also bear in mind that I'm not actually referring to any specific video service, even though some or all of these issues may apply to existing video services which make use of OAuth. It can be left as an exercise for the reader to determine which ones.

For our first usage scenario, let us imagine a camcorder manufacturer that would like to supply software with their camcorder which, among other things, allows videos recorded with the device to be uploaded to EVS. It is intended to allow users of this camcorder to plug their device into their computer, open the custom software, select the videos on the device they'd like to upload, and come back later knowing that all the selected videos will have been uploaded to EVS.

For our second scenario, let us imagine a small organization decides to purchase 50 accounts with EVS for their employees, so all employees can upload videos and have them shared with other employees from the same department. This organization is using A Friendly Custom Platform, for managing their employees and which sub-units they belong to, and would like to integrate their AFCP service with EVS. This organization will expect that when a manager assigns someone to the sales department using AFCP that the employee in question will automatically gain access to all videos that belong to members of the sales department. They will expect the reverse to occur if they remove someone from the sales department, and all similar scenarios.

The Issues

Security Related

Stealing credentials / Gaining elevated access

One of the most popular reasons why token-based authentication systems (a core premise of OAuth) are currently used is that when implemented properly they avoid the need to provide third party applications and services with individual users’ credentials. It is undesirable to provide third parties with personal user credentials, because:
  • It gives third parties more access than they require.
  • It is another place personal credentials are stored and can be stolen from.
  • It requires that API consumers be updated when users change their credentials.
  • Access cannot be easily revoked from just one application without also revoking access from all other applications.
  • User credentials can be too limited where additional authentication factors are in use.
The above list of problems can be avoided by any token-based authentication system, not just OAuth. While this is counted as a strength to OAuth, it is hardly unique, and viable alternatives can be used which carry the same strengths without OAuth’s weaknesses.

However, despite being based on a solid premise, OAuth as popularly implemented attempts to avoid the above problems by providing a system with something along the lines of the following steps:
  1. Users visit the third party application/service such as AFCP and informs it of their desire to integrate a particular service.
  2. AFCP then brings up a special login page hosted by EVS where the user enters their EVS credentials.
  3. EVS then asks the user to confirm they are sure they want the third party application/service, AFCP, to have all the levels of access specified.
  4. EVS then provides AFCP with some kind of token or series of tokens it can then use to make the various API calls.
Since these tokens are not the user's credentials, and can be specific to every user and application combination, limited in their permissions, and later revoked, it seemingly avoids all the aforementioned problems this setup was designed to address. However, in reality, despite having a sound premise at its core, this particular usage flow used by popular implementations of OAuth does not address all the above enumerated issues.

This design begins from an insecure standpoint. The rule of thumb when it comes to designing a secure platform is that anything which begins from an insecure standpoint is already lost, it cannot be salvaged. Thanks to step #1, which begins on a service making use of EVS rather than EVS itself, users have already been man-in-the-middled from the very beginning. This is the computer-system equivalent of giving out personal or financial information over the phone to an incoming caller who claims to be from some utility service you use but whose number you either do not recognize or is blocked. There have been many such scams in recent times, and don’t need to be elaborated upon here. The main point is that if you cannot trust the party which initiated a connection, then you cannot trust the connection at all. It is impossible to design a secure authentication system for API use which achieves the objectives enumerated above unless the first step begins from the EVS side itself.

Similar to the phone scam example, where the caller simply needs to sound as if they are calling from the company they’re impersonating, to attack a user, a third-party application or service just has to provide something which looks like the special EVS login page for step #2. Most users will not be aware that the page displaying the EVS logo and asking for their username and password is not authentically from EVS. Once a third-party service gains the user’s credentials in this manner, the application or service, and those behind it, now have more access than they should, and their access cannot be revoked without the user changing their credentials.

Since users have already been conditioned with OAuth-based login flows with all kinds of embedded frames with corporate logos, silly pop-ups, and redirects with ridiculous URLs on atypical domains, most users won’t even notice any red flags which would alert them that the page into which they’re currently entering their credentials may not be genuine. A colleague of mine put it so: The companies themselves are training their users to be phishing targets. If URLs are needed to be displayed, the attacker can even register an official sounding domain (microsoft-authentication.us, ibm-secure.co.uk, gooogleauth.us, my-citrix.au, globalauth.world) and can even have redirection go through some URL which appears to be legit.

In the case of actual standalone applications, such as that provided with your camcorder, nothing outrageous even needs to be done. Since the web browser is being provided by a custom application, it can already capture every single input box and all data sent over the network with it, it doesn't even need to spoof some login form.

This class of attack is labeled in the aforementioned security document as 4.1.4. Threat: End-User Credentials Phished Using Compromised or Embedded Browser. The solutions offered? (emphasis mine)
Client applications should avoid directly asking users for their credentials. In addition, end users could be educated about phishing attacks and best practices, such as only accessing trusted clients, as OAuth does not provide any protection against malicious applications and the end user is solely responsible for the trustworthiness of any native application installed.
Also:
Client developers should not write client applications that collect authentication information directly from users and should instead delegate this task to a trusted system component, e.g., the system browser.
Essentially OAuth security guidelines say that developers making use of OAuth should not try to attack the users or do anything malicious. Relying on external developers not to do anything malicious is not a security model any sane service designer would rely on.

Nearly every major OAuth-based service I know of can be attacked with the method outlined here.

For those of you thinking OAuth is the new gold-standard for security, wake up! OAuth as popularly implemented is already defeated before it has begun. Many systems implemented way before OAuth ever existed are secure and work around this issue effectively. Unfortunately, and all too often, I’ve seen services transition themselves from something secure to an insecure OAuth model because someone told their developers or managers that OAuth was “more secure”, “forward thinking”, “future proof”, or any number of other buzzwords which sound nice but lack anything in the way of substance. Most of the time these changes are implemented without even reviewing whether these changes address any existing problems or if the solution is any better than what they are replacing.

Masquerading as an OAuth-using service

A common mistake I see in OAuth-based service design is the supplying of an endpoint designed for a web browser which accepts as one of its parameters a client_secret (or something of the same concept). The OAuth client_id and client_secret parameters are essentially a third-party platform’s equivalent of its own personal API username and password, and should therefore only be known to those developers making use of EVS's APIs. Since it is analogous to a password, the client_secret parameter should never be sent across a user’s web browser (hint: the word secret is in the name of the parameter). If some user of an application or service can find out the client_id and client_secret of the application or service, that means they can masquerade as that service and potentially do something malicious. Also note that some services will sometimes name the client_secret parameter something else, so review the service you are working with carefully and see if any of their other parameters need to be kept secret. Unfortunately, since important variables are sometimes not indicative of their nature, this problem is more common than it should be. Additionally, some services will build an authentication flow on top of OAuth using the client_id alone. Be wary of these, because under certain circumstances such a client_id functions exactly like a client_secret.

Since OAuth as popularly implemented transfers users between multiple websites using a web browser, and that OAuth needs one website to send the other a client_id and client_secret (or equivalent), such as between AFCP and EVS, these are actually available to the user of the web browser if they monitor the browser's HTTP log. This is even possible in various custom browsers built into applications where a simple right click allows access to an inspector of some sort with network logging capabilities.

In our case of AFCP utilizing EVS, this flaw would allow employees which have some access to AFCP to potentially gain more access than they should, and perhaps apply permissions they should not have access to. In a different example, if Facebook made use of an OAuth endpoint via a web browser for GMail where both the client_id and client_secret were transferred through the web browser, this would allow every user of Facebook to impersonate Facebook itself in this regard.

This issue is present any time an OAuth endpoint expects to be sent the client_secret in plain text via a user’s web browser, or the API consumer is mislead into thinking doing so is a requirement and embeds a secret where they should not. A good indication that this vulnerability may be present is an endpoint where both the parameters for client_secret (or equivalent) and redirect_uri are expected (or even optionally allowed). The redirect_uri parameter is designed specifically for browser use to indicate to EVS where to send the user's browser after the login actions have been performed on the EVS side. As such, it means that if redirect_uri is in use for transferring on an endpoint, the flow is expected to be performed via the user’s web browser. Neither of the major OAuth documents specify or call for the use of such a case where both the parameters for client_secret and redirect_uri are expected to be used like this.

A quick search online of such potentially offending OAuth-based APIs unfortunately shows many hits. Although Google offers many ways to use OAuth, they have a flow which advertises the two being used together:

 Citrix makes this mistake:

Along with Cisco:


So does Github:

And Salesforce:

As well as Buffer:


And Zendesk:


And the popular Disqus:

I got this list after searching with Google for only two minutes. I'm sure readers can find many more with a little more effort. Note, the above list is not an indication that any of these services are directly vulnerable or that it's too easy to misuse them. Due to various factors, where for example, Zendesk specifically says their redirect_uri parameter is not actually used for redirection in this particular case, and that they even show that the endpoint should be called from an application using curl - not a full fledged web browser, developers will hopefully not be misled into trying to do something dangerous with it. However, inexperienced developers in their applications may try to load one of these endpoints with a custom web browser. Furthermore, this combination simply being common in the wild is lowering developer's defenses against a potentially nasty misuse, where even the more experienced developers of OAuth-based services are blindly applying in similar situations, especially where the client_secret is named something else and the idea of keeping a secret is lost on them.

A good indication that a service is broken in this regard is when several popular OAuth libraries fail to work with this service. Such services will generally offer their own "SDK" which will work with them, and point third party developers to the official SDK if they complain their favorite library is unable to make use of their frankenstein-OAuth. These kinds of customizations often goes unnoticed, as the majority of developers prefer to make use of an advertised SDK when provided, and forgo rolling their own combination of software to utilize a service.

This class of attack is labeled in the aforementioned security document as 4.1.1. Threat: Obtaining Client Secrets. However, it doesn't even mention the specific attack case where a server is requiring use of a web browser for passing both the client_id and client_secret (or something of similar use). The authors of the document probably didn't expect anyone to design a service which could be this stupid nor developers using such APIs to make use of them with a custom web browser or SDK. These developers are mixing and matching separate components from different parts of the OAuth specifications in unspecified ways and expecting their platforms to remain secure without considering what new issues may be introduced by this patchwork approach. This is unfortunately the manner in which most of the OAuth players today function, and the already rampant problem only perpetuates itself as more and more providers jump on the bandwagon and copy the approaches they see or think they see being used by others.

Odds are you'll be able to find many systems making use of the above services which are exploitable due to this problem. It's especially common in desktop applications, where a secret can be directly pulled out of a compiled application binary, even if the service being used isn't requiring anything insecure. It is important to note that Google offers many ways to use OAuth, and only one of them has an endpoint which receives both client_secret and redirect_uri. In the case of Google at least, they aren't recommending this endpoint for web browser based applications despite the presence of redirect_uri, but I'm sure that doesn't stop anybody from using it with a custom web browser or copying this flow into their service for an endpoint intended for regular browser use. In addition, Google appears to be the exception which proves the rule, and there's still the stupidity of all the other OAuth-based services out there which do not allow for secure OAuth-flows in such cases, as they require the client_secret (or equivalent) to always be passed, even when the flow is via a web browser. Worse, many of these services can only be used via a user’s web browser, a point which will be further elaborated upon below.

The aforementioned security document mentions a couple of malicious things one can do once they steal an application's credentials (client_id and client_secret). I'll cover some issues below that can be coupled with this attack to allow one to do some nasty things which have not, to my knowledge, been previously covered. I'm sure my creative readers will also find additional ways to exploit stealing what is supposed to be kept secret.

Insecure Tokens

Token based authentication is a new concept to many developers. Therefore, it is also commonly misunderstood. Many developers designing something like EVS think if they simply follow some design guidelines (such as OAuth) on how APIs should work, or copy what other platforms are doing, then their platform is inherently secure. However, in order for something to be secure, it requires that every single component be secure, that the combination of the components be secure, and that the overall framework be secure. Remember, security is only as strong as its weakest link, and it is not enough to rely solely upon adhering to some overall framework and assume that any and all use of it is therefore secure. The OAuth-based framework in and of itself provides very little in the way of ensuring the security of the underlying components (if it's not outright counter-secure for certain components).

In order for a token-based system to have any semblance of security, the tokens generated must use a cryptographically secure pseudo-random number generator, a topic which is not so well understood. Even worse, APIs for good CSPRNGs in popular scripting languages is severely lacking, yet such scripting languages are often the foundation of what is being used to design many popular modern services.

If the tokens generated are predictable, that means that an attacker can impersonate users and perform malicious activities with their account simply by guessing at what a token might be. I saw one OAuth-based service from a major fortune 500 company which just uses some constantly incrementing ID (perhaps a database field?) for its tokens. I found another where I noticed the tokens generated all seemed to be the output of some monotonic-function. With further research, I found it was an extremely simple algorithm based on the current real world time. On these systems, I could log in as myself, see what the current token IDs are, predict what the next series are going to be, and then use that as part of a token exchange or other operation on behalf of the next random user. Combined with other techniques, even more targeted attacks can be accomplished.

This class of attack is labeled in the aforementioned security document as 4.5.3. Threat: Obtaining Refresh Token by Online Guessing and 4.6.3. Threat: Guessing Access Tokens. While this issue is remediable, the amount of services currently making this mistake, and the ease with which this mistake is made, does not bode well for proving the security of a given OAuth-based service from an external review.

Certain attacks against randomness, which is a whole other topic, can be used to utterly destroy an OAuth-based server if a security-hardened CSPRNG is not in use. While such issues are extremely problematic with other systems too, the issues are much more pronounced with popular OAuth implementations whose entire method of functioning is based around the concept of handing out random numbers. These tokens are generated server-side by EVS, and when used constantly as OAuth as popularly implemented does, drains the reliability of the server and increases predictability of all tokens involved. If you don't have a security-hardened CSPRNG for your environment which can protect against modern attacks, you're probably better off with another protocol which is more forgiving in this regard.

It should however be noted that some OAuth-based implementations structure things in such a way to move randomness requirements to the client-side. While in many ways this is just moving a problem elsewhere, it does reduce the attacks surface from the service-side of things. This at least allows for more educated consumers of OAuth-based services to use a service they can trust in a secure manner, even if the less educated consumers may still be vulnerable. Applying this to our example, this setup would mean that the developers of AFCP can ensure its use of EVS is secure, and can't be exposed to such threats from EVS itself, even if ABC or XYZ do not use EVS securely.

Cross-site request forgeries

Before I get more into this one, let me just point out that despite the name, CSRF attacks are not necessarily originated from a third party site. CSRF attacks can also be initiated from within sites themselves that allow users to post their own links, such as various online discussion and messaging software.

There are many different techniques and frameworks designed to combat CSRF in various ways. OAuth-based integration can make many of these systems unusable or prompt various unsafe practices which can open sites up to attack.

One defense mechanism against CSRF is to ensure that the referer (sic) sent by the browser does not point to an external site. Since many OAuth implementations require that users are directed to certain pages from an external site, this defense cannot be enforced. Since the full scope of what pages and multitude of third party domains an OAuth server will perform redirection through, and since these URLs and domains involved are undocumented and may see periodic changes, the full scope of EVS domains and pages cannot be whitelisted.

Also one needs to consider whether it’s possible for those offering EVS to turn around and try to attack AFCP. One of the principles behind OAuth is that OAuth-based services are not expected to trust their consumers, yet at the same time, require that the consumers fully trust them by allowing them blanket CSRF avoidance. An ideal authentication system would ensure a mutual level of distrust, not a one-way street.

Partial whitelisting for either sources or destinations may also prove problematic. Depending on the anti-CSRF framework in use, tools for disabling certain features may be all-or-nothing, and it may not be possible to disable features on specific pages or for specific sources, forcing those who make use of EVS to stop using their anti-CSRF framework altogether.

OAuth specifically defines the optional state parameter to be used to specify CSRF tokens to prevent CSRF attacks. However, I found that OAuth-based services commonly have limitations on length or allowed characters in state, and may not return it verbatim as required. Therefore, due to weird compatibility issues, many consumers of OAuth-based services find themselves forced to turn off CSRF protection altogether on redirection endpoints. This is labeled under 10.14. Code Injection and Input Validation. Another consideration with the state parameter is that anyone with access to it on the EVS side can alter the request before sending the browser back to AFCP with an otherwise valid state parameter.

OAuth-based API consumers are further limited by being required to define a URI or series of URIs up-front upon registration of their application or service, which is a white-list of URIs that can be used for redirect_uri. Putting aside for the moment major usability issues with such a system which will be discussed below, this limitation forces developers to start getting creative with the state parameter or other potentially dangerous ideas which can lead to a whole slew of issues. Many OAuth-based servers allow only a single white-listed URI, or require an exact match with redirect_uri and disallow additional parameters appended to it. This causes developers to stop using their anti-CSRF framework and start trying to shove all sorts of dangerous stuff into the state parameter or create other poorly thought out systems. The end result is some combination of redirect_uri and state that can be used to push users to some page they should not be pushed to. This is labeled under 10.15. Open Redirectors.

The problem with such redirection can potentially be exploited by itself, due to the combination of parameters not being fully authenticated, or this exploit can be combined with the issue - Masquerading as an OAuth-using service documented above which can be used to wreak havoc upon users. By making use of a stolen client_id and client_secret, a malicious party can create a redirection flow which appears genuine even to AFCP, by the fact that the authentication was performed with AFCP’s own credentials. A malicious user of AFCP may also be able to find a way to use or modify the state parameter, perhaps with stolen client credentials, in order to gain permissions they should not have within AFCP. All in all, due to poor design by OAuth as popularly implemented, and the difficulties external developers face with poor education on certain topics, attacking OAuth-based consumers is often much easier than it should be.

Important reading here is also 3.5. Redirect URI, 3.6. "state" Parameter, and 4.4.1.8. Threat: CSRF Attack against redirect-uri.

Section conclusion

In terms of security, OAuth as popularly implemented does quite poorly. OAuth fails to achieve many of the security objectives it supposedly sets out to achieve. Further, some OAuth-based services outright require that their consumers open themselves up to various attacks in order to use them. Even in cases where OAuth-based services can be used securely, which isn't always known (due to important service-side security details such as token generation methods being undocumented and closed source), OAuth still leads to many poor programming practices. OAuth does little to protect external developers, and various frameworks that such developers use in turn don't provide real security or can't be used securely without strict discipline and caution.

This article in turn only covers some issues that I found rampant. Some of these issues are also the result of developers copying extremely poor practices they see others using alongside OAuth, practices which aren't even mandated by any OAuth specification.

Developers for both OAuth-based services and the consumers thereof need to read and understand all of the linked documentation for implementing and using OAuth-based platforms. One also needs to fully comprehend the 50 classes of attacks listed, the multitude of attacks in each class, and note that the implementation material and security guidelines are not exhaustive. It should also be noted that this article only touches the surface of OAuth security problems, even if it does cover some issues not documented in the official material. Compounded with this, any changes made to the official OAuth proposals introduce a whole new set of security challenges, and these kinds of changes are unfortunately common. One in turn also needs to understand other security-related fields such as random number generation and security verification techniques to achieve any reasonable level of security with OAuth.

If you're looking for real security, I recommend you look elsewhere. I'll cover some alternatives to OAuth in the final section.

Usability Related

Pull the plug architecture

OAuth as popularly implemented, requires that every integration done with an OAuth-based service require a set of application specific credentials to simply exist. These credentials aren't actually used to manage any particular set of user or organization accounts.

This design allows EVS at any time to pull the plug (revoke the application credentials) on any application they no longer wish to service. This is often seen as an advantage to OAuth. However, this exact design is also telling of the intentions behind EVS's service, namely that they want full control over all use of EVS, and have the right to refuse service via APIs on a whim.

If the company behind EVS decides to go into their own camcorder business, and wants to reduce competition, they can pull the plug on competing products that integrate with EVS. Imagine if desktop applications from their inception required approval from the Operating System vendor in order to function. When Microsoft decided to create Excel, they could have pulled the plug on Lotus 1-2-3. Nowadays they would be able to just prevent anyone from using Open Office or Libre Office, and force everyone who wants some desktop application office suite to purchase Microsoft Office.

Besides being an evil way to practice business, this also hurts adoption of the service itself. Why would camcorder vendors want to waste money developing for EVS if any application they design can be shut down on a whim remotely? Even if they did offer some application with EVS compatibility, they certainly wouldn't want to advertise it for fear of being sued for false advertising and premature termination of service if EVS ever pulls the plug on them. Would you be comfortable providing a service subscription to someone, knowing that some third-party could come and completely disable the service at any time? Would you really expect that a client (especially a paying client) would accept an apology that says “sorry, EVS shut our service down, there’s nothing we can do”? Do you really think that such clients would let it go without seeking refunds and damages from you?

As a manager making buying decisions and choosing a video hosting solution to purchase and integrate with AFCP, why would they choose EVS over other vendors, when EVS can quit working for their use-case at any time? When a vendor offers some service which does not use OAuth, they typically include some sort of API guarantee. Meaning their contract or terms of service include API usage specifically for the service package being purchased, and the package itself guarantees access to APIs. OAuth-based services, on the other hand, only guarantee access to the service directly, and tell prospective clients to review their OAuth APIs and apply for a completely separate set of developer access accounts if they wish to have API access. Due to this, the intelligent and discerning buyer will choose the non-OAuth-based service over an OAuth-based one every single time.

A malicious user can also make use of the security issue above - Masquerading as an OAuth-using service, to acquire application specific credentials to impersonate it and do something which violates the terms of service for the APIs in question. This way attackers can ensure your application gets its plug pulled. In the case of our example, a competing camcorder vendor need only to obtain one copy of the camcorder to EVS application, extract the client_id and client_secret from the software, and then they can ensure that their competition fails.


Incorrect accounting

On top of a pull the plug architecture, OAuth-based services as popularly implemented will apply limits to how and when a particular application can make use of the service in question. For example, EVS might enforce that any specific application which uses EVS can only upload 100 videos in a 24-hour period. They may even charge the application vendor automatically for usage above that amount. As a result, if a camcorder bundles software to upload videos to EVS, their entire client-base can only upload 100 videos in a 24-hour period, even though each client has their own account with EVS. If one camcorder owner is particularly active one day and uploads a lot of videos to EVS, all other camcorder owners are now either locked out till the next day or will cause the camcorder vendor to be subject to additional fees. Worse, in the latter case, since the application performing the uploads is stand-alone without any intrinsic communication with any of the other upload applications, there is no way for the camcorder vendor to ensure that their limit is adhered to without significant overhead and a centralized tracking framework. Finally, many OAuth-based systems which do not change for overuse will simply pull the plug on third-party services which they see repeatedly going over their limits, holding the third-party service responsible for their users’ actions instead of terminating or charging the overactive users directly. This entire architecture is a scalability nightmare for third-party service providers, as every camcorder the vendor sells now brings them closer to the point where EVS might shut them down and destroy their business.

Most non-OAuth-based services usually have normal accounting in place where limits of the service are applied to each individual user or organization of users (depending on whether the service is for personal-use or enterprise-level, respectively). OAuth as popularly implemented, however, groups together completely unrelated users and organizations, and makes all of them subject to the whims of one.

A “simple” workaround for incorrect accounting is to require each user or organization who wants to use some application with EVS to go apply for their own developer account. This, though, has the unfortunate consequence of forcing every camcorder buyer to figure out for themselves how to obtain a developer account, a process which is often far from simple. Then the user will have to figure out how to set up the camcorder software to use that account, increasing the possibility of human error.

I took the above described approach with an application I wrote about a year ago which integrates with a Google service, and every first-time user of it has to log into the Google Developer Console and perform 15-20 steps before they can use the application. Besides being annoying, I found I couldn't even give clear guidelines on how to perform these steps, as Google has completely restructured their developer console and renamed things half a dozen times in the past year. Even the first time I wrote a manual for navigating the console and selecting the right options, the manual became obsolete the very day after I published it. I can't point to any documentation on Google's side either, because they have no A to Z documentation specifically for obtaining the specific kind of OAuth credentials necessary for the application to work with the service in question.

The sane approach as used by non-OAuth-based services would be to allow every user or organization account manager (again, depending on whether the service is enterprise-level or not) to have a quick and easy to use control panel which can generate API access tokens for any service which is part of the account, with whatever permissions are needed. However OAuth as popularly implemented never seems to do this. Some OAuth-based services I've seen even require manual approval every time a user applies for a developer account. All this means using OAuth as popularly implemented creates considerable extra burden on the support staff for EVS, the camcorder vendor, and all of their users.

URI lock-in / Application incompatibility

OAuth as popularly implemented requires that a URI be provided up front to EVS when registering for a developer account or application credentials to be used as part of the authentication process in the new application. Remember, this URI will be used every time a user in the third-party service authenticates with the OAuth-based service. After the user logs in, the EVS special login pages will direct the user's browser to the specified URI with the tokens required to access the APIs. Some OAuth-based services will only allow for a single URI up front, while some other will allow several URIs to be entered. In the latter case, when the third-party service initially directs the user's browser to EVS's special OAuth login page, it can also specify which of previously enumerated return URIs to use.

If only one URI is allowed, or the amount of allowed URIs is not enough, often developers will find themselves being forced into opening themselves up to attacks discussed above under Cross-site request forgeries. But this is only the beginning of the issues this requirement causes.

OAuth as popularly implemented also tends to think that every use of it is by a web application built using the software as a service (SaaS) model. If some product, say AFCP, is installed on-premise and deployed on each individual client's personal domain, what URIs do the vendors of AFCP provide when registering AFCP for EVS? This is even more ridiculous when the application using EVS is a desktop application like the camcorder software. Such software has no associated website at all! How are these applications supposed to work with these OAuth-based APIs?

It should be noted that getting a plain HTTP client, such as cURL, is readily available in every major programming language, and can be used in any kind of application. Web browsers with modern features cannot be used in non-graphical clients, such as command-line/terminal applications, and are only available in some programming languages. This means that OAuth-based APIs are severely limited in what kinds of applications they can be used with, making many desired use-cases impossible. It should be noted that many of the popular OAuth based services also require JavaScript on either their special OAuth login pages, or as part of the subsequent redirect process, further complicating simple usage in an application.

Even for SaaS products, if it's deployed on regionally diverse domains (mysaas.us, mysaas.co.uk, etc…) and EVS does not allow for entering enough URIs, then what? What about situations where every client gets their own sub-directory or sub-domain when using the service, how does one pre-register these or deal with the case when the amount of URIs required exceeds the amount EVS allows?

Even if EVS is a service which allows post-editing of the URI white-list, and allows for a nearly unlimited amount of URIs to be entered, how does the list get updated exactly? I have not seen a single OAuth-based service which provides any meta-APIs for modifying the URI white-list. In today's day and age, most SaaS deployments are or should be automated. When a client registers for a service, credit cards can be automatically processed, servers automatically deployed, sub-domains automatically added to DNS, initial credentials automatically e-mailed to the administrator, and so on. But how do the new URIs get added for any OAuth-based services used by the just deployed SaaS instance? Manually entry is utterly unacceptable and completely unscalable.

The workaround most suggest is to have some website set up which handles redirection for all clients and users. However, besides the aforementioned security issues when not done carefully, this can get expensive fast. In order to have all requests processed by a fixed location, enough load balanced infrastructure needs to be set up to handle the load, even though it could otherwise have been handled by the same server or servers which handle the rest of the service for the given client. This also binds on-premise and desktop applications to this extra website, and will be unavailable if the extra website goes down for some reason. This has now become an annoying and costly dependency solely to manage a misfeature.

Another workaround suggested for desktop applications that don't want to be bound to a website is to build in an HTTP server into the application, and set the return URI to http://localhost/. It's bad enough that a web browser - often a full featured one with JavaScript support - needs to be built into the desktop application just to handle the login process, now they recommend a web server should be built-in too! I should point out, though, that whitelisting http://localhost/ is not enough, as that URL implies the server is running on port 80. Not every application can grab that port, nor is the port always available, as something else may be using it. To make a robust application that can handle every eventuality as best as possible, one also needs to whitelist http://localhost:1/, http://localhost:2/, ..., http://localhost:65534/, http://localhost:65535/. This probably sounds ridiculous to you, and that's because it is. This also doesn't even account for the fact that some security software may get cranky or scare users if it finds an application is launching a server.

Being faced with this and some of the previous issues and finding only poor solutions offered, I came up with a completely different solution which I use with some OAuth-based services. I created a small web application that I can throw up on any server which asks in a web-based form to be populated with a client_id, client_secret, and anything else the OAuth-based service requires from what it thinks is an application. After submitting the details, the application redirects the user to the special OAuth login page, and after redirected back, the application displays whatever tokens it just got. The user can then manually paste these tokens into the real application they want to use which does not need to be tied down to any site nor requires browsers, servers, and graphical interfaces be used by the real application.

My above solution first requires users register for their own application or developer account, whitelist whatever the URI is to the small web application, paste their data into the small web application, log in, get the tokens, and paste those into the real application. It works well, circumvents any needs for a web browser and redirect_uri, and it's only a mere 20-25 steps for every user to perform. This would be much simpler for the users if the OAuth-based service itself showed them the courtesy of just supplying a page in their account where they can generate tokens with whatever permissions they wanted. Instead, these services would rather force third party developers to provide such finery, and make their users lose their minds.

Open-source unfriendly

A minor point to the above, OAuth is also unfriendly to open source applications, because every user making use of it is required to register their own developer account in addition to whatever user account they already have with a service. It would be unsafe to include credentials in the source or within binary packages which can be stolen, see Masquerading as an OAuth-using service above. This is on top of all the previous remarks about not knowing what URI to use, incorrect accounting, and all the other limitations.

Low availability

Another major flaw with OAuth as popularly implemented is its low availability (which is the opposite of high availability). OAuth-based systems differ as to the exact details, but they usually expire the tokens they provide that are required to be used with the actual API calls. Some of them allow a way to refresh them, but usually only for a limited amount of time. These systems require that the user of an account be present to re-authenticate with the service like clockwork. Besides being annoying, requiring re-authentication in middle of an operation and being able to continue the process after doing so may cause the design of the platform to fail in ways described above under the issue Cross-site request forgeries.


Now in the case of the camcorder software, where the user was using the provided software to upload to EVS for a while, what happens when the tokens expire? Say the user queued up a bunch of videos and then went camping for the weekend. They come home to find the first few videos uploaded, and then the rest failed because they were not around to re-authenticate. This user will be extremely annoyed, especially if they promised someone the videos would be up by a certain time before they left.

When we consider our usage scenario with AFCP, this requirement to re-authenticate gets even worse. Normally when an administrator assigns someone new to a department, AFCP runs through the list of all integrated users in that department, and adds permission for this new user to access the EVS videos of the other users in the same department. However, if one of those previously existing users needs to re-authenticate, AFCP cannot automatically assign permissions for accessing videos to the newly added user. If the videos of the particular user who needs to re-authenticate is crucial for training a new employee, and the user is on some extended leave (vacation, maternity, etc...), the new employee cannot even be trained.

This expiratory handicap can make sense in various usage scenarios, but completely destroys what EVS integration with AFCP is trying to accomplish. If your usage scenario is AFCP, you really need to look for a service to use which does not use expiring tokens, which OAuth as popularly implemented unfortunately does. However, I did come up with a workaround which I use with some of my applications.

If a platform needs to re-authenticate on behalf of a user when they're not around, one would need their credentials to do so. I've exploited the flaw described above - Stealing credentials / gaining elevated Access, in which I prompt users for their credentials when they log in, store them (encrypted of course), and reuse their credentials automatically when tokens expire. This technique works as long as the user does not change their password and additional authentication factors are not in play.

I created a SaaS application which exploits this flaw over two years ago. Several thousands of users have since willingly entered their credentials into the application, and not a single one of them has ever complained or noticed anything suspicious. Better yet, the vendor behind the OAuth-based service I built upon heard about my application from some of their users, and was pleased as to how they gained access to a larger user base. They contacted my employer and asked if we could provide them with some accounts on our platform for their sales department to show off to prospective clients, as well as a few other key personnel. We did so, and have since captured the credentials of several of their high ranking employees, including an executive responsible for managing their OAuth-based service. Not one of them noticed anything wrong with what we were doing, which goes to show that this is a viable workaround - however unorthodox.

While the above technique can turn a useless OAuth service into something profitable, it'd be better if it was achievable without needing to undermine security, defeat the few benefits of OAuth, and rely on exploitable flaws. I'll discuss below what really should be done instead of trying to always limit usage to the point that a service becomes unusable.

Not enterprise-ready

All the above usability issue sections show that OAuth as popularly implemented is not ready for the enterprise market. Contracts with OAuth based service providers do not actually cover the services you want, accounting is incorrect for organizations making them subject to unrelated third parties, there's extra setup annoyance, it’s not scalable, and the services repeatedly fail to work without manual user intervention from specific users. All this on top of not necessarily being able to conform with an organization’s security requirements.

However a real problem with OAuth-based services is that their APIs always seem to be geared towards only managing things for a single user as themselves. When someone personally gets an account for a service, they obviously do not want others to be able to take control of their account. But when an organization at the enterprise level purchases many accounts for their employees company-wide, they expect to have full control over all accounts, there is no room for individuals. In enterprise scenarios, no AFCP user should even be able to opt-out of the EVS usage, as the higher-ups want all resources within a department to be accessible to the entire department. Therefore, in order to be feasible for an enterprise, whoever or whatever is in charge of administrating all these accounts needs to be able to perform any action on behalf of any user. If this requirement is not met, the enterprise company will need to find a different service which does make this possible.

I know of several OAuth-based services which in their front-ends for non-API usage allows for companies to set up authentication to their services using SAML. With SAML, any login request signed by a particular private key is able to gain entry to a platform as the user who is identified in the signed request. Whoever is in charge of managing the SAML identity provider and its private keys, usually the IT staff at the companies, can masquerade as any user they please and perform needed activities on their behalf.

What companies really want when they purchase a package with a service is to use an automated system to perform needed activities as required on behalf of their personnel. The APIs of the OAuth-based services, however, don't provide a way for any user - even at the administrator level - to perform activities on behalf of other users, nor do they provide a way to acquire tokens representing those lower-level users to use with the APIs on their behalf. An administrator cannot assign permissions for any videos in EVS except what they themselves have uploaded. When I asked developers of these services why not, they responded that providing such a feature would weaken the security of their platform. Yet these services which support SAML already have their security “weakened” in this way, though I fail to see how allowing administrators to effectively administrate their users, a situation which is usually considered desirable, can be called a “weakness”.

All in all, we see that the typical service with APIs built upon the foundation of OAuth as popularly implemented is designed and maintained with myopia regarding what enterprise customers actually want to achieve with a system. These APIs generally don't allow for anything to be done which couldn't already be done the same way with their existing user interface. However if you can't build anything that wasn't directly achievable with the provided interface, why bother offering APIs at all? Providing APIs is not so that the exact same UI with the same limited feature-set can be recreated over and over in other contexts, since today with SSO technology to access a website (such as SAML), there's no real point in that. The point in providing APIs is so that something new can be created which can offer added value to a service. If it's not possible to do more with the APIs than what is already built-in, then the APIs are of little value and no self-respecting enterprise is going to take the product seriously.

Don't get me wrong, with limited APIs in place, there are still those making third party applications. However these applications are generally just embedding a subset of a service’s existing features into a different context with no real added value. If a third-party application is actually providing something with added value with these crippled APIs, they end up also requiring users to perform dozens of steps and tons of copying and pasting to accomplish even the simplest of tasks. In such a situation, odds are a discerning buyer is not going to consider buying that product for all personnel, especially when there are alternatives available which aren't such a pain to use. A good rule of thumb, bad integrations from otherwise competent developers are the result of bad APIs. Therefore, if all of the so called “integrations” being created for a service either lack added value or are extremely clunky, it’s probably an indication that the APIs are lacking what enterprises need. If your product lacks what enterprises need, you can expect that most enterprises will not be purchasing your product.

It should be noted that the only major services which have thriving OAuth-based ecosystems are platforms designed specifically for individual user use, and are not geared for enterprise use-cases. Facebook and Twitter (both of whom were in part responsible for the formation and adoption of OAuth), have a huge repertoire of apps making use of them. Google is another interesting example. Several applications, platforms, and services exist which make use of Google’s OAuth APIs, but all of these are noticeably geared towards individual Google accounts, despite the fact that Google has a large business offering as well. In contrast, Google Apps for Business services generally offer alternative systems and protocols which are more appropriate for the enterprise market than OAuth, as they recognize their OAuth-based APIs to be incapable of providing the needed functionality.

Section conclusion

While the security of OAuth as popularly implemented is not all that it's considered to be, the worst part about it is how crippling it is to actually work with. Many of the things OAuth sets out to accomplish are actually detrimental, especially in enterprise settings, and at best, you'll need to find ridiculous workarounds to even get any use at all out of a service whose APIs are built upon OAuth.

The following is a mostly accurate depiction from one of my colleagues as to where the world with OAuth is heading:

Allow me to present an alternative to OAuth which provides the same level of functionality and security but is far simpler to implement. We call it NoAuth. The protocol is as follows: No one may ever authenticate, period. Simple, effective, and we estimate that it will take developers a mere fraction of the implementation time of OAuth, cutting your costs significantly. “NoAuth, because the future deserves absolute impenetrability.”

A key misdesign of OAuth as popularly implemented is thinking that all external services should be mistrusted equally. Let administrators define what should and shouldn't be done with a service, and what capabilities should be made available with various API tokens. Don't make this decision for them and limit what can be done with a service in its entirety just because there can be some rogue applications out there.

For applications I provide which make use of API services, I frequently get clients who ask me what exactly is my system doing that it needs certain permissions, and that's okay. Administrators are capable of deciding what they want or don't want to allow and what the ramifications may be.

My employer is commonly approached by third parties asking us to integrate some service with another service, telling us how much revenue we'll pull from sales if we partner with them. Every time we find out one of these services is using OAuth we groan, because almost always, it means the project is infeasible. Yet the third party thinks there must be some magical way to do it because we've done some amazing things with other third parties which are not using OAuth. When we ask them to improve their APIs or drop this ridiculousness with OAuth, they claim they can't because this is how it has to be done.

More often than not, we find whatever is desired really is not feasible, and the workarounds are either not possible or too ridiculous, time-consuming, and annoying to the end-user for the case at hand. These third parties beg us to then just do something with it, as if that were a sane business practice. We're not going to create some product for which there's no business case and doesn't look like it'll break even, let alone make a profit.

I've seen a number of these projects come and go over the years. Usually the third party can't find anyone dumb enough to waste their time and effort on working with them, although on occasion they do. The outcome is always something which doesn't sell well, and the third party throws in the towel a couple of months later.

Even large enterprise organizations are coming up with some new product every year that they then try to force on the market, but time after time, these never seem to go anywhere. Despite the fact that the product has no real use, and other businesses can find no way to make it useful, they blame everything but a crucial issue at the heart of the matter. Instead of fixing the actual flaws preventing integration, the lifeblood of enterprise adoption and retention, they think it must something else, discontinue the product, and try releasing a different but similarly crippled product the next year.

Alternatives to OAuth as popularly implemented

What do proper OAuth-based designs look like?

Now that we've seen that OAuth as popularly implemented is utterly broken, when does OAuth actually work?

OAuth systems that adhere mostly to the earlier OAuth specifications and concepts are generally more secure and less broken than those based on later specifications. This is not to say that all OAuth 1.0 implementations are secure, but they're usually less problematic. These systems will normally follow one of two distinct approaches:
  • By providing users the ability to directly generate access tokens in their account which they can dole out to software they wish to integrate, a lot of the silly requirements and insecure transfers and redirects are bypassed.
  • By using a system where the client_secret does not function as a piece of data which is passed verbatim like a common password, but is instead itself a cryptographic shared secret used to generate authentication codes, the remainder of the token system, silly requirements, and insecure transfers and redirects are bypassed. In these systems, users generally do not even have their own credentials and only use SSO mechanisms.
Precious few OAuth-based systems are designed like this though, and these systems generally look nothing like OAuth as used everywhere else. Since these systems stick closer to the OAuth 1.0 specifications, which is officially deprecated, systems using this approach eventually get "updated" to be restructured with all sorts of OAuth 2.0 concepts and additions, thereby ruining their security and usability. This is a reason I'm hesitant to condone anything OAuth based, because even if using an earlier, more operable style of OAuth, some manager is going to have the bright idea that the system will need "improving" and will break it. Better to use something else altogether than begging for problems.

Other options

Looking for other options, people often want to know what other frameworks are out there. However, one does not need some framework to achieve a well understood and secure design. As is, every service has their own take on what OAuth looks like, so there really is no exact approach on how authorization works anyway. Hunting for a framework is often over-complexifying what can be done simply. The only really difficult component that requires a good specification is how to sign variables to prevent tampering with key parameters used, and most OAuth-based implementations do nothing of the sort anyway.

The largest provider of web services on the market today is Amazon. They are the premier provider for enterprises the world over, and utterly dwarf everyone else with a whopping greater than 30% combined market share. Amazon's approach is to provide all their accounts and account administrators with access to a control panel where they can generate application credentials. These credentials can be specified as to what Amazon services they can work with, what actions they can perform in those services, and what permissions they have to work on. These credentials can be revoked by the account holder at any time if necessary.

Amazon's authentication and authorization techniques for their APIs do not require any redirection methods which are inherently limiting and potentially unsafe. Amazon's protocol never sends along any credentials directly, rather they're used for signing data, and can ensure parameters remain tamper-proof if there's any need to send them through a browser.

Amazon's design has proper usage accounting, includes API usage as part of every account, and all API authentication and authorization is initiated from the Amazon side with the creation of application credentials from their control panel. These credentials are then used directly in the API process without any sort of additional token exchange system. This design achieves all the real security objectives OAuth as popularly implemented achieves, and it also avoids all the security and usability issues enumerated above.

One downside I have to say about Amazon is that their permission system is somewhat confusing and not all that user friendly. This happens to be true though of most control panels, and in any case, is a matter of user interface design and is not a mark against the authorization process itself. Also, Amazon's control panel can be navigated fairly quickly and even be used with their APIs, unlike, say, Google's, which, as far as I know, has no meta-APIs, and requires at least a dozen steps to do anything with it.

Amazon's authentication and authorization method is also copied by several other service providers on the market. Google themselves even allow for it in certain of their enterprise products. Google themselves also acknowledge that a pure OAuth design is poorly suited towards enterprise services, and for their enterprise services, they recommend the use of JSON Web Tokens.

JWT is a specification for allowing SSO or API usage between services.  In many ways JWT is like SAML, although unlike SAML which is confusing, built upon XML Security (which is anything but secure), and not geared for API use, JWT achieves the primary SAML objectives in a simple and easy to use manner without all the headaches. If you have an HMAC implementation and know how to structure and parse JSON, then you can use JWT. For those of you who want something off the shelf, there are plenty of JWT libraries already available.

Google’s use of JWT is more advanced than typical though, and instead of HMAC, they require the use of RSA digital signatures which is a more advanced, and less popular concept than HMAC in this area. Google's control panel allows account administrators to generate a new key-pair for their enterprise services, and download the private key to use for signing API log-ins. While this is more secure than HMAC, Google really over-complexifies the whole process, not to mention that they completely redesign their control panel frequently, making it confusing to repeatedly use. I recommend looking instead at what others are doing with JWT if you need examples.

Another technique being used is that of services allowing definition of what kind of permissions third parties need in some kind of XML or JSON file that they can post on a web site. Users can then visit a page in their account where they can paste the URL to this file (or paste the contents of it), and the service will display a list of what kind of permissions the external service or application wants to use and any descriptive information it may contain. If users want to approve this, they can generate credentials which they can then paste into the third party application or service they are using. Users can later revoke the credentials if they want to disable the third party product. This is also a very secure design which doesn't have any ridiculous burdens placed on developers, includes API services for all accounts, provides permissions, and initiates the flow with the service itself, not the third party.

All you really need from the service-side in order to manage authorization is some panel which allows users with the appropriate role (administrator or account owner) to generate API usage credentials which each have permissions and a possible expiration (if desired) assigned to them. These credentials can then be used over any secure authentication system you choose, such as something simple like HTTP Basic Authentication over HTTPS, which is available with practically every HTTP library available, HTTP Digest Authentication, which is more secure and supported by most high-grade libraries, or something else based on authentication codes utilizing a cryptographic technology which does not require any credentials ever being passed over the network, such as HMAC, RSA, or Elliptic Curves. HMAC in particular is already in use by nearly everyone implementing some form of authorization or authentication (including Amazon and even some OAuth implementations).

These various well established techniques decrease the burden of needing to study the effects of one framework’s interaction on others, such as those for anti-CSRF, in order to create a secure platform, and can generally be implemented in a modular manner which can simply be dropped into an existing architecture. They avoid the possibility for stealing the user's or the application's credentials. They also don't require any constant use of elaborate CSPRNGs. These kinds of systems existed long before OAuth and are popular today too. OAuth may have better security than some poorly designed systems which require users’ personal credentials and have other weaknesses, but OAuth is not a substitute for the real designs that already existed. The problems that OAuth claims to solve do not actually exist in the existing well-designed systems, and OAuth as popularly implemented actually introduces many of the problems it claims to solve, along with several others which never existed in the first place. Despite the hype, OAuth does not inherently provide amazing security, and due to the numerous drawbacks and implementation difficulties, the other well-thought-out options are vastly better.

If you're going to be designing a service and provide API access, please, really think about what you're trying to achieve, and don't just copy what you see others do or buy into ridiculous hype. If you must copy someone, try to copy Amazon (the best), Rackspace, IBM SoftLayer, Linode, VULTR, Zoho, Zoom, or others who seem to currently have some inkling on how to structure a straight-forward and sound authentication system for APIs.

64 comments:

Max Rabin said...

You present many pain points I have felt as a consumer of OAuth APIs. Expiring tokens, web-only flow, lack of administrator control for enterprise use-cases stand out, and those are all inconveniences, without talking about the security flaws. I'm definitely going to look into JWT. Thanks for the great post!

Antonio Sanso said...

For the record, this article is technically inaccurate. And the part about Responsible disclosure is ludicrous. I can't see any Responsible disclosure and none of the issue you mention is really a 0-DAY as you claim :)

Thomas Broyer said...

Wow, so many inaccuracies in there! …sigh…

I'll just point one out: not every endpoint taking a redirect_uri parameter will use it with a redirection outcome. All those endpoints whose documentation you screenshotted fall in this bucket: they're all the Token Endpoint, which receives the redirect_uri as some kind of "verification" of the "legitimacy" of the request: if there was a redirect_uri in the original request (going through the web browser) then there must be one in the request to the Token Endpoint, and their values must be identical. This is per spec: https://tools.ietf.org/html/rfc6749#section-4.1.3

This only proves you have no idea what you're talking about.

/micdrop

Antonio Sanso said...

For not talking about the claim that client_secret is sent using the browser agent.... :S

insane coder said...

Hello Antonio Sanso,

Thank you for not taking things seriously, you're verifying my points! If you can't see how to 0-day attack certain existing services with this information, all the better, as this article it not meant to be a blueprint to aid hackers how to do so. However people I work with (who are not malicious) are currently making use of these attacks against existing services.

You can also watch this video from the author of OAuth who later decided that the entire spec went down the drain and is insecure. He talks about some of the same issues brought up here as well as other problems.


Hello Thomas Broyer,

Thank you for quoting that section of the RFC. As you can see in the RFC, the Token Endpoint is not supposed to receive a client_secret. You have already proven these services are now doing their own thing over here in violation of the RFC.

As to your argument that not every endpoint taking a redirect_uri will necessarily redirect is true, however I can tell you that some of these services are always using it to redirect, and I verified that myself. I can't speak for all of them though as that list was grabbed with a Google search, and I didn't apply for a Salesforce account (nor some of the others) in order to test the precise details on how they use their endpoints. Part of the problem here is also that these services aren't always documenting what their endpoints are doing, which makes use of them a bit of guess work to see what works and what doesn't - and that can be insecure too.

As to whether an endpoint should be contacted via the browser or not is an important issue for security. Obviously those of us that know what we're doing will not attempt to do something so stupid, yet there is real software out there which is making this mistake, and the OAuth implementations out there are prompting that the mistakes occur. I know of at least one service which requires a JavaScript-based redirect on the Token Endpoint, and therefore you're forced into using some kind of browser with it.

As per the disclaimer I wrote in the beginning, this article is not about whether the spec itself is secure or not, it's about whether things are being done insecurely with OAuth and whether the design of it leads to that behavior. If you, like me, are outraged that OAuth-based services are causing problems, then by all means, take it up with those services as I requested in my introduction. Please don't shoot the messenger.


To both of you, you have no need to take my word on these matters, read to what the original author has to say: "To be clear, OAuth 2.0 at the hand of a developer with deep understanding of web security will likely result is a secure implementation. However, at the hands of most developers – as has been the experience from the past two years – 2.0 is likely to produce insecure implementations."

Antonio Sanso said...

I know pretty well what Eran Hammer things about OAuth . I respect him and I do appreaciate his point of view.
This article though has way to many technical inaccuracies and makes me doubt the fact you even understand OAuth.

For the record you can check my blog (http://intothesymmetry.blogspot.com/) to see several vulnerabilities I found on OAuth services. There were all OAuth implementations issues (not spec one). This might means that the spec is too hard to understand.
Rather to just complain though you might help out improve the status quo.... Just subscribe to oauth mailing list and contribute...

Thomas Broyer said...

Please read the specs end-to-end, and possibly try to implement them yourself.

From https://tools.ietf.org/html/rfc6749#section-4.1.3:

“If the client type is confidential or the client was issued client
credentials (or assigned other authentication requirements), the
client MUST authenticate with the authorization server as described
in Section 3.2.1.”


Section 3.2.1 then defers to Section 2.3, which defines how one will authenticate, and there it defines how you can pass the client_secret as a parameter (though clients are discouraged to use this and should use HTTP Basic authentication, which servers are required to implement): https://tools.ietf.org/html/rfc6749#section-2.3

I highly doubt the Token Endpoints would redirect to the redirect_uri as that would make the whole thing completely unusable. While OAuth 2 is easy to implement (from a client point of view at least), many devs will use libraries; and those libraries expect a JSON response from a Token Endpoint. Anyone doing it differently is an asshole who haven't read the spec and not even tried to use OAuth2 elsewhere before implementing it. I'm not saying this cannot happen, but you can't really blame OAuth2 for such gross incompetence.

I "shoot the messenger", as you say, because the messenger spreads FUD about a subject he doesn't know. If you found a service doing something absolutely wrong, then describe this; don't shoot at Google/GitHub/Salesforce/etc. when what they're doing is both OK security-wise and spec compliant. We all know what the OAuth1 author thinks about OAuth2; he probably have points, but don't use him as your alibi to cover your own mistakes.

insane coder said...

Hello Antonio Sanso,

I'm not sure what technical inaccuracies you're referring to. What is mentioned here is the result of research of what is actually happening the field. Just because neither of us likes it doesn't make it inaccurate.

As I mentioned in this article's disclaimer and again in my last post, I am not talking about whether OAuth mandates something must be done a certain way, that point is in fact irrelevant. As you correctly surmised, and I thought I made this point clear already, OAuth is too hard for the average developer to implement securely, and this is why many applications and services using OAuth-based APIs are easily hackable.

My contribution towards improving the status quo has been the compilation and publication of this information. The information has been and is currently being shared with those that create APIs for their services so that they can be more well informed what to do and what not to do. It is being made public because others may also find it useful, and because I'm not going to sit down with the hundreds of players out there currently using OAuth to work out these issues (if applicable) with them. Those using an affected service and care are able share this information freely with them.

As to subscribing to the OAuth mailing list, if Eran Hammer who created this originally and spent 3 years with those people was not able to work things out with them, I don't see how I'm going to. Instead of wasting my time with them (which he also recommended that I not bother), I instead will be focusing on supplying information to those who care and working on specifications that actually work and are hard to misuse.


Also, despite your dislike for my section on security, the real focus of this article is how utterly useless most OAuth-based APIs end up being, which isn't a requirement of the spec. For some reason, which I have yet to figure out, OAuth-based APIs seem to make the same crippling decisions over and over. I don't know why OAuth is prompting this, as there are workarounds allowed by the framework, but the amount of services crippling themselves is staggering, and by tallying many services, the cause (OAuth) and effect (crippled) seems to be clear. The only way I see solving this is by coming up with some sort of specification which is not about the technical aspects, but a high level overview of what a protocol must look like and how that works with various kinds of services. Such an specification is never going to be published though, so you'll just have to settle for a list of things of what not to do, and to bear in mind what kinds of interesting things consumers want to accomplish. I'd also like to thank Max Rabin for confirming that these OAuth-based APIs constantly cripple themselves as proven by his experience too.

insane coder said...

Hello Thomas Broyer,

I will iterate again that I am not attacking the spec per say for mandating something, but the spec for prompting bad behavior as seen in practice. Whether I implement something a certain way or not is irrelevant, others are still implementing things incorrectly.

You are correct that not all services will redirect to the redirect_uri at this stage, and the screenshot I quoted above for Zendesk explicitly says it is only for identification purposes and not redirect. Other services though make no specification (causing developers to do whatever seems reasonable to them), often prompting them to do the same thing they saw with the same parameter in the past. Further as I already mentioned, some of them even require it to redirect.

As I wrote in my article, I did speak with some of these services I found guilty of gross incompetence. They have done nothing to change it. One of them instead of fixing it even suggested instead that we use a ridiculous workaround for this particular issue. Their "workaround" would in turn lead to fascinating XSS attacks which are able to defeat cross-origin policies too.

As for who to blame, I primarily blame those implementing OAuth on their APIs, but I feel the spec also is somewhat at fault because it doesn't define a full protocol, and developers are doing anything and everything under the sun and calling it OAuth. This is why this article is not so much about the OAuth spec, but OAuth as popularly implemented.

Please don't call this article FUD because you failed time and again to note the disclaimer and the points I've iterated multiple times over, with constantly mentioning OAuth as popularly implemented.

As to your remark what the OAuth 1 author thinks of OAuth 2, you're forgetting he was the OAuth 2 author as well up to the final draft where he no longer could take it anymore. As to my referring to him, I am doing so because we both discuss many of the same issues, and the idea that OAuth 2 and its concepts are causing implementation issues is not mine, he was the one who first made note of it, I am only elaborating further and mentioning additional mistakes people are making.

Thomas Broyer said...

Remove all your misleading screenshots and the false accusations that accompany them and I might stop calling this article FUD, but not before. I did see your disclaimer, but I do see you're making accusations against perfectly OK implementations.

Antonio Sanso said...

the mistakes are so many that it would take one day to enumerates.
One annoying one is when you claim the client_secret is passed via the browser user agent and even in plain text!!! in which World?? :)

insane coder said...

Hi Thomas Broyer,

I'm not sure how what I'm doing with those screenshots is misleading, as I did not alter them, and my point with them is that they are misleading certain developers to do bad things with them (except perhaps in the case of Zendesk). As is, we found some of them are requiring the endpoint to be used with a browser, and filed reports with the appropriate companies. These were not singled out in the article so as not to make it too easy for hackers. I did not test all of them as I already mentioned, such as Salesforce, which I do not have an account with. Several existing implementations in applications making use of these services are not okay as you so claim, as we were able to steal their application specific credentials. I'm not even sure how you can make a statement that all these applications out there are okay, as not you nor I could exhaustively review all of them even if we wanted to, there's simply too many of them. Based on what we've found happening in the field, we deem this kind of design dangerous, and any of these companies, including Zendesk, should find another way to get the information they need without requiring a method which prompts many inexperienced developers to do poor things with them. Zendesk's remark in how the parameter is used is good, but ideally they should rename the parameter to something like uri_verification so developers know they're supposed to be doing something different with them and not use all of them in their current capture-happy framework. Or follow Google's lead where they provide many compliant endpoints which never have client_secret appearing on an endpoint which can also take redirect_uri. Ideally those kinds of endpoints should be exclusively used.

Furthermore, your remarks are simply to one section of this article. If you think that part of the article is FUD (which I and my colleagues strongly disagree with you), you're welcome to your opinion. However I'd appreciate if in your disagreement with that part of the article you can at least acknowledge that OAuth as popularly implemented is quite crippling in many different fields, which is the key point in this article.

insane coder said...

Hi Antonio Sanso.

> One annoying one is when you claim the client_secret is passed via the browser user agent and even in plain text!!! in which World?? :)

In the world where there's stupid developers out there currently doing this. Some of the developers I've spoken to making this mistake even argued that it's not a security risk to give out your client_secret because they mistakenly think that alone can't be used to attack someone.

Just because you and I are intelligent enough not to make this mistake does not mean all other developers know what they're doing.

Antonio Sanso said...

I do not understand what is wrong about those screenshot either for the record. You claim you broke many implementations. I can't see nowhere your name (differently than in my case, but this is not important) in any security wall of fame of big companies. How come ? Maybe because you did not break anything and those company just ignored you?

insane coder said...

Hi Antonio Sanso,

I think you're missing the point with my article. I'm not saying the companies like Google per se are hackable. I'm saying those using Google services (random desktop application), or new services like EVS (which was stressed over and over again in the article) which are made by developers who think they're copying Google (and YouTube) is broken.

The point of the screenshots is to show behavior which is prompting dangerous things to occur in the field. Just because the gigantic companies who usually have people to design things well may not be broken themselves, that does not mean this is not bordering on dangerous for others out there. A company like EVS is seeing Google's brief documentation and their tokens and saying to themselves hey, I can make such endpoints and such tokens too, and then they go make endpoints requiring browsers with JavaScript and use auto-incrementing database fields for the tokens, and the other things this article mentioned. Or some guy is making his own application to use a Google service is doing something incredibly stupid because the design is asking for the same parameter with different meanings in different contexts, and the documentation is not offering any guidance on how one works with it. Look at Citrix or Buffer, they are offering absolutely no understanding of what all these endpoints or parameters will be doing. The less intelligent developers will end up using those endpoints and parameters the same way they did in previous steps and are currently creating breakable applications.

This article was originally somewhat shorter, but my editor kept wanting me to expand sections to better elaborate on certain points which I thought were self understood. In the process, perhaps certain points were overshadowed. Maybe this article could also use elaborate diagrams and additional explanation on how each of these issues occur, but at 35 pages already, I felt this was just about pushing the limit past reason. I'm sorry if some of this was not clear enough.

Jim Manico said...

The number of technical inaccuracies and the general confusion between implementation specific problems vs. spec problems is significant in this post. The folks commenting here include members of the OAUTH 2 standard body and experts who have written books about this subject in very objective ways. Heck, Antonio has written similar but accurate posts about deep problems with OAuth 2!

I think it's very healthy to point out OAuth spec problems, but when doing so you need to be very surgical in order to be useful. Also, the best place to do such things is on the standard body list in order to generate good discussion and make positive changes.

This blog post is a interesting but inaccurate attempt to point our real problems with Oauth 2.

Jim Manico
OWASP Global Board

insane coder said...

Hello Jim,

Thank you for commenting.

I don't know how I could be more clear about it, but I kept repeating over 20 times in this article and in the comments that I am referring to implementation problems, and even had a huge disclaimer at the top of the article spelling this out.

The only thing I can seriously fault with the spec is that it's a bit too loosely defined enabling implementations to do all kinds of wacky things. Most of the issues in this article though have absolutely nothing to do with the spec, the spec doesn't even cover the situations these implementations are running into.

This article is not an attempt at all to point out problems with OAuth 2, it's about pointing out real problems with implementations of OAuth 2, and quasi OAuth 1/2 implementations.

If you think this article in itself is also hitting some real problem points with OAuth 2 as a spec, that may be telling, but that's not my focus. I wanted something I could give out as a PDF to those currently implementing things (my clients and partners) so they know what mistakes to avoid, and also provide a general resource to those who find themselves in the same boat. If you'd like to rehash whatever issues you think somehow hit upon the spec itself elsewhere, be my guest, you have full permission to reuse any of the material you found here to improve the situation.

Jim Manico said...

Thank you for your mature response, insane coder. I'll take a much closer look at your article and will provide more surgical comments that stoked my concerns.

Unknown said...

Thank you insane coder for a new article, I thought you stopped writing.

I did some searching on my own if I could find the comopony you said from your list need leaking the secret.

I looked for the company in-order and found this where the consumer secret is sent in the browser in 1. Is this what you refer? You are sneeky for pointing to different page from the same company and different step. They do not use another secret at next steps.

I thought how this can hurt me, and thought about you're "Incorrect accounting". I see they account by the consumer key, then this is what you mean?

Do you recommend a library to avoid mistake? Is zend_oauth good?

Also, did you review Slack? This looks like they explain well how to use it.

insane coder said...

Hi Unknown,

I did not stop writing, I've just been busy. This article was also one which took a while to write, the outline of it was even written over a year ago, and I've been slowly adding to it. It didn't turn out quite what I initially expected though, at first I thought it would only be between 5 to 10 pages. But then my colleagues and my editor kept telling me I had to add more and more, and well, you see how it turned out. Based on feedback, I probably will also have to edit it a bit further to clarify some points.

As to your first link. A client of mine brought that OAuth implementation to my attention several years back, and it is one of the things I had in mind while writing this article, but it's not necessarily what I'm referring to per se. Last I checked them out, they are doing incorrect accounting, and based on other information in my article, and other login flows they offer it is possible to compromise applications or services making use of them. However, I am not going to spell it out for you, as this article is not intended to be a blueprint on how to attack others. I will note though that incorrect accounting is a common issue, even Google is guilty of it.

Using existing libraries to avoid implementation mistakes is a good idea - if you can trust the existing library. I'm not familiar with zend_oauth, so please do your own review to see if it meets expectations. Check out the links I posted in this article for the OAuth specifications and the threat assessment document, as they can aid you in determining if a particular library can help you or not. I do recommend using something open source so you can review it yourself.

I'm not sure what you mean by reviewing Slack. Their OAuth documentation does look informative, which is always good, and contributes more to the solution than the problem. I am not personally familiar with their APIs though.

insane coder said...

Due to a lot of feedback pointing out an unclear section - Masquerading as an OAuth-using service, I expanded it, better elaborating upon it and spelling out what the problems are without giving too much away as to which services can currently be attacked and providing an exact manual on how to attack them. I'd like to especially thank Thomas Broyer and Unknown whose comments highlighted to me several points that I was being unclear about and concepts that were presented in a potentially misleading fashion.

Jim Manico said...

insane coder: Solid changes, well done.

Torsten Lodderstedt said...

Hi insane coder,

in section "Responsible Disclosure" you state: "Attacks against OAuth are nothing new, as IBM issued a 71-page document describing 50 classes of attacks against OAuth based services over three years ago". This whole statement is just wrong!

Your text refers to RFC6819, an official IETF document, containing the OAuth 2.0 Threat Model and Security Considerations. This document was published by the OAuth working group and is the foundation of the OAuth security considerations. So this document is not a criticism on existing flaws in the protocol but documents the threat model we used to secure OAuth and shall help readers to implement OAuth correctly.

You have put the document into a wrong context in order to support your arguments. Please change the reference and the way you cite it!

Thomas Broyer said...

“In the case of Google at least, they aren't recommending this endpoint for web browser based applications despite the presence of redirect_uri, but I'm sure that doesn't stop anybody from using it with an actual web browser or copying this flow into their service for an endpoint intended for browser use.”
You're paraphrasing and misrepresenting what Google warns about. Either you don't know what you're talking about (implicit grant vs. authorization code grant) or you deliberately try to manipulate the reader into thinking Google doesn't know what they're doing (or badly communicating about it). I'm not saying Google documentation is beyond reproach, this is a complex matter and they may have to be more explicit about what is a "client-only web app" (also called "client-side (JavaScript) application" in the overview) vs. a "web app" (also called "web server application" in the overview), but you cannot say this is discouraged “for web browser based applications despite the presence of redirect_uri”.

“In addition, Google appears to be the exception which proves the rule, and there's still the stupidity of all the other OAuth-based services out there which do not allow for secure OAuth-flows in such cases, as they require the client_secret (or equivalent) to always be passed, even when the flow is via a web browser. Worse, many of these services can only be used via a user’s web browser, a point which will be further elaborated upon below.”
This is even worse than the above. I have no words. Again, either you don't know what you're talking about, or you're trying to mislead the reader into thinking “all the other OAth-based services out there” don't know what they're doing. Yes, the authorization code flow is expected to go through a web browser, but that doesn't mean the token endpoint will be called from the web browser. The “stupidity” here is not where you say it is.

And, oh, it looks like a debunked all of this section. I'm not even sure what's left after you fix all the above: that people treating security offhandedly can misread and misunderstand specs and documentation and do stupid things? You don't need to go to such great lengths and shoot all around for that.

----

What worries me most, I think, is that you're recommending that instead of using a protocol with a) many well-done libraries and b) a well-documented threat model, people should build their own protocol (bye bye interop, now you have to build one library per protocol) by copying what some others have done. And you're basing your OAuth-bashing mostly on implementers' stupidity/incompetence. Do you really expect those same people to build anything more secure by themselves? Thinking of all threats, etc. Do you really think people making stupid decisions when implementing OAuth2 will make sensible decisions building a security protocol on their own?

insane coder said...

Hi Torsten Lodderstedt,

Despite the rationale behind those who collaborated on the creation of it and the intentions behind the publication of it, one thing is clear, the document shows that many different pieces can be too easily misused. I feel I put the document into the only context that is worth mentioning, that implementing OAuth 2 requires care, and it should not be treated lightly. I'm sorry that I did not mention your contribution to the document. When I initially spoke with several people about their use of OAuth, they all readily admitted to having been unaware of the document, and they shrugged it off as unnecessary reading because they were just superficially copying what they saw some other popular vendor doing. However, after changing the way I presented the document, overstating IBMs' contribution to it (thanks Mark), people started to admit it was something they should read. Since I want those implementing things to read your document and take it seriously, I presented it as I did.


Hi Thomas Broyer,

I'm describing multiple styles of the same attack where credentials can be stolen. I don't know why you think this is impossible. I admit that I am not clearly communicating in different approaches exactly how this can be done, I don't want to spell it out. If you read what I wrote closely noticing certain attribution paid to one company more than the others, along with what Unknown above linked to, you can probably put it together, but I don't want to publicize exactly how to attack existing software.

As for Google knowing what they're doing, in terms of the security section in my article, aside from poor documentation at times, it's hard to fault them. In terms of usability though, they're an absolute nightmare.

As to your argument about interoperability, I find it to be lacking. You have to read every vendor's documentation regarding how their services works and call all the appropriate functions and handle all the custom variables directly, and still find some way to do this within the rest of your software's framework. OAuth is not something where I can just mention some base URI and the rest just all works itself out because everyone does things the exact same way - no one is doing it exactly the same way. This is no different than other services which use many similar approaches to different things OAuth is doing and you have to call the same communication methods with the service specific parameters and so on. At the end of the day, with a well documented vendor's implementation of OAuth or something else, I see little difference between the developer's work involved between the two vis-à-vis the code they write (the usability workarounds though is another matter).

You also seem to be overly fixated on the security sections of this document. The number one reason why I can't stand OAuth is because I keep seeing everyone who makes use of its design is producing useless or unusable APIs. Even if OAuth was more secure than fort knox and it was foolproof to implement, I'd still recommend to never use it because the result is almost always unusable. Security is important, but ultimate security without any functionality is worthless.

(Continued)

insane coder said...


(Continued from previous)

Most of the services I see built upon OAuth are crippling themselves as described in Incorrect accounting, URI lock-in, Low availability, and the other sections. Google, Citrix, Cisco, and the others are all major offenders in most of these described usability problems. I find providing on-premise well working software based on services from these vendors either impossible or mind numbingly difficult. Having to work around OAuth's so called features means regular users have to be exposed to Google's control panel which has been a support nightmare for me. The IT staff at major companies can barely follow a straight-forward step by step guide how to turn on a piece of software, let alone follow a vague constantly changing control panel with a good two dozen steps to deal with.

Vendors on the other hand who haven't been brainwashed into thinking that since OAuth is so magical they need to try to use every aspect of it everywhere in the most unnatural places aren't making these usability mistakes. Without having a protocol to copy with two-legged, three-legged, spider-legged flows, and tied down to specific cross-vendor single-user sites, they end up providing something sensible.

If OAuth was only being used sensibly where it made sense I wouldn't despise it so. But since I see developers hearing good things about it in unrelated contexts, they approach it from a completely warped viewpoint. They think to themselves: "Oh, Facebook uses OAuth, I use Facebook, I love them, they're a big company, I'm can use their stuff too just like they do, yay! I can now become a big company too, yay!" They then run off and apply all these OAuth concepts where they don't belong and the junk being created is the result.

This is why until OAuth 3.0 or whatever comes out being iron-clad how certain flows should NOT be used with APIs and strong guidance on how to structure things in a usable manner, I'm going to strongly discourage anyone to use OAuth technology for APIs. Not because I necessarily think a custom implementation is going to be more secure than some off the shelf OAuth service-side library, but because without one, they're not going to try to implement every single feature (or copy) which makes absolutely no sense for the market they're targeting their API services at. Indeed, I am confident that those making stupid mistakes will fair far better when building their own protocol, and the evidence I've accumulated regarding the capabilities of OAuth vs. non-OAuth based APIs strongly supports that conclusion.

Antonio Sanso said...

I am starting to think as Thomas that you have really no clue about what you are talking about. While you have been really nice on answering comments I really doubt you understood OAuth (at all).

Some of your claims are definitely false. E.g.

"A common mistake I see in OAuth-based service design is the supplying of an endpoint designed for a web browser which accepts as one of its parameters a client_secret (or something of the same concept). "

Moreover you put some screesnshot of services (as Google/Citrix et al) that are totally fine!! There is nothing wrong about those screenshots. I hope you will understand one day!!!

insane coder said...

Hello Antonio Sanso,

I don't know why you think that claim is false, I found it to be currently happening. I know I posted screen-shots of services that when not used in an insane way are totally fine. My argument isn't that some particular service isn't fine, but that the design is prompting problems and this goes on frequently. If you look very closely at the link Unknown posted above you will see one of these companies has a design which is not totally fine. I'd say more, but I don't want to get sued.

Also, this section is getting a lot of dislike, and I agree with what Thomas wrote that it's shooting in every direction and not clearly pointing out existing problems. I don't know how else to describe it though where I explain that this is a point ripe with potential errors without clearly showing real live cases.

Even if you think what I wrote here in this section is very unclear, and possibly I have no clue what I'm talking about in this particular section, it's not nice or accurate to claim I don't know anything at all and therefore the rest of the article must be false too. I have not seen any of you provide any defense against the other sections I wrote.

I know OAuth is your baby and I'm insulting it and therefore guilty in a way of the same crime. I don't know how else though to get developers to stop creating APIs guilty of all the usability issues and some of the problems they're tied to as described here. The usability section is constantly referring to the security section and the dances applications need to do which is why the security section is present at all. I did not buy your book so I don't know if it offers guidance on avoiding all these issues described. If your book is an aid to creating better services, I would recommend it as other recommendations I make. However, based on the monkey-see, monkey-do approach everyone out there is using, I see no alternative but to point out the overall problems I'm finding and recommending to not use what appears to be the primary culprit.

Antonio Sanso said...

The claim is false because this is not what the OAuth spec says . So is not OAuth. Same as what Unknown linked. That is not OAuth as well . Is rather similar to one of the self backed protocol you suggest to people. If you report stuff to companies they do not sue you. At the contrary you are going to be rewarded or give the money to a good cause.

And OAuth is not my baby. Unluckily I did not write none of the related RFC so far.

insane coder said...

Hello Antonio Sanso,

My claim is true, because I have written about OAuth as popularly implemented. I know OAuth is not supposed to be done like that, I wrote in the section itself OAuth doesn't mandate any of these cases. I don't know how many times I need to pound upon this point.

The people making these things, certainly what Unknown linked, is being advertised by the providers of it as being OAuth, and it is from some of these big companies. If you try to use an OAuth library with these broken services, many of them will work, and for all intents and purposes is an OAuth implementation. People are hearing that OAuth is good, and are then looking at these services and doing these things. It doesn't matter if what is being done is in violation, in their mind it is OAuth and therefore secure.

I realize my approach is throwing the baby out with the bathwater, but I don't know how else to get into peoples' minds that just because you call it OAuth and it has much in common with other OAuth implementations that doesn't make it secure. The culture currently is that if it looks like OAuth and talks like OAuth, and it is therefore OAuth AND secure. This article is written specifically to combat that notion.

This is not similar to writing your own protocol, a concept that I am strongly encouraging, because when people do so, they don't try to make it look like OAuth. OAuth is too complex to make something sort of like it and expecting it to be secure. Homegrown protocols that do not try to be OAuth rarely are making these mistakes, at least in the cases I personally have encountered. I'm fighting an uphill battle with these service provides because they are maintaining it is OAuth and therefore secure. You telling me something we both already know, that these implementations of an OAuth-like service is not really OAuth per any given RFC nor secure is not news, but this is what happens when you have a loose practically free-for-all spec which tries to starts advertising dangerous notions. I can't even point to some RFC requirement with these companies, because the moment some executive put the OAuth stamp of approval on it, and it works with whatever OAuth SDK they are supplying, it doesn't matter what the specifications are anymore.

As I wrote in my article itself, I've already reported the issues to the companies we found vulnerable. In one case, we sent a list of over half a dozen security vulnerabilities to address in their "OAuth" implementation (such as monotonic tokens and requiring the client_secret at the very first step). That was several years ago and so far they did absolutely nothing about it. Printing the exact details in public is not going to get me any rewards, it's going to get me sued for violating NDAs I have with them.

Antonio Sanso said...

ok I see you are too much in your World and this is not going to change.
Last thing. OpenSSL for example had a lot of vulnerabilities during its lifetime but noone blamed TLS. What you are doing here is totally non sense. Not because you do not have valid points. But because the amount of mistakes/inaccuracies and false claims contained.
And you know why those companies ignore your report ? Because it probably was not a vulnerability. I reported dozens of vulnerabilities to many companies. I got rewarded (also monetary) and freely wrote about it once this was fixed. Just give a look at my blog and you can read the details of every single vulnerability I found (also not OAuth related). In one case , this time OAuth related, I proposed a draft to the OAuth working group in order to try to close some open redirector in the spec and this might become an RFC. This is trying to be constructive, differently than disruptive as you. You also say you are not doing FUD and then you do a website called http://no-oauth.insanecoding.org/ !!

Thomas Broyer said...

Hi Antonio and insane coder,

The link to Citrix docs posted by Unknown is OAuth!
It's the authorization code flow with a public client. It's a really bad choice given the possibilities it opens with their API, but it is OAuth. They use custom properties in the token response but that's OK per spec. And they unfortunately make many other bad choices: their redirect_uri validation policy (open to open redirector issues, made too easy), making it look like authentication wrt the properties in the token response, having the token valid for 1 full year!
But it is OAuth.

Joe P. said...

"As popularly implemented". Say it with me, folks, "as popularly implemented". Aside from the disclaimer at the top of the article explaining this point, Ctrl-F shows no less than 23 instances where the article reiterates that it is about OAuth "as popularly implemented", not about the spec itself. But apparently nearly everyone in this thread failed basic first-grade-level reading comprehension (not surprising from the same kind of people who think that any of this is an intelligent approach to security). So let's try it again, and I will try to use small words so that all of the cognitively-deficient buffoons present can comprehend. People are misusing OAuth. It's not about the spec. People are misusing OAuth. People are making gold-plated sewage, calling it OAuth, and shoving their fingers in their ears while incessantly repeating "myeh-myeh-myeh, it's OAuth so it's secure, myeh-myeh-myeh".

The typical response from the OAuth crowd any time anyone criticizes them is to claim that anyone challenging them clearly doesn't understand OAuth, and if they would just take the time to understand it, they would realize that they're wrong. Well I've got news for you, oh-mighty-benevolent-gods-of-OAuth, it's actually possible for someone to understand your precious framework and still recognize it for the collection of bovine excrement that it is. The serious security experts all agree, this is a framework which violates nearly all of the core tenets of solid security practice. GOOD security models rely on small, streamlined algorithms which (for someone who actually UNDERSTANDS secure cryptography) are straightforward to implement, easy to validate for correctness, and have very few moving pieces. This is what's known as having a "small attack surface". Look it up, since it's clear that none of you actually knows what that means.

OAuth on the other hand is complicated, hard to implement, and is a fragmented patchwork made up nearly entirely of moving pieces. Many vulnerabilities have been demonstrated both against specific implementations and against the spec itself. Antonio even mentioned a vulnerability which he himself found that will require yet another OAuth RFC to cover it. This is the security analog of finding a terribly rusty pipe which has sprung a leak and instead of replacing the whole damn pipe, you cover the leak with duct tape, hoping that the pressure won't cause one of the other dozen weak spots to burst. And while each of the demonstrated vulnerabilities may itself be relatively minor, the large attack surface means that the minor vulnerabilities can be combined in ways which amount to a zero-day attack. I know insane coder didn't spell it out in the article, but it should be clear to anyone who actually knows security how the exploits mentioned can be combined for catastrophic effect. And if I can see it, you'd better believe the hackers can see it.

Aside from the large attack surface, it also relies on single points of failure all over the place, violates high-availability, and does all of the other stuff that was pointed out in the article. But by all means, instead of discussing the actual security and usability concerns, let's all get hung up on whether the specific implementations mentioned in the least significant segment of the article conform to the spec or not or are broken or not. I'm sure the hackers will all wait until we're done with that debate before beginning their assault on the other myriad vulnerabilities.

Antonio Sanso said...

@Joe P
I read and understood this "As popularly implemented". But it turns out though as the case linked by Anonymous that

1. something that is claimed to be wrong/dangerous is not
2. many claims in this article are not supported by anything else than thin air

We all know OAuth isn't perfect (but what is?). Implementation vulnerabilities are many as well. My main concern is again with the inaccurancies and falsity wrote in this article.

An since you UNDERSTAND crypto (and I do not right? :)) I am not as well able to understand this article.

Joe P. said...

Antonio, "Large attack surface", "low availability", "single point of failure". If you don't understand these terms, then no, you don't understand security. If you do understand these terms, you should be able to recognize that OAuth suffers from all of them. Either way you slice it, OAuth loses. And if you can't see why what the anonymous user linked is highly dangerous, it's just a further indication that you don't understand what a vulnerable exploit means. I'll give you a hint, look closely at what's being used to identify the client application and at what stage it's being sent. Look VERY closely at it.

Antonio Sanso said...

@John P

Since I do not know anything about vulnerabilities this is a shortened list of stuff I broken: OpenSSL, Google Chrome, Apple Safari, Google, Facebook, Github , Microsoft and continues... (You can find all the exploit details in http://intothesymmetry.blogspot.com/)

How about you?

I look at this really really closely. And still I challenge you to exploit it... Then If you can exploit it report it here https://firebounty.com/bug-bounty-program/564/citrix-systems and enjoy your bounty ;)

Joe P. said...

Good job not addressing any of the main points being made about the core tenets of security being violated by OAuth and continuing to focus on minutiae. Stay the course, never say die, fight to the last man!

Unknown said...

Thank you insane coder for the response and I look for more articles from the future.

I offer Slack because it looks clear by comparison. Ddd it to your list?

And sorry, I started a real war with my link :)

@antonio take the consumer key from application using this flow in 1 and use with the "direct login" flow to get the token. When you use with the "Incorrect accounting" you can denial of service the application that uses the consumer key. This is easy :)

I want the reward, but they only assign the CVE to the tangible products.

Thomas Broyer said...

@Unknown But you still need a user ID and password so is it really a vulnerability? I was more thinking about a simpler form of http://homakov.blogspot.fr/2014/02/how-i-hacked-github-again.html

insane coder said...

Hi Antonio Sanso,

I'm not sure why this is "my world", what's going on is in everyone's world. I already described up front what this article is about, I'm going to quote a key paragraph again: "Some of you may also argue that some things done with OAuth are misusing the specifications, or that OAuth doesn't specifically mandate things be done the way they are. Whatever the case may be, I'm not here to write about a particular OAuth based specification, but how OAuth is currently utilized by major players in the market, regardless if what these organizations are doing conforms with the specifications or not.".
If you feel something in that paragraph was unclear, point it out to me and I'll rephrase it.

In the section you dislike so, I phrased it multiple ways, the strongest probably being: "These developers are mixing and matching separate components from different parts of the OAuth specifications in unspecified ways and expecting their platforms to remain secure without considering what new issues may be introduced by this patchwork approach."
Again if you feel something in this paragraph was unclear, I'm happy to improve it.

Regarding OpenSSL and TLS which is a tangent, I'm not sure where you're getting your information from, but people did blame TLS. It was restructured how many times? How many algorithms within it were replaced? They're currently working on a new version with new algorithms too. If you were to take a page out of the TLS book, we'd be on OAuth 3.1 by now which addressed various issues, and there would be much material about older versions doing it wrong out there. I'd be quite happy if people started reviewing OAuth like they did TLS.

> And you know why those companies ignore your report ? Because it probably was not a vulnerability.

That's so easy for you to say from your armchair, because you haven't seen any of these reports. I can tell you that these were even acknowledged issues. In one case as I mentioned earlier, the developers recommended a workaround that clients could use on their end by modifying the existing OAuth libraries, and they did nothing to improve the flow itself. Their modification of course introduced new issues too.

> This is trying to be constructive, differently than disruptive as you.

I've worked with services which were usable, which were then upgraded to this "OAuth thing". I was open to it, and went to go work with this new shiny thing that I heard good things about. Suddenly I started finding all the issues listed in my usability section, and services became useless. As far as I'm concerned, OAuth disrupted all the services based on services I was providing.

I'm coming from a completely unbiased perspective here, no one is paying me to feel one way or another about OAuth. I have no vested interest in whether OAuth exceeds or not. I'm not a vendor of any competing technology. From my point of view, OAuth is creating issues, and the way things are currently working, I don't see how it can be salvaged.

Due to how I see APIs are being implemented, anything trying to promote OAuth I consider dangerous, and I wrote a site enumerating real issues out there. Since it's the truth, and there is real reason for concern, it's not FUD as you so claim.

You on the other hand are making money on the very concept of OAuth. As you yourself admitted, you relish in finding all these vulnerabilities in a complicated spec and getting money for it. The more services that use OAuth, the more people that will also end up buying your book. OAuth is personally beneficial to you, and I don't want to say it, but you are not an impartial party here.

I'm sure the view from the Ivory Tower of OAuth is great, and all you guys posting here from that perspective love it. But those of us little guys who have to deal with what you rained upon us very much dislike it.

insane coder said...

Hi Thomas Broyer,

If you and Antonio Sanso cannot agree if something is OAuth or not, that probably indicates some part about it is too complex, no?



Hi Joe P,

Thanks for the support. I'm glad some of my readers are understanding what I'm writing here. I also like that you brought up large attack surface vs. small attack surface. It's a good point that I'll add to the website next time I update it, thank you.




Hi Antonio Sanso again,

> many claims in this article are not supported by anything else than thin air

Let me edit that for you: many claims attacking this article are not supported by anything other than thin air

You say there are many inaccuracies and falsities in this article, but aside from constantly talking about the Masquerading section and the screen-shots in it, you have yet to actually offer anything constructive regarding the rest of it. Regarding Stealing credentials, are you telling me these phishing and logging attacks are not possible? Regarding Insecure Tokens and Cross-site request forgeries, these sections do nothing more than elaborate on attacks found in the official RFCs, are you saying that's inaccurate too? Regarding Pull the plug architecture, are you saying not a single service out there is built this way? Regarding Incorrect accounting, are you saying all services do account correctly against users and none are affected as described? How about Low availability, are you saying services built where the tokens expire and can no longer be refreshed don't exist, or that such a thing is not considered low availability? The burden of proof is upon you to refute these things, as some of this is documented elsewhere, even from your own cabal, and everyone who responded to this article who isn't from the OAuth Ivory Tower apparently agree with these points and find them to be truthful.




Hi Unknown,

I hope to be able to put out another article soon. Perhaps something regarding a list of things not to do your first day on a new job, or a critique regarding the pros and cons of string based interfaces, I haven't decided yet. So be on the look out for it.

> I offer Slack because it looks clear by comparison. Ddd it to your list?

I'm not sure what you mean. Were you trying to say "did you add it to your list" or "please add it to your list".

I'm not going to post Slack in my list of screenshots because there's enough, and this section seems to be really hated, and I think the point (which perhaps is already lost?) doesn't need another example.

Joe P. said...

Thomas, let's assume for a second that you haven't read the "Incorrect Accounting" section and can't put two and two together on your own, and it's therefore not obvious to you that a vulnerable application secret is readily exploitable even on its own. Anyone who can seriously ask whether it's "really a vulnerability" that a piece of supposed-to-be secret data involved in a security process is easily obtainable does not have what it takes to call themselves a security reviewer. Period. It's clear that those of you "refuting" this article but refusing to actually address the issues raised in it are simply trying to protect your own flawed agendas. Until someone actually discusses the specific points raised instead of making generalizations, I'm done.

Thomas Broyer said...

Joe, a "client_id" in OAuth is not "supposed to be secret", it's just an identifier; like an API Key for Google Maps: it's public, you put it in your HTML. If you base your quotas on it, you'd better put measures in place so it cannot be abused. The Authorization Code flow on Citrix's implementation does this using the redirect_uri as a whitelist, just like the Google Maps script looks at the URL of the page it's embedded in. The fact that Citrix put quotas based on a public identifier and doesn't have countermeasures on their "direct login" (actually, Resource Owner Password Credentials flow) to authentify legitimate use of that public identifier is beyond stupid; I think we can all agree about that.
(and yes, for some reason I forgot about that quota thing; I was too focused on data exfiltration or data injection/manipulation; please accept my apologies)

I still question whether it'd have been better if they had not used OAuth and instead rolled their own protocol though.

And if the goal of this article is to draw attention on the fact "just because it uses OAuth2 doesn't mean it is secure", then it fails IMO, because it's way too handwavy and vague and "shooting in all directions", instead of being precise on some of the risks (and without necessarily citing a vulnerable implementation). The fact that it's openly "anti OAuth" ("because OAuth is too commonly badly implemented"), and contains inaccuracies (some have been fixed, others –e.g. the part about JWT– still exist) don't really help. An example, “This issue is present any time an OAuth endpoint expects to be sent the client_secret in plain text via a user’s web browser”; we both know OAuth2 doesn't mandate or even suggest that, but this sentence may mislead a reader into thinking otherwise, therefore blaming OAuth (the spec) for that; it wouldn't need much rewording to be precise about it and not throw FUD on "OAuth, if properly implemented". I have a similar problem with “OAuth, as popularly implemented”; it can be interpreted in many ways, where it really means "many OAuth implementations"; which blames implementations more than the protocol itself. You can still blame the spec for making it too easy to implement it in such a wrong and insecure way (I don't dispute it), but those a different things: on the one hand, it implies OAuth cannot be salvaged (without changing it in backward-incompatible ways), while on the other hand it implies those implementations can actually be made secure by following the best practices and better understanding the consequences of their implementation choices (i.e. if their implementers cared about their users and their data).

That article has points to make, but they're lost in a deluge of handwaving, imprecisions, inaccuracies, etc. to the point that all it says in the end is: "OAuth is bad, don't use it, fear those who use it, better roll your own (insecure) thing" (the "because it has better chances of being more secure than if you naively implemented OAuth" part is easily missed).
Last, but not least, the proposed alternatives, unless I missed/misunderstood something, don't provide the same features as OAuth (having an application acting on behalf of a user, without knowing that user in advance, and without requiring him to do any sort of configuration that would obviously lower the "conversion rate").

insane coder said...

Hi Thomas Broyer,

Glad to see you realized that incorrect accounting (applying usage quotas solely based on developer specific information and not user/organization) coupled with multiple flows that are unaligned in their security can cause problems. Unknown's point about application DoS appears to be valid, and shows that many kinds of problems are easy to fly under the radar because we aren't looking in every possible direction for issues.

I fully agree that this article is shooting in all directions. Perhaps I was too vague on some points, but Joe P summarized my point quite nicely that what I am saying is that OAuth has a very large attack surface. Due to that, I have not focused on any one point, I'm throwing everything out there to show you really need to consider everything due to the complexity and potential problems.

I am openly anti-OAuth because in my experience with various implementations I see nothing but real issues. OAuth introduced many new concepts to the market, which are often poorly understood and causing serious usability and security issues. Most APIs are crippled with OAuth, this is a fact based on surveying many APIs. The OAuth spec doesn't force things to be crippled, but it's what's happening. Security issues are also commonly found with big players like Facebook and OAuth. It's almost like every couple of months I hear about another issue with one of them due to the large attack surface. I've decided it's time to cut our losses at this point and start looking elsewhere. You're free to disagree though.

Take the client_id you mentioned which shouldn't have to be secret. A point I made in this article is that may usually be true. But when you combine it with various other issues I raised, suddenly the client_id is really functioning like a client_secret. Those implementing don't even realize they have a problem because they think they're adhering to something secure. But based on the implementations I personally reviewed, I am finding too many of these kinds of things, and it's extremely difficult to always get it right.

> the part about JWT

What's wrong with the part about JWT? (and yes I know many people from the OAuth team created JWT and there are ways to combine JWT with OAuth)

> we both know OAuth2 doesn't mandate or even suggest that, but this sentence may mislead a reader into thinking otherwise, therefore blaming OAuth (the spec) for that; it wouldn't need much rewording to be precise about it

I'm open to suggestions, how do you suppose I reword it?

> on the one hand, it implies OAuth cannot be salvaged (without changing it in backward-incompatible ways), while on the other hand it implies those implementations can actually be made secure by following the best practices and better understanding the consequences of their implementation choices (i.e. if their implementers cared about their users and their data)

This to me is a very important point, and is exactly what I'm trying to convey. I openly admit I may not be conveying this point as clearly as I should be, but based on everything I've seen it appears to be a fact on the market.

> That article has points to make, but they're lost in a deluge of handwaving, imprecisions, inaccuracies, etc.

You say things are imprecise and inaccurate, but I think you are too focused on the spec itself or only looking for the attacks and problems that are similar to things you already know about. I however am seeing all kinds of new attacks and problems that I've never seen with other protocols, often which have nothing to with the spec itself. I'm trying to be all encompassing without having my focus to narrowed to older more understood kinds of attacks and problems.

(To be continued)

insane coder said...

(Continued from above)

> Last, but not least, the proposed alternatives, unless I missed/misunderstood something, don't provide the same features as OAuth

I'm not coming to suggest OAuth doesn't has good points about it. OAuth has tools which have their own purpose and probably should be used as such. However those working with OAuth are treating a certain flow they see common as their only tool and using it inappropriately. I made this point in my introduction: "implementations cripple services which choose to use OAuth by severely, inappropriately, and undesirably limiting what can be accomplished with them."

What I'm proposing is to use other kinds of techniques which are more appropriate for APIs. Whatever these other techniques are they should not look like OAuth nor have all its (mis)features.

> without knowing that user in advance, and without requiring him to do any sort of configuration that would obviously lower the "conversion rate"

I think OAuth is good for something like that where say you want to allow someone who has some kind of account somewhere to log into blogger and post a comment. I don't think that system works for APIs where one service is trying to use another service.

Regarding users in advance, other API techniques don't need OAuth to accomplish this. If a service is enterprise level (see my definitions in the article), the administrator in service A (like EVS) can create some kind of credentials they copy into service B (like AFCP). Now service B can use those credentials to automatically create users in service A. This actually has an even higher conversation rate than OAuth (as popularly implemented), because individual users don't need to authorize it in anyway, it can all be done automatically. OAuth (as popularly implemented) does not seem to allow for this use case though.

Thomas Broyer said...

> What's wrong with the part about JWT?

Where you're describing (“JWT is a specification for allowing SSO or API usage between services.”) is not JWT at all. Possibly some usages of JWT, but not JWT. JWT is only an envelope around some payload (generally JSON, but actually not necessarily) for signature and/or encryption.
“Google’s use of JWT” is JWT-Bearer, i.e. using a JWT as an authorization grant instead of a client_secret.
But JWT's are also used in OpenID Connect (also implemented by Google) to transfer claims about the user's identity to the client. In this respect it might be more similar to what's used in SAML (OpenID Connect and SAML both addressing WebSSO).

> I think OAuth is good for something like that where say you want to allow someone who has some kind of account somewhere to log into blogger and post a comment. I don't think that system works for APIs where one service is trying to use another service.

OAuth is not an authentication protocol http://oauth.net/articles/authentication/; it's raison d'être is authorizing a service B to access user's data at service A without knowing user's credentials at service A. It's the "please go to your settings at service A and generate a token with permissions X and Z and then come paste it here", automated (and if service A also implements OpenID Connect for authenticating users, users don't need to create yet another password –or more likely just reuse the beloved password they created years ago–).

> Now service B can use those credentials to automatically create users in service A. This actually has an even higher conversation rate than OAuth (as popularly implemented), because individual users don't need to authorize it in anyway, it can all be done automatically.

How do users authenticate at service B?

insane coder said...

Hi Thomas Broyer,

> JWT is only an envelope around some payload

That's exactly what I meant in that section. Create a payload which conveys the needed information and use JWT to pass it around. I find this similar to SAML, but not as complex and insane as SAML is, and can be suited for APIs.

I realize others are using JWT differently, but JWT itself can be flexible in this regard.

> it's raison d'être is authorizing a service B to access user's data at service A without knowing user's credentials at service A

Indeed, which is why I think it's great when something like blogger supports it for posting comments. I think it's horrible when it's used as part of an authentication protocol for APIs, it's not well suited for it.

>It's the "please go to your settings at service A and generate a token with permissions X and Z and then come paste it here", automated

That automation you're pointing out is wide open to phishing attacks and also adds web browser requirements to an API. Therefore I find it utterly inappropriate for APIs.

The fact that services built upon OAuth typically don't allow the administrator who purchased X amount of user accounts to preauthorize their entire userbase with that service also is less automated. Requiring ever user to go through this process is annoying and also makes integration more brittle. Again, great for blogger, terrible for enterprise-level integration between two services.

> How do users authenticate at service B?

In the case I provided, AFCP, the enterprise already has a system in place that they want all users to be using. This can be tied to some kind of directory with LDAP, CAS, SAML, JWT, or whatever, or it can have their own user base built into it, and AFCP acts as the directory itself.

My point is when something like EVS is using OAuth as popularly implemented, it no longer becomes a good fit for AFCP which is already deployed in enterprises, and EVS becomes useless. Enterprises needs one internal directory where they can bind all external services directly to it, not some hodge podge where every user has their own individual accounts with external unconnected systems and no real way to control them.

Torsten Lodderstedt said...

I don't mind whether you mention my contributions to RFC 6819 or not. Since this is a IETF RFC published by the OAuth working group, a lot of people (beside Mark and myself) contributed to it and provided the foundation for a sounding design of OAuth 2.0. You don't recognize their contributions and you keep referencing and interpreting it wrongly. That's a really bad style.

Thomas Broyer said...

AFAIK, SAML doesn't only define a data format, but also (mainly?) how to pass them around to achieve SSO. JWT is only a data format, and many protocols use it for many different things; some of them similar to SAML, others not. So no, JWT is not “similar to SAML”. AFAICT, SAML uses XML-DSig for digital signatures and XMLEnc for encryption; so actually it's more like "JWT is to OpenID Connect what XML-DSig and XMLEnc are to SAML".

> > it's raison d'être is authorizing a service B to access user's data at service A without knowing user's credentials at service A
>
> Indeed, which is why I think it's great when something like blogger supports it for posting comments.

I don't follow you: how is "authenticating to Blogger (to leave a comment) using an account somewhere else" (aka, delegate authentication) related to "authorizing a service B to access user's data at service A"? What "user data" does Blogger accesses? Nothing. That scenario is not about authorization, it's about authentication; and OAuth is not suited for authentication (I posted the link already).

> I think it's horrible when it's used as part of an authentication protocol for APIs, it's not well suited for it.

And yet it's exactly what it's designed for. The commonly implemented "three-legged auth" is not suited for all scenarios, but is not the only possible flow with OAuth.

> >It's the "please go to your settings at service A and generate a token with permissions X and Z and then come paste it here", automated
>
> That automation you're pointing out is wide open to phishing attacks and also adds web browser requirements to an API. Therefore I find it utterly inappropriate for APIs.

For some scenarios yes; for others it's perfectly fine.
OAuth also provides "two-legged auth" flows.
GitHub and Google (among others) allow you to generate tokens for use in scenarios where "three-legged auth" is not appropriate (CLI tools, etc.). Google also allows you to generate a key-pair. The difference between those are "who" the token/key-pair represents, and the associated authorizations.
What kind of "flow" is implemented by services "in the wild" only depends on what kind of scenarios they want to enable/support; you cannot say "OAuth is utterly inappropriate for APIs" just because you've only met three-legged auth flows when you'd have preferred/needed two-legged auth. There are cases where services won't let you use their APIs for the kind of thing you want to do (indeed, there are also cases where there's no API ;-) )

> The fact that services built upon OAuth typically don't allow the administrator who purchased X amount of user accounts to preauthorize their entire userbase with that service also is less automated.

OAuth is not about user provisioning. You mentioned SAML above; SAML also is not about user provisioning. OASIS has SPML for that, and there are things being developed at the IETF (based on JSON and JWT, rather than XML, XML-DSig and XMLEnc); and services like Salesforce and Google have their own APIs for such things, and nothing stops an implementer to pre-authorize users that way.
But you cannot blame OAuth for not making the coffee.

(to be continued)

Thomas Broyer said...

(continued from above)

> > How do users authenticate at service B?
>
> In the case I provided, AFCP, the enterprise already has a system in place that they want all users to be using.

Sorry, I actually meant "service A": how do users of AFCP authenticate to EVS? And when using EVS APIs through AFCP to publish new videos (I'm specifically not talking about user provisioning or other admin-level things), how are authorizations handled? How does EVS knows that the video comes from "user X"? "who", from EVS's point of view, is calling the API? (the "organization"? or the actual "user X"? or something/someone else?)

> My point is when something like EVS is using OAuth as popularly implemented, it no longer becomes a good fit for AFCP which is already deployed in enterprises, and EVS becomes useless.

If EVS doesn't want to provide user provisioning APIs to their customers, then yes, it's not a good fit for people who want user provisioning APIs. But OAuth is not about those user provisioning APIs, only about authorizing someone/something to call them.

Which leads me back to: do you really know what you're talking about?

insane coder said...

Hi Thomas Broyer,

> AFAIK, SAML doesn't only define a data format, but also (mainly?) how to pass them around to achieve SSO.

SAML 2.0 is mainly about the protocol for passing assertions around. 1.0 focuses on what the assertions themselves are.

> JWT is only a data format, and many protocols use it for many different things; some of them similar to SAML, others not. So no, JWT is not “similar to SAML”.

In the context I am describing it in, it can be used similar to SAML. Granted you can do many other things with it.

> I don't follow you: how is "authenticating to Blogger (to leave a comment) using an account somewhere else" (aka, delegate authentication) related to "authorizing a service B to access user's data at service A"?

I don't think they're related which is why I am comfortable with Blogger using it, and not comfortable with service APIs using it. I will elaborate further on this below.

> That scenario is not about authorization, it's about authentication; and OAuth is not suited for authentication

Which is exactly my point why OAuth doesn't work for APIs. These APIs are making use of OAuth as a key component of their authentication mechanism, when OAuth is suited for an authorization process, not an authentication one. Since the services should have the accounts administrator create some kind of access secret or key and authorize what can be done with it directly in a control panel (as Amazon and others do), OAuth is now completely appropriate. Having OAuth interpose itself in the authentication flow as is common introduces several of the crippling points I mentioned above, requiring a browser, application incompatibilities, and so on.

> The commonly implemented "three-legged auth" is not suited for all scenarios, but is not the only possible flow with OAuth.

Since this article is about what's commonly done with OAuth, it's not relevant what else can be done with OAuth. As soon as some company thinks they should be implementing OAuth, they do so using common flows they see which are inappropriate to their situation.

> GitHub and Google (among others) allow you to generate tokens for use in scenarios where "three-legged auth" is not appropriate (CLI tools, etc.).

I'm not familiar with GitHub. Regarding Google, not quite. It depends on their service, and it's quite maddening when you find one of them doesn't support the same auth features as others. Also some of their alternative methods heap on additional restrictions like IP white-listing, which allow you to use them with CLI tools from known servers, but not for an application you're distributing to others or want to use from a personal home network with a dynamic IP.

(To be continued)

insane coder said...

(continued from above)

> What kind of "flow" is implemented by services "in the wild" only depends on what kind of scenarios they want to enable/support

I think this is a key point which you are mistaken about. Those in the wild don't understand what it is they're supporting. They ask third parties, such as myself, to implement things which are impossible with their flows. I've spoken to multiple providers, even teams at some very large companies, and they say they want to enable all the kinds of applications being created that their competitors have (who aren't using OAuth), and even point to specific examples of applications they want. But then they only offer OAuth as they see everywhere else and think it's enough because it's what they see a multitude of others solely offering. They have no understanding that multiple flows exist or that certain flows enable or disable certain kinds of functionality. When I've tried explaining to them, when a certain design is crippling and they should offer some alternatives, they tell me they're not going to change anything about their flows or APIs, and they'll just find someone else who can figure it out (which they never do). I've seen this happen very often over the past couple of years.

> Sorry, I actually meant "service A": how do users of AFCP authenticate to EVS?

Generally, they don't have individual authentication in an enterprise setting, because they use SAML or some other SSO authentication method. But when it comes to APIs, these same services like EVS are only offering per-user API authentication, and no global service-to-service authentication.

> how are authorizations handled? How does EVS knows that the video comes from "user X"?

They're using OAuth on a per-user basis which I find to be incorrect. As I wrote in the article, correct authorization for these settings is when the accounts administrator generates whatever credentials for the service as a whole and assigns permissions. From that point, which user a video is associated with an API call should either be an explicit parameter in the API function, or to more closely fit their existing design, on behalf of whichever user the master token requested a per-user token on behalf of. The latter arch allows with the addition of a single API function to provide working on behalf of users without needing to modify all the other existing functions.

> "who", from EVS's point of view, is calling the API? (the "organization"? or the actual "user X"? or something/someone else?)

Generally, the vendor of EVS doesn't even understand this question. They want organization-level integration, but they don't know how to achieve that. They only know to create the same thing they saw Facebook is doing with their users and similar popular services.

(To be continued)

insane coder said...

(continued from above)

> Which leads me back to: do you really know what you're talking about?

You keep saying this, and it prompted me to reread all the posts in the thread before replying to see if perhaps we are not understanding each other properly.

I started to notice something with many comments over here, including ones from you. I'm envisioning certain very capable usage scenarios, of which I'm discussing (and thought I kept pointing out), architectured where a service is capable of filling a broad need. Services like those Amazon offers.

Most of the commentators though keep to be focusing on what other kinds of more limited services need, and therefore we are talking past each other.

In my vision, an enterprise service has authorization built into some admin control panel. From this point, no fancy protocol needs to be used to handle anything. The vendor can roll their own authentication process, even something as simple as HTTP Basic over HTTPS, and they rarely will get anything wrong here. Anything else is over-engineered, error prone, and often crippling.

I think a bunch of you are thinking of other scenarios which are not service to service oriented, and then finding what I'm writing about to be complete lunacy. How can some developer on their own possibly engineer their own kind of three-legged authorization process? Best to use OAuth, right?

Since I work with vendors day in day out encountering over-engineered poorly thought out models which can't fill the needs they want and have multitudes of problems, I am speaking out against OAuth in this area. From the field I come from, I don't see OAuth being good for services which want to capture enterprise markets, it simply isn't working based on what I see is happening.

From our differing perspectives, we probably think the other is completely nuts, and understandably so. I'm trying to be civil and understanding (despite some rudeness directed at me in the comments), please try to do the same.

I think we can both agree that we are both intelligent human beings developing software in a multitude of confusing environments. Please try to be understanding that I have some inkling of what I'm saying which is applicable to what I have to deal with in my line of work. I've tried to describe in my article the situations I'm talking about and it's quite probable I've done so poorly for those who do not share my perspective. If you think something I'm saying makes no sense, this is probably indicative that we are picturing two very different things. I'd appreciate it if you could try to take my arguments within the setting I've painted in my article. If something is unclear, please ask me to explain instead of attacking and insulting me.

Thomas Broyer said...

Let me try to sum it up: you see many people not understanding what they're doing and how it doesn't answer their needs (assuming they even know what they need/want), and specifically choosing OAuth2 three-legged flow "because others are doing the same", and moreover doing it all wrong, and you want to draw attention on this: "OAuth is not necessarily for you, and it's easy to get wrong and you probably actually get it wrong".

Unfortunately, this is not what several people understood reading your article, and that's not what the article title says: "OAuth doesn't work"? yes it works, in scenarios it's tailored to address. You're blaming OAuth for, basically, being popular and, unfortunately, being picked up because it's "hype" rather than because it addresses a need.
You know what, the same can be said of many, many, many other things; do we say AngularJS and React "don't work" because people use them when they don't need to? No, we blame overengineering and bad stack choices instead. Do we say transaction-less relation-less schema-less NoSQL "don't work" because people misuse them and shoot in their own feet? No, we blame bad tech choices instead.

Your explanations in your last comments make it quite clear that your article is actually badly written and doesn't convey your message.
If you want to say "don't pick OAuth because it's the 'industry-standard, best practice, authentication and authorization method.' (Citrix says so, not me)", say it clearly and make it the prominent idea of your article. If you want to say "OAuth is easy to get wrong, unless you read (and understand) pages of specs and threat-model, and even 'big players' get it wrong, sometimes to an inconceivable point", say so, and make it the prominent message of your article (but also say that it's not hard to get it right either, because really, it is; assuming it fits your needs to begin with).
But that's not how I read it, neither the first time, nor the second and third.

insane coder said...

Hi Thomas Broyer,

That summary you wrote is fairly accurate. It also almost matches my past article which was an intro to the topic: http://insanecoding.blogspot.com/2013/03/oauth-great-way-to-cripple-your-api.html

This article was designed to answer many of the questions and complaints I was getting from people over the years regarding the last one. The last one is more focused and briefly describes most of the points that are elaborated upon here, but in a more straightforward setting.

I tried to eliminate the issues you found and I was anticipating with my disclaimer and usage scenarios sections on top, but apparently those failed for those coming from a different perspective. Those in my field actually enjoyed this article very much, and thought it conveyed good points. But then again, I guess we are all suffering from https://en.wikipedia.org/wiki/Curse_of_knowledge

Both articles have received criticism, and I thank all you guys for it, I will use that criticism hopefully for a future third article. Thomas, you in particular in your last couple of comments have provided amazing feedback, and I will try harder to get it right next time making use of your suggestions.

> If you want to say "don't pick OAuth because it's the 'industry-standard, best practice, authentication and authorization method.' (Citrix says so, not me)"

I had to search Google to see where they said that. To find it written in a place where four different people here discovered a broken design is pretty funny.

Thomas Broyer said...

> > If you want to say "don't pick OAuth because it's the 'industry-standard, best practice, authentication and authorization method.' (Citrix says so, not me)"
>
> I had to search Google to see where they said that.

That was the link from Unknown above.

> To find it written in a place where four different people here discovered a broken design is pretty funny.

That proves the point: they picked OAuth without deep-thinking, and it shows in how they (utterly badly) implemented it. Their justification for using OAuth is not that it's appropriate, but basically because "that's what others do, so I suppose we should do the same".
(in their case, their use of OAuth and the flows they implemented look appropriate, the problem there is security; problem of culture maybe?)

insane coder said...

> That proves the point: they picked OAuth without deep-thinking, and it shows in how they (utterly badly) implemented it. Their justification for using OAuth is not that it's appropriate, but basically because "that's what others do, so I suppose we should do the same".

Indeed. And this is by a big company like Citrix. Unfortunately I see these kinds of things happening all over. The smaller companies are even less educated and at times make even worse mistakes than Citrix there is.

I just got out of a meeting with yet another company who wanted us to get them into the service-to-service enterprise market. After pinpointing together with them the flaws in their existing design, they admitted they're under-prepared to handle what they anticipated would be their market, and simply just copied what they thought everyone else was doing. We finished the short meeting with them saying they'll think on what we discussed and needs to be addressed and they'll see about releasing additional methods to use their service, but I'm not going to hold my breath. At this point companies usually do nothing, as their developers are out of their depth, and often have confusing and sometimes conflicting information from multiple sources to work with, but aren't looking to pay for additional consulting to work out all the details.

Unknown said...

Thanks for the great article, insane coder.
I have read about a half of it. I have nothing against you.
But I'm a little confused grammatically with this sentence:
"Since the full scope of what pages and multitude of third party domains an OAuth server will perform redirection through, and since the URLs and domains involved are undocumented and may see periodic changes, the full scope of EVS domains and pages cannot be whitelisted."
Maybe the second "since" is unnecessary? Or am I just missing something?
Or did you mean "Since an OAuth server will perform redirection through multitude of third party domains, and since ...?"

By the way, some other words which are suspected to be typos are "Is also seems as if..."
and
"the API consumer is mislead into thinking this is a requirement"

insane coder said...

Hello Unknown,

It's quite possible there are typos that have gone unnoticed. I'll double check what you pointed out to see what I can fix.

I'm not sure what the grammatical issue is with having "since" twice. The intent of that section is to indicate that which domains and pages an OAuth-based service is using is undocumented and can change at any time. Therefore, the API consumer of such a service cannot whitelist certain domains or pages. Back when I was new to OAuth and thought I was clever, I tried whitelisting a domain thinking it was not likely to change, and the same day some of my users from another country told me they couldn't use the system. It turned out the OAuth-based service used a different domain as part of the last step in redirection for users in that country. I then did a little more research, and decided the whole approach was pointless, I couldn't be sure of the full list, and new country specific domains could be added at any time.

It's also actually worse than what I described in the article. Many OAuth-based services that try to cater to organizations will offer the ability to delegate out the authentication-specific component within the authorization process. In these scenarios, organizations can install some LDAP-based component locally on their own personal domains, or similar technology, which the OAuth login process will redirect to when it realizes the user belongs to that organization. In some of these cases, depending on how the final step is structured, the referer you'll end up receiving will be different per organization.

Putting aside how some of the above in many scenarios is beyond overkill for various reasons, it means you can't know up front what necessarily is or isn't valid. That makes one-size-fits-all whitelisting impossible.

insane coder said...

Based on some recent comments here, over IRC, and in-person, I updated the article again with some minor changes to improve readability, fix typos, and clarify certain concepts. Thanks goes out to all involved.

Daniele V. said...

Hi, If only you will search for SingleID on Github you will discover a really nice point of view on identity and authentication step.

The root of all the problem you listed is because the (hashed) password is stored togheter with the data! Split them and you will get a passwordless auth system with yes/no question on your phone!

Passwords will evolve in decentralization storage really soon.

Shahbaz Asghar said...
This comment has been removed by the author.
Shahbaz Asghar said...

Really Nice post,today i also become to know Windows Zero Day Vulnerability have founded and hackers are selling it for $90,000.

niaziakmal khan said...

Programming is combination of intelligent and creative work. Programmers can do anything with code. The entire Programming tutorials that you mention here on this blog are awesome. Beginners Heap also provides latest tutorials of Programming from beginning to advance level.
Be with us to learn programming in new and creative way.