Pass-the-permission-ticket vulnerability in UMA 2.0
Published:
Updated:
In the User-Managed Access (UMA) 2.0 protocol, a malicious resource server (or a malicious server acting as a resource server) can obtain a requesting party (access) token (RPT) intended for another UMA resource server from a UMA client by passing a permission ticket obtained from the target resource server to the UMA client. This can compromise the privacy (confidentiality) and integrity of UMA protected resources.
See as well:
Note: malicious authorization server attack
A similar/related attacks (not discussed here) involves a malicious authorizaton server. However, this attack is probably more a phishing attempt which can be mitigated in implementations rather than a real vulnerability which would need to be fixed in the protocol.
Table of content
- Table of content
- Description
- Mitigations
- Impact for the HEART Profile for UMA
- Conclusion
- Appendix, recap on UMA 2.0
- References
Description
Summary
A malicious UMA resource server RS1, can trick a UMA client application into providing it a access token (RPT) which is actually intended for another UMA resource server RS2 (target resource server) by sending to the client application a permission ticket obtained from the target resource server. Unless the RPT is sender-constrained, the malicious resource server can then use this access token on the target resource server and act on the user's behalf.
In order to that, when the UMA client application makes a request to the malicious resource server,
- Instead of sending a RPT it would have obtained from the authorization server, the malicious resource server obtains it from the target resource server by making a request to the target resource server (acting as a UMA client) and sends this RPT to the client application. Instead of requiring permissions for the resources on the malicious resource server RS1, this permission ticket is for resources on the target resource server RS2.
- If the UMA flow completes, the client application obtains an access token (RPT) associated with permissions on the target resource server but sends it to the malicious resource server.
- When the malicious resource server receives this RPT, it can use it on the target resource server and can access the protected resources on behalf of the user.
This works because the client cannot know on which resource server (which URIs) the RPT is supposed to be used.
The malicious resource server does not even have to be registered as resource server on the authorization server as long as the client can be tricked into using it as a UMA resource server.
This threat is not discussed in the security considerations section of the core UMA specification and the federated authorization specification.
Am I impacted?
You are probably not impacted if the UMA clients and the auhorization server support a single hardcoded UMA resource server.
You are probably impacted in the following cases:
- You support dynamic registration of clients. In this case, you probably can't be sure that all your clients use the same hardcoded list of resource servers.
- The UMA client might start UMA flows for at least two different UMA resource server. If one of these resource servers is malicious (or gets compromised), it could obtain a RPT intended for the other one.
Details
The client application makes a request to the malicious resource server RS1 (eg. POST https://rs1/foo
):
GET /foo HTTP/1.1
Host: rs1
...
The malicious server makes a request on the target resource server RS2
without RPT (eg. POST https://rs2/bar
)
in order to obtain a permission ticket for resources on RS2:
POST /bar HTTP/1.1
Host: rs2
...
The target resource server RS2 requests a permission ticket from the authorization server:
POST /perm HTTP/1.1
Host: as
Content-Type: application/json
Authorization: Bearer {PAT_OF_THE_RESOURCE_OWNER_ON_THE_TARGET_RESOURCE_SERVER}
...
[
{
"resource_id": "RID-XXXX",
"resource_scopes": ["write"]
}
]
HTTP/1.1 201 Created
Content-Type: application/json
...
{"ticket":"PT-XXXX"}
This permission ticket is associated with:
- one or more required resources (on the target resource server) identified by
resource_id
(eg."RID-XXXX"
); - associated scopes for each resource (eg.
["write"]
).
The target resource server sends the permission ticket to the malicious resource server which forwards it to the client application:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: UMA realm="...",\n\
as_uri="https://as",\n\
ticket="PT-XXXX"
...
The client application completes the UMA grant and obtains a RPT for resources on RS2:
POST /token HTTP/1.1
Host: as
Authorization: {CLIENT_CREDENTIALS}
Content-Type: application/x-www-form-urlencoded
...
grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Auma-ticket
&ticket=PT-XXXX
&...
HTTP/1.1 200 OK
Content-Type: application/json
...
{
"access_token":"RPT-XXXX",
"token_type":"Bearer"
}
The client repeats the request to the malicious server RS1 with the RPT (actually intended for the target resource server RS2):
POST /foo HTTP/1.1
Host: rs1
Authorization: Bearer RPT-XXXX
...
The malicious server now has a RPT for the target resource server and can make requests on the target resource(s) on behalf of the user:
POST /bar HTTP/1.1
Host: rs2
Authorization: Bearer RPT-XXXX
...
RS2 checks that the RPT is associated with the correct permissions and accepts the request.
Mitigations
The following mitigations options are discussed below:
- Allow-listing resource servers
- Detecting of the phishing attempt before initiating the UMA flow
- Detecting of the phishing attempt during the consent verification
The following fixes of the protocol could be used:
- Using sender-constrained RPTs (with DPoP or mTLS)
- Extending the UMA flow to declare the resource server URIs in the messages
Allow-listing resource servers
The client application could restrict its interactions with a list of known trusted resource servers (allow-list).
Limitations:
- Does not protect against compromised resource servers.
- Does not work in a loosely-coupled/federated scenario where the clients applications and resource servers may be dynamically registered on the authorization server.
Detecting of the phishing attempt before initiating the UMA flow
In the fake resource server case, the user is tricked into using the fake resource server. The user could detect this phishing attempt before initiating the UMA flow.
Limitations:
- Does not protect against compromised resource servers.
- Only protects against phishing attacks. Des not protect against attack on the client itself.
- Detecting this attack may be difficult, especially when the requesting party is not the resource owner and when the resource server may be dynamically registered on the authorization server. For example, a user may receive a legitimate invitation from another person to access a UMA protected resource located on a resource server hosted on another domain which would require authentication on the authorization server.
Detecting of the phishing attempt during the consent verification
The user may be able to detect the attack during the interactive claims-gathering if the content of the authorization request is clearly indicated as part of the consent validation. The consent should clearly indicate:
- the requested resources and resource scopes;
- the identity of the associated resource server.
Limitations:
- In many cases, if would be difficult for the user to detect the attack based on this information.
- Even if the authorization server checks the user consent, consent would have to be checked for all UMA authorization requests. If consent is remembered, the consent verification might be skipped during the attack and the user would not have the opportunity to detect the attack: remembering consent for the (RqP, client, resource, scope) tuple does not protect against this attack.
Mitigations using sender-constrained RPTs
Sender-constrained access tokens (TLS-bound access tokens or DPoP access tokens) could be used in the UMA flow in order to mitigate the pass-the-permission-ticket vulnerability. As DPoP access tokens are easier to deploy, this solution should probably be prioritized over TLS-bound access tokens.
Sender-constrained RPTs would be bound to a public/private keypair owned by the client. In both cases, the private client key is needed to use the access token. A malicious resource server could not reuse a client RPT on another resource server because it would not have the associated private key.
Limitations:
- Sender-constrained tokens must be supported by the client, by the authorization server and by the target resource server.
DPoP
In the case of DPoP, the client must send
a proof-of-permission
when using the sender-constrained access token.
This proof-of-posession token is a JWT signed with the client private key
and contains the target URI ("htm":"https://rs1/api/foo"
).
A malicious resource server cannot
replay this proof-of-posession on another resource server
because the hmt
claim would not match.
In the interactive claims gathering,
the client could pass the a hash of its public key
using the dpop_jkt
parameter:
GET /claims?client_id=...&ticket=...&claims_reidrect_uri=...&state=...&dpop_jkt=... HTTP/1.1
Host: as
...
In the RPT token request,
the client could pass a proof-of-possesion token
in the DPoP
http header field:
POST /token HTTP/1.1
Host: as
Authorization: {CLIENT_CREDENTIALS}
Content-Type: application/x-www-form-urlencoded
DPoP: eyJ…,
...
grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Auma-ticket
&ticket=PT-XXXX
&...
TLS-bound access tokens
The usage of TLS-boud access tokens would be similar.
Limitations:
- TLS-bound access tokens rely on mTLS which might be cumbersome to support.
Mitigation by declaring the resource server URI
The UMA protocol could be extended to exchange information about the URI of the resource server. This information could then be used to detect the pass-the-permission-ticket attack.
Note: OAuth resource indicators
OAuth resource indicators
(resource
parameter)
could be used instead of of the resource_uri
parameter.
In order to avoid unintended impact on other application,
with other usages
we are different parameters in this proposition.
Resource server registration
If the resource server registers itself on the authorization server using dynamic client registration, the client could advertise its UMA resource URIs using a dedicated parameter:
{
...,
"resource_uris": [
"https://rs1/api/"
]
}
Resource indication in the Permission Ticket Request
Alternatively, the resource server could declare the expected resource URI as part of the Permission Ticket Request:
POST /perm HTTP/1.1
Content-Type: application/json
Host: as
Authorization: Bearer 204c69636b6c69
...
{
"resource_id":"RID-XXXX",
"resource_scopes":["write"],
"resource_uris": [
"https://rs1/api/"
]
}
Unauthorized response from the resource server
HTTP/1.1 401 Unauthorized
WWW-Authenticate: UMA realm="...",\n\
as_uri="https://as",\n\
rs_uri="https://rs1/api/",\n\
ticket="PT-XXXX"
The client must not proceed with the UAM flow
if the resource_uri
is not consistent
with the URI of the resource server.
RPT request by the client
If the client supports this extension, it includes the resource server URI in the interactive claims gathering requests and in the RPT requests:
- if the
rs_uri
parameter was sent by the resource server (in the 401 response), this value must be used; - otherwise, the root URI of the resource server must be used (
https://rs1/
).
Example of interactive claims gathering request:
GET /claims?...&resource_uri=https://rs1/api/ HTTP/1.1
Host: as
...
Example of RPT request:
POST /token HTTP/1.1
Host: as
Authorization: {CLIENT_CREDENTIALS}
Content-Type: application/x-www-form-urlencoded
...
grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Auma-ticket
&ticket=PT-XXXX
&resource_uri=https://rs1/api/
A this point, there are two possibilities:
- if the authorization server knows the URI(s) associated with the resource server
(either because it was given in the Permission Ticket Request
or because it was statically configured),
it can validate the
resource_uri
parameter and reject the request if they are not identical; - if the authorization server does not know the URIs associated with the resource server, the authorization server cannot reject the request at this point but the resource server will still be able to detect the attacks later on (when receiving the RPT).
When the authorization server issues the RPT, it associates the requested resource server URI to the RPT:
- when the RPT is a JWT, this is communicated with the
rs_uri
claim; - when the authorization server supports token introspection, this is communicated with the
rs_uri
property.
If the resource server supports this extension, it can check that it is the intended audience of the RPT.
Additional constraints on RPTs
A RPT must always be bound to a single audience (resource
) and a single protected resource server:
- The client application should not attempt to use a RPT obtained for an resource server on another resource server.
- The client application should not attempt to upgrade a RPT obtained for a resource server with additional permissions intended for another resource server.
- The authorization server should not upgrade a RPT which was intended for a given resource server with permissions intended for another resource server.
On the other hand, PCTs may be associated with permissions from different resource servers.
Impact for the HEART Profile for UMA
The HEART profile for UMA 2.0 is a UMA profile for healthcare applications. In this sections, we discuss the impact of these vulnerabilities on this profile.
Loose coupling
The HEART profile for UMA 2.0 requires the support for loosely-coupled applications with UMA 2.0 Federated Authorization, dynamic registration of clients and dynamic registration of resource servers. Clients applications may dynamically connect to arbitrary resource servers which would dynamically register on the authorization server. In this scenario, the attack where a client application its tricked into connecting into a malicious resource server is not unlikely.
From the Connection with Protected Resources:
The UMA authorization server MUST implement UMA 2.0 Federated Authorization to allow for dynamic association with protected resources at runtime. The UMA authorization server MUST implement OAuth 2.0 Dynamic Client Registration to allow protected resources to register at runtime with the AS.
From the Component Registration section:
[...] Since all UMA resource servers also act as OAuth clients, they MUST also register with the authorization server under the same requirements as regular OAuth clients.
The authorization server MUST allow for dynamic client registration [of UMA clients]. The authorization server MAY prohibit dynamically registered clients and resource sets from requesting specific scopes, as described in the HEART OAuth 2.0 profile.
ID token as pushed claims
For claims gathering, the HEART profile for UMA 2.0 requires support for pushed-claims as ID tokens and for interactive claims gathering using OpenID Connect login:
The authorization server MUST support claims being presented in at least two methods:
- by redirecting the requesting party to a web page where they can log in to the authorization server using OpenID Connect
- directly by the client in the form of an OpenID Connect ID Token.
[...] Since the audience of an ID token is the client's identifier with the IdP, and this client identifier is known only to the client and the IdP, this restriction effectively means that ID tokens can only be presented at the RPT endpoint in the special case when the authorization server is also the IdP or there is another closely bound relationship between the AS and IdP.
If the legitimate authorization server accepts ID tokens as pushed claims and unless the authorization server enforces the verification of the user consent (using interactive claims gathering) in addition to the pushed claim, as soon as the user logs in on an application, this application would be able to obtain RPTs on the user's behalf without the user's consent. On the other hand, if the authorization server enforces the verification of the user's consent, there is little point in pushing ID tokens anyway.
Pushed ID tokens should be limited to highly trusted client applications. In all other cases, the user consent should be explicitly verified by the client application using interactive claims-gathering.
Conclusion
The UMA 2.0 protocol in its current form has flaws which adversely impacts the the privacy (confidentiality) and integrity of UMA protected resources.
One goal of UMA is to allow the owner of one or more protected resources (on the resource server) to give granular access to these resources to other users (or other third parties such as organizations) and define/manage the policy for accessing to these resources in a privacy-preserving way. An example of intented usage of UMA is for patient-centric data sharing. This flaw may compromises the privacy goals of UMA in many scenarios, especially when used the different actors may be loose-coupled.
The protocol should be extended in order to protect against against this type of vulnerability. This is particularly important when the client applications may interact with arbitrary UMA resource servers.
Possible mitigations include:
- using sender-constrained RPTs (it would be useful to extend the UMA specifications to include this explicitly);
- exhcanging informations about the resource server URI (which would require extending the UMA specifications).
Moreover, it would be useful to add more wording about security considerations to the UMA specification for example:
-
user consent verification
The authorization server should check the user's consent (using the interactive-claims gathering) as a rule. This is especially important if client applications may dynamically register themselves on the authorization server and is important in order to achieve the privacy goals of UMA. This might be skipped if the client application is highly trusted by the authorization server (such as for internal microservices).
Appendix, recap on UMA 2.0
This appendix contains a quick recap of the UMA 2.0 protocol. See my previous post on the topic for some more details.
UMA 2.0 is an extension of OAuth 2.0 where:
- a client application
- obtains a (fine-grained) requesting party token (RPT, an access token for the RS)
- from an authorization server
- on behalf of a user, the requesting party</> (RqP)
- for accessing one or more protected resources (with associated scopes)
- managed by a resource server
- belonging to a user (resource owner) which might be the requesting party or another user;
- according to a policy which may be be defined by resource owner.
The core of the protocol roughly works as follows:
- The client application makes a request on the resource server.
- The resource server determines the permissions required for completing the request and obtains a permission ticket from the authorization server. The permission ticket represents the permissions required for completing the request (resource(s) and associated resource scope(s)).
- The resource server sends this permission ticket to the client application as a way of requesting these permissions from the client application.
- The client application sends this permission ticket to the authorization server as a way of requesting these permissions from the authorization server.
- The authorization server will (typically) authenticate the requesting party (user) and check if this user is allowed to access to the resources and resource scopes according to a policy (typically defined by the resource owner(s) of the affected resource(s)).
- If the access is authorized, the authorization server issues a requesting party token (RPT), i.e., an UMA access token, to the client application. This RPT is associated with the required permissions (resources and scopes).
- The client application repeats the original request on the resource server and includes the RPT.
- The resource server checks that the RPT is associated with the required permissions and processes the request.
References
UMA:
- User-Managed Access (UMA) 2.0 Grant for OAuth 2.0 Authorization
- Federated Authorization for User-Managed Access (UMA) 2.0
- UMA implementations
- Patient-Centric Data Sharing with UMA
HEART:
- HEART for OAuth 2.0
- HEART for FHIR OAuth 2.0 Scopes
- HEART for OpenID Connect 1.0
- HEART for UMA 2.0
- HEART for FHIR UMA 2 Resources
OAuth:
- OAuth 2.1 (draft)
- Resource Indicators for OAuth 2.0 (RFC 8707)
- Proof-of-Possession Key Semantics for JSON Web Tokens (JWTs) (RFC 7800)
- OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens (RFC 8705)
- OAuth 2.0 Demonstrating Proof of Possession (DPoP) (RFC 9449)
- OAuth 2.0 Protected Resource Metadata (draft)
- OAuth Parameters ~ IANA Registry
- OAuth 2.0 Dynamic Client Registration
OAuth security considerations: