3 Powerful Extensions to Improve Security and Get the Most Out of Kong
OAuth 2.0 is the current gold standard for secure delegated authorization. The reason is simple: OAuth puts control back in the hands of the users. It enables users to securely grant access to their resources without having to share passwords with third-party applications. Hence, it's one of the most widely adopted standards in the industry.
The standard defines several authorization flows (or grant types) to help address a wide range of use cases. Given the critical role that API gateways play in securing access to APIs, it's essential that API gateways support industry standard protocols such as OAuth and OpenID Connect. With its support for all OAuth 2.0 grant types and OpenID Connect (OIDC) flows, Kong has emerged a winner in securing and scaling APIs.
Though OAuth 2.0 is a powerful standard with well-defined flows, there are a few shortcomings. To address these deficiencies, the OAuth standard releases security extensions. The extensions offer mechanisms to enhance the security of the authorization flows. Since Kong is in the critical path, it's essential to adapt the new extensions and stay compliant with the standards.
In this blog, we’ll discuss the drawbacks of the bare authorization flows and explore the various mechanisms available via security extensions to enhance the security of the flows. We'll also review how Kong offers support for these security extensions.
The risks of authorization flows — and their mitigations
Let’s talk about the risks of authorization flows in the context of the popular Authorization Code Flow (also called Authorization Code Grant). This flow enables users to securely grant access to their resources without sharing passwords.
Here's a visualization of the authorization code grant/flow. It's a redirection-based, three-legged flow where the authorization server responds to the client application with a temporary code after user authentication. The code is later exchanged for a token by Kong and the application is granted access if the token is valid.
Authorization Code Grant/Flow
Kong’s OpenID Connect (OIDC) plugin provides the functionality. Under the hood, Kong orchestrates the exchange of the authorization code for an access token to authorize the application's access to resources with consent from the resource owner as shown above.
Let’s examine some of the risks and drawbacks in the bare authorizations flows.
Risk #1: Lack of confidentiality and integrity protection for authorization requests
During the authorization code flow, the first request is to the authorization server’s authorization request endpoint, authorize. This endpoint is typically an open endpoint and doesn't require authentication.
The following is an example of a typical authorization request where the request parameters are encoded as query string parameters (plain text).
Authorization request as a plain text request:
Example of authorization request with request parameters encoded as query strings parameters
This request has the following potential risks:
- The source of the communication (request origins) can't be established since it's an unauthenticated request and has the potential to be triggered by malicious actors (source authentication failure).
- Even though communication may be over an encrypted/secure channel (https), the confidentiality of the communication can't be maintained as it transits through various hops and has the potential to be terminated prematurely along the hops (confidentiality failure).
- The request typically happens via user agents (such as browsers). Even if TLS is used to offer secure communications between the client and the user agent as well as the user agent and the authorization server, TLS sessions are terminated in the user agent. Communication via user agents isn't integrity protected and is vulnerable to tainting (integrity protection failure).
Due to these weaknesses, the authorization flows are vulnerable to several attacks, such as phishing, redirection, URI rewriting, and leaks.
Mitigation: Using request objects or JWT instead of plain text request via JAR security extension
JAR (JWT-Secured Authorization Request)
To help maintain the confidentiality and integrity of the authorization flows, OAuth released the JAR security extension. The JAR extension enforces usage of a request object or JWT (JSON Web Token) in an authorization request instead of the traditional plain text request (URL query parameters). Usage of JWTs provides an additional layer of security and helps maintain the integrity of the authorization request. JWTs are typically signed, making it hard to tamper with the request. Additionally, the JWTs can be encrypted, further protecting the confidentiality of the data being transmitted in the authorization flow.
The following is an example of an authorization request with the JAR security extension enforcing usage of the request object or JWT:
Authorization request with signed request object or JWT
Example of authorization request with a JWT
The request object is constructed with request parameters as shown below:
Example of a request object with request parameters included as claims in the object
The request object is signed with RS256 algorithm resulting in a JWT as shown below:
Example of signed request object (or JWT)
Usage of JWTs ensures that the request cannot be tampered with in transit, thus providing integrity protection.
How does Kong support JAR?
Kong’s OIDC plugin offers support for JAR via the Require Signed Request Object configuration option. The plugin can be configured to use request objects consisting of request parameters when it initiates the authorization request flow. The plugin constructs a JWT consisting of all the request parameters and signs it with Kong-generated keys. The public key is made available to the authorization server which can then validate the JWT signature. This ensures both integrity protection and source authentication.
Risk #2: Uncertainty about origin of response leading to lack of protection against response tampering or man-in-the-middle
While risk #1 talked about risks in authorization request flow, similar risks exist for authorization response. The authorization server’s response to a request does not contain any information about the identity of the authorization server that issued the response. Therefore, the receiving party can't be sure who issued the response and the secrets contained therein. Attackers in the middle can read and manipulate the response.
Due to this inherent weakness, the authorization flow is vulnerable to a few classes of attacks such as code leakage, code replay, and mix-up attacks.
Mitigation: Using JWT (JSON web token) in the authorization response via JARM security extension
JARM (JWT-Secured Authorization Response Mode)
To mitigate the risk of a man-in-the-middle reading or altering authorization responses, JARM extension defines new response modes. Using JARM, the client instructs the authorization server to craft the response parameters as a JWT. The server then encodes the JWT into the response payload to be transmitted to the client as either a query URI parameter, fragment component, or form post.
Since the response payload is a signed JWT, a man in the middle can't easily read the data nor alter the response parameters in the payload. JARM also mitigates risks against authorization server mix-up attacks by allowing a way to identify the sender and intended audience of the response. The JWT always contains the following data to secure the transmission:
- iss - issuer URL of authorizations server that created the response
- aud - the client_id of the client the response is intended for
- exp - expiration of the JWT
JARM defines the following encodings for the response:
- query.jwt
- fragment.jwt
- form_post.jwt
- jwt
The following example shows the authorization response with JARM security extension
The authorization request instructs the server to respond with a JWT instead of plain text response
Example of an authorization request with instruction to respond with a JWT
Authorization server responds with a JWT
Example of authorization response with JWT instead of plain text response
Using JARM security extension ensures that the responses can't be tampered with in the transit thus providing integrity protection.
How does Kong support JARM?
Kong’s OIDC plugin offers support for JARM via the Response Mode configuration option. The plugin can be configured to instruct the authorization server of the expected response mode. Based on this setting, the authorization server crafts the response as a JWT and transmits it as per the configured option (query.jwt, form_post.jwt, fragment.jwt or jwt).
Risk #3: Lack of client authentication before authorization leading to impersonation
JAR and JARM extensions provided solutions to security challenges by allowing the authorization requests and responses to be wrapped in a request object that is signed and optionally encrypted. However, there's still an unaddressed risk. The authorization endpoint is an unauthenticated endpoint which means authorization flow can begin before the client is authenticated leading to malicious actors impersonating legitimate clients. There's also the risk of malicious actors rendering the authorization service unavailable to legitimate clients by bombarding it with malformed requests.
The following is an example of an authorization request to a standard authorize endpoint.
Example of authorization request to standard authorize endpoint
No client authentication is enforced on the authorize endpoint leading to authorization flow beginning before authentication.
Mitigation: Pre-register the authorization request via PAR (Pushed Authorization Request) Security Extension
PAR extension further improves the security by allowing the authorization request to be pre-registered with authorization servers. Since the authorization server only considers the registered requests, unregistered requests can be redirected. In addition, the PAR endpoint is an authenticated endpoint forcing client authentication before authorization flow can begin. With minimal changes required to use the PAR endpoint over a standard authorization request, organizations can achieve increased confidence in the identity of the client during the authorization process.
With PAR, the authorization request is pushed to the authorization server’s PAR endpoint instead of the authorize endpoint. The request is initiated as a POST. Client authentication is included as JWT client assertion-based authentication. This is the first call that registers the authorization request with the server. Malformed requests or unauthenticated requests can be rejected
The following is an example of an authorization request to a PAR endpoint.
Example of authorization request to PAR endpoint
Response from the authorization server’s PAR endpoint, which includes a request_URI. The value and lifetime of the request_URI are contained in the response from the PAR endpoint.
Example of a response from PAR endpoint upon successful registration
The request URI returned in the authorization response is used in subsequent calls to the authorize endpoint.
How does Kong support PAR?
Kong’s OIDC plugin offers support for PAR via the Require Pushed Authorization Requests configuration option. If configured, the plugin first pre-registers the request when the authorization request is initiated. The authorization server’s PAR endpoint issues a request URI that represents the registered authorization request. It responds back with the ‘request_uri’ parameter, which is used in subsequent requests.
Conclusion
In this blog, we reviewed the weaknesses of the authorization flows (particularly authorization code grant/flow) which can leave organizations vulnerable to several attacks such as phishing, redirection, URI rewriting, and leaks. We discussed potential risks and reviewed the OAuth security extensions available to mitigate them. We also reviewed how Kong supports all three OAuth security extensions to fortify the authorization flow and offer robust security controls.
For environments that require elevated security requirements such as financial-grade APIs or Open Banking, support for the new security extensions is more than a question of compliance — it's a core requirement to protect themselves and their customers from authorization flow-related attacks. Kong’s support of JAR, JARM, and PAR security extensions ensures compliance with industry standards in securing APIs.