enardeitjaptrues

These kinds of incidents make it clear that the development teams behind these applications assumed that APIs were difficult to find. In all likelihood, they were prioritizing both application functionality and development speed over security. In other words, they “just had to get it to work.” This is a practical illustration of our thesis from volume 1 that until we understand the implications of API-based architectures, the existence of robust controls and standards in isolation will not solve the problem. These incidents also illustrate that just because APIs are obscure to normal users does not make them hard to find. Obscurity is never a substitute for security, but in the case of APIs, it is actually the antithesis of security.1

API Authentication Failures With Authorization Impacts

The other theme of unsuccessful API authentication is that when these authentication models fail, they tend to manifest as authorization failures or escalations of privilege. On a logical level, this seems intuitive; successful authentication is a precondition for successful authorization, since a system needs to know who the user is in order to determine what actions they can take. At the same time, it is an example of a system failing openDefinition: a failure state for authentication systems that allows the user to proceed using the application in question. Opposite of failing closed.in an obscure but dramatic way. It appears that these applications were designed and implemented with functionality and speed to market as the only priorities.

The most egregious case we saw of this was a system in which the API server generated an authentication token for the client upon connection, as it should, but then the server never subsequently checked the token. The result is that an attacker could use brute force authentication tokens to retrieve data about every user in the system—in this case, extraordinarily sensitive data about customers’ children.

No design principle or different set of priorities can explain this; it is simply a bug. It does, however, indicate that this app and the device to which it connected probably did not go through rigorous code review or testing, and that the people who developed it were almost certainly focused on functionality over security.

In another case, an operating system for network infrastructure contained a bug in which a malicious HTTP request to the API resulted in the attacker gaining an authorization token that granted them administrator permissions, although this exploit only worked if an admin was already authenticated to the system.

There were also a handful of incidents from the “no authentication” category, in which the next step for the attacker was to gain an authorization token that allowed them to make requests of other APIs or use other functionality in the web app.

The point is that, in theory, the two systems—authentication and authorization—should function separately, but a failure in one is driving a failure in the other. In practice, many systems manage secrets surrounding sessions and permissions in similar ways, and this kind of cascading failure is not rare. However, permissions and authorization are more important for API connections than for human users, both because malicious human users are increasingly beginning their attacks at API endpoints and because those endpoints are designed expressly for the rapid and easy transmission of machine-structured data.

This kind of cross-pollination of authentication and authorization failure magnifies the impact of any given bug or misconfiguration. The onus to design and build these systems with security in mind has never been more critical, and yet these systems are most often built with security as an afterthought.

These complexities also illuminate an issue that is central to the question of API security. Taken to their logical conclusions, API-based systems not only blur the boundaries of trust between system owners, partners, and users, but they blur the boundaries of the web application itself. As systems become more disintegrated and place greater emphasis on connections between disparate elements, determining the likelihood and impact of an event, as well as locating the burden of due care, becomes significantly more difficult. Added to the fact that APIs represent a significant expansion of the attack surface, and the task ahead for security teams starts to look daunting.

How to Get API Authentication Right

Other than a glaring lack of awareness about API risk, one of the themes that recurs the most in comparing API incidents is the lack of standardization and the ways that home-built processes play into the different failure modes we’ve encountered. This is why we are joining everyone else in the API security conversation to recommend embracing standards and established libraries, and avoiding reinventing the wheel. Put another way, one of the core problems in API security is that, as an industry, we are treating APIs as though they are a protocol with detailed specifications, when they are really just a way of thinking about a problem.

With that in mind, we recommend OpenID Connect for authentication and OAuth 2.0 for authorization. OpenID Connect is, in fact, a specific implementation of the OAuth 2.0 base protocol that uses JSON Web Tokens (JWTs) to exchange and evaluate identity claims. Both are well-established protocols for which information, advice, and solutions abound.2

However, these protocols are not immune to risks either, though they tend to be misconfigurations or poor implementations rather than vulnerabilities in the protocols themselves. In the next few months, we will review case studies in API authorization failures as well as release a JWT hardening guide with tactical advice for ensuring that your API access control systems are built as soundly as possible.