A Comprehensive Formal Security Analysis of OAuth
A Comprehensive Formal Security Analysis of OAuth
of OAuth 2.0∗
Daniel Fett Ralf Küsters
University of Trier, Germany University of Trier, Germany
[email protected] [email protected]
Guido Schmitz
arXiv:1601.01229v4 [cs.CR] 8 Aug 2016
The OAuth 2.0 protocol is one of the most widely deployed authorization/single sign-on (SSO) proto-
cols and also serves as the foundation for the new SSO standard OpenID Connect. Despite the popularity
of OAuth, so far analysis efforts were mostly targeted at finding bugs in specific implementations and
were based on formal models which abstract from many web features or did not provide a formal treat-
ment at all.
In this paper, we carry out the first extensive formal analysis of the OAuth 2.0 standard in an ex-
pressive web model. Our analysis aims at establishing strong authorization, authentication, and session
integrity guarantees, for which we provide formal definitions. In our formal analysis, all four OAuth
grant types (authorization code grant, implicit grant, resource owner password credentials grant, and
the client credentials grant) are covered. They may even run simultaneously in the same and different
relying parties and identity providers, where malicious relying parties, identity providers, and browsers
are considered as well. Our modeling and analysis of the OAuth 2.0 standard assumes that security
recommendations and best practices are followed in order to avoid obvious and known attacks.
When proving the security of OAuth in our model, we discovered four attacks which break the security
of OAuth. The vulnerabilities can be exploited in practice and are present also in OpenID Connect.
We propose fixes for the identified vulnerabilities, and then, for the first time, actually prove the
security of OAuth in an expressive web model. In particular, we show that the fixed version of OAuth
(with security recommendations and best practices in place) provides the authorization, authentication,
and session integrity properties we specify.
1
Contents
1 Introduction 5
2 OAuth 2.0 7
3 Attacks 9
3.1 307 Redirect Attack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
3.2 IdP Mix-Up Attack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
3.3 State Leak Attack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.4 Naïve RP Session Integrity Attack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.5 Implications to OpenID Connect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.6 Verification and Disclosure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
4 FKS Model 16
5 Analysis 18
5.1 Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
5.2 Security Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
5.3 Discussion of Results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
6 Related Work 22
7 Conclusion 23
8 Acknowledgements 24
References 24
A OAuth 2.0 27
A.1 Preliminaries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
A.2 OAuth Modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
2
E Detailed Description of the Browser Model 47
E.1 Notation and Terminology (Web Browser State) . . . . . . . . . . . . . . . . . . . . . . 47
E.2 Description of the Web Browser Atomic Process . . . . . . . . . . . . . . . . . . . . . . 49
I Proof of Theorem 1 79
I.1 Proof Outline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
n
I.2 Properties of OWS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
I.3 Proof of Authentication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
I.4 Proof of Authorization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
I.5 Proof of Session Integrity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
3
List of Figures
1 OAuth 2.0 authorization code mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2 Overview of attacks on OAuth 2.0 and OpenID Connect . . . . . . . . . . . . . . . . . . 10
3 Attack on OAuth 2.0 authorization code mode . . . . . . . . . . . . . . . . . . . . . . . 11
4 OAuth 2.0 implicit mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
5 OAuth 2.0 resource owner password credentials mode . . . . . . . . . . . . . . . . . . . 29
6 OAuth 2.0 client credentials mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
7 IdP Mix-Up Attack on OAuth 2.0 implicit mode . . . . . . . . . . . . . . . . . . . . . . 32
8 OpenID Connect 1.0 hybrid mode with discovery and dynamic client registration . . . . 33
9 Attack on OpenID Connect 1.0 hybrid mode with discovery and dynamic client registration 35
10 Equational theory for Σ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
11 Dictionary operators with 1 ≤ i ≤ n . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
12 List of placeholders used in browser algorithms . . . . . . . . . . . . . . . . . . . . . . 50
13 List of scripts in S and their respective string representations. . . . . . . . . . . . . . . . 59
14 List of placeholders used in the relying party algorithm . . . . . . . . . . . . . . . . . . 66
15 Events as described in Lemma 11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
16 Structure of run from start to redirection endpoint . . . . . . . . . . . . . . . . . . . . . 92
List of Algorithms
1 Determine window for navigation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
2 Determine same-origin window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
3 Cancel pending requests for given window . . . . . . . . . . . . . . . . . . . . . . . . . 51
4 Prepare headers, do DNS resolution, save message . . . . . . . . . . . . . . . . . . . . 51
5 Navigate a window backward . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
6 Navigate a window forward . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
7 Execute a script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
8 Process an HTTP response . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
9 Web browser main algorithm. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
10 Relation of a Relying Party Rr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
11 Relation of script_rp_index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
12 Relation of script_rp_implicit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
13 Relation of IdP Ri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
14 Relation of script_idp_form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
4
1. Introduction
The OAuth 2.0 authorization framework [21] defines a web-based protocol that allows a user to grant
web sites access to her resources (data or services) at other web sites (authorization). The former
web sites are called relying parties (RP) and the latter are called identity providers (IdP).1 In practice,
OAuth 2.0 is often used for authentication as well. That is, a user can log in at an RP using her identity
managed by an IdP (single sign-on, SSO).
Authorization and SSO solutions have found widespread adoption in the web over the last years, with
OAuth 2.0 being one of the most popular frameworks. OAuth 2.0, in the following often simply called
OAuth,2 is used by identity providers such as Amazon, Facebook, Google, Microsoft, Yahoo, GitHub,
LinkedIn, StackExchange, and Dropbox. This enables billions of users to log in at millions of RPs or
share their data with these [40], making OAuth one of the most used single sign-on systems on the web.
OAuth is also the foundation for the new single sign-on protocol OpenID Connect, which is already
in use and actively supported by PayPal (“Log In with PayPal”), Google, and Microsoft, among others.
Considering the broad industry support for OpenID Connect, a widespread adoption of OpenID Con-
nect in the next years seems likely. OpenID Connect builds upon OAuth and provides clearly defined
interfaces for user authentication and additional (optional) features, such as dynamic identity provider
discovery and relying party registration, signing and encryption of messages, and logout.
In OAuth, the interactions between the user and her browser, the RP, and the IdP can be performed in
four different flows, or grant types: authorization code grant, implicit grant, resource owner password
credentials grant, and the client credentials grant (we refer to these as modes in the following). In
addition, all of these modes provide further options.
The goal of this work is to provide an in-depth security analysis of OAuth. Analyzing the security of
OAuth is a challenging task, on the one hand due to the various modes and options that OAuth provides,
and on the other hand due to the inherent complexity of the web.
So far, most analysis efforts regarding the security of OAuth were targeted towards finding errors in
specific implementations [6,10,28,38,39,41,43], rather than the comprehensive analysis of the standard
itself. Probably the most detailed formal analysis carried out on OAuth so far is the one in [6]. However,
none of the existing analysis efforts of OAuth account for all modes of OAuth running simultaneously,
which may potentially introduce new security risks. In fact, many existing approaches analyze only the
authorization code mode and the implicit mode of OAuth. Also, importantly, there are no analysis efforts
that are based on a comprehensive formal web model (see below), which, however, is essential to rule
out security risks that arise when running the protocol in the context of common web technologies (see
Section 6 for a more detailed discussion of related work).
Contributions of this Paper. We perform the first extensive formal analysis of the OAuth 2.0 standard
for all four modes, which can even run simultaneously within the same and different RPs and IdPs,
based on a comprehensive web model which covers large parts of how browsers and servers interact in
real-world setups. Our analysis also covers the case of malicious IdPs, RPs, and browsers/users.
Formal model of OAuth. Our formal analysis of OAuth uses an expressive Dolev-Yao style model of
the web infrastructure [14] proposed by Fett, Küsters, and Schmitz (FKS). The FKS model has already
been used to analyze the security of the BrowserID single sign-on system [14, 16] as well as the security
and privacy of the SPRESSO single sign-on system [17]. This web model is designed independently
of a specific web application and closely mimics published (de-facto) standards and specifications for
the web, for instance, the HTTP/1.1 and HTML5 standards and associated (proposed) standards. It is
1 Following the OAuth 2.0 terminology, IdPs are called authorization servers and resource servers, RPs are called clients,
and users are called resource owners. Here, however, we stick to the more common terms mentioned above.
2 Note that in this document, we consider only OAuth 2.0, which is very different to its predecessor, OAuth 1.0(a).
5
the most comprehensive web model to date. Among others, HTTP(S) requests and responses, including
several headers, such as cookie, location, strict transport security (STS), and origin headers, are modeled.
The model of web browsers captures the concepts of windows, documents, and iframes, including the
complex navigation rules, as well as new technologies, such as web storage and web messaging (via
postMessage). JavaScript is modeled in an abstract way by so-called scripts which can be sent around
and, among others, can create iframes and initiate XMLHTTPRequests (XHRs). Browsers may be
corrupted dynamically by the adversary.
Using the generic FKS model, we build a formal model of OAuth, closely following the OAuth 2.0
standard (RFC6749 [21]). Since this RFC does not fix all aspects of the protocol and in order to avoid
known implementation attacks, we use the OAuth 2.0 security recommendations (RFC6819 [29]), addi-
tional RFCs and OAuth Working Group drafts (e.g., RFC7662 [33], [8]) and current web best practices
(e.g., regarding session handling) to obtain a model of OAuth with state-of-the-art security features in
place, while making as few assumptions as possible. Moreover, as mentioned above, our model includes
RPs and IdPs that (simultaneously) support all four modes and can be dynamically corrupted by the
adversary. Also, we model all configuration options of OAuth (see Section 2).
Formalization of security properties. Based on this model of OAuth, we provide three central security
properties of OAuth: authorization, authentication, and session integrity, where session integrity in turn
is concerned with both authorization and authentication.
Attacks on OAuth 2.0 and fixes. While trying to prove these properties, we discovered four attacks on
OAuth. In the first attack, which breaks the authorization and authentication properties, IdPs inadver-
tently forward user credentials (i.e., username and password) to the RP or the attacker. In the second
attack (IdP mix-up), a network attacker playing the role of an IdP can impersonate any victim. This
severe attack, which again breaks the authorization and authentication properties, is caused by a logical
flaw in the OAuth 2.0 protocol. Two further attacks allow an attacker to force a browser to be logged in
under the attacker’s name at an RP or force an RP to use a resource of the attacker instead of a resource
of the user, breaking the session integrity property. We have verified all four attacks on actual imple-
mentations of OAuth and OpenID Connect. We present our attacks on OAuth in detail in Section 3. In
Appendix B.1 we show how the attacks can be exploited in OpenID Connect. We also show how the
attacks can be fixed by changes that are easy to implement in new and existing deployments of OAuth
and OpenID Connect.
We notified the respective working groups, who confirmed the attacks and that changes to the stan-
dards/recommendations are needed. The IdP mix-up attack already resulted in a draft of a new RFC [24].
Formal analysis of OAuth 2.0. Using our model of OAuth with the fixes in place, we then were able to
prove that OAuth satisfies the mentioned security properties. This is the first proof which establishes
central security properties of OAuth in a comprehensive and expressive web model (see also Section 6).
We emphasize that, as mentioned before, we model OAuth with security recommendations and best
practices in place. As discussed in Section 5, implementations not following these recommendations
and best practices may be vulnerable to attacks. In fact, many such attacks on specific implementations
have been pointed out in the literature (e.g., [6, 10, 21, 28, 29, 41, 42]). Hence, our results also provide
guidelines for secure OAuth implementations.
We moreover note that, while these results provide strong security guarantees for OAuth, they do
not directly imply security of OpenID Connect because OpenID Connect adds specific details on top of
OAuth. We leave a formal analysis of OpenID Connect to future work. The results obtained here can
serve as a good foundation for such an analysis.
Structure of this Paper. In Section 2, we provide a detailed description of OAuth 2.0 using the au-
thorization code mode as an example. In Section 3, we present the attacks that we found during our
analysis. An overview of the FKS model we build upon in our analysis is provided in Section 4, with the
6
formal analysis of OAuth presented in Section 5. Related work is discussed in Section 6. We conclude
in Section 7. Full details, including how the attacks can be applied to OpenID Connect, further details
on our model of OAuth, and our security proof, can be found in the appendix.
2. OAuth 2.0
In this section, we provide a description of the OAuth authorization code mode, with the other three
modes explained only briefly. In Appendix A, we provide a detailed description of the remaining three
modes (grant types).
OAuth was first intended for authorization, i.e., users authorize RPs to access user data (called pro-
tected resources) at IdPs. For example, a user can use OAuth to authorize services such as IFTTT3 to
access her (private) timeline on Facebook. In this case, IFTTT is the RP and Facebook the IdP.
Roughly speaking, in the most common modes, OAuth works as follows: If a user wants to authorize
an RP to access some of the user’s data at an IdP, the RP redirects the user (i.e., the user’s browser) to
the IdP, where the user authenticates and agrees to grant the RP access to some of her user data at the
IdP. Then, along with some token (an authorization code or an access token) issued by the IdP, the user
is redirected back to the RP. The RP can then use the token as a credential at the IdP to access the user’s
data at the IdP.
OAuth is also commonly used for authentication, although it was not designed with authentication in
mind. A user can, for example, use her Facebook account, with Facebook being the IdP, to log in at the
social network Pinterest (the RP). Typically, in order to log in, the user authorizes the RP to access a
unique user identifier at the IdP. The RP then retrieves this identifier and considers this user to be logged
in.
Before an RP can interact with an IdP, the RP needs to be registered at the IdP. The details of the
registration process are out of the scope of the OAuth protocol. In practice, this process is usually a
manual task. During the registration process, the IdP assigns credentials to the RP: a public OAuth
client id and (optionally) a client secret. (Recall that in the terminology of the OAuth standard the term
“client” stands for RP.) The RP may later use the client secret (if issued) to authenticate to the IdP.
Also, an RP registers one or more redirection endpoint URIs (located at the RP) at an IdP. As we will
see below, in some OAuth modes, the IdP redirects the user’s browser to one of these URIs. Note that
(depending on the implementation of an IdP) an RP may also register a pattern as a redirect URI and
then specify the exact redirect URI during the OAuth run.
In all modes, OAuth provides several options, such as those mentioned above. For brevity of presen-
tation (and in contrast to our analysis), in the following descriptions, we consider only a specific set of
options. For example, we assume that an RP always provides a redirect URI and shares an OAuth client
secret with the IdP.
Authorization Code Mode. When the user tries to authorize an RP to access her data at an IdP or to
log in at an RP, the RP first redirects the user’s browser to the IdP. The user then authenticates to the IdP,
e.g., by providing her user name and password, and finally is redirected back to the RP along with an
authorization code generated by the IdP. The RP can now contact the IdP with this authorization code
(along with the client id and client secret) and receive an access token, which the RP in turn can use as
a credential to access the user’s protected resources at the IdP.
Step-by-Step Protocol Flow. In what follows, we describe the protocol flow of the authorization code
mode step-by-step (see also Figure 1). First, the user starts the OAuth flow, e.g., by clicking on a button
3 IFTTT (If This Then That) is a web service which can be used to automate actions: IFTTT is triggered by user-defined
events (e.g., Twitter messages) and carries out user-defined tasks (e.g., posting on the user’s Facebook wall).
7
Browser RP IdP
1 POST /start
idp
2 Response
Redirect to IdP /authEP with client_id, redirect_uri, state
3 GET /authEP
client_id, redirect_uri, state
4 Response
5 POST /authEP
username, password
6 Response
Redirect to RP redirect_uri with code, state
7 GET redirect_uri
code, state
8 POST /tokenEP
code, client_id, redirect_uri, client_secret
9 Response
access_token
Authorization:
10 GET /resource
access_token
11 Response
protected resource
Authentication:
12 GET /introspectionEP
access_token
13 Response
user_id, client_id
14 Response
session_cookie
Figure 1. OAuth 2.0 authorization code mode. Note that data depicted below the arrows is either transferred in
URI parameters, HTTP headers, or POST bodies.
to select an IdP, resulting in request 1 being sent to the RP. The RP selects one of its redirection endpoint
URIs redirect_uri (which will be used later in 7 ) and a value state (which will serve as a token to prevent
CSRF attacks). The RP then redirects the browser to the so-called authorization endpoint URI at the IdP
in 2 and 3 with its client_id, redirect_uri, and state appended as parameters to the URI. The IdP then
prompts the user to provide her username and password in 4 . The user’s browser sends this information
to the IdP in 5 . If the credentials are correct, the IdP creates a nonce code (the authorization code) and
redirects the user’s browser to RP’s redirection endpoint URI redirect_uri in 6 and 7 with code and
state appended as parameters to the URI. If state is the same as above, the RP contacts the IdP in 8 and
provides code, client_id, client_secret, and redirect_uri. Then the IdP checks whether this information
is correct, i.e., it checks that code was issued for the RP identified by client_id, that client_secret is
the secret for client_id, that redirect_uri coincides with the one in Step 2 , and that code has not been
redeemed before. If these checks are successful, the IdP issues an access token access_token in 9 . Now,
8
the RP can use access_token to access the user’s protected resources at the IdP (authorization) or log in
the user (authentication), as described next.
When OAuth is used for authorization, the RP uses the access token to view or manipulate the pro-
tected resource at the IdP (illustrated in Steps 10 and 11 ).
For authentication, the RP fetches a user id (which uniquely identifies the user at the IdP) using the
access token, Steps 12 and 13 . The RP then issues a session cookie to the user’s browser as shown
in 14 .4
Tracking User Intention. Note that in order for an RP which supports multiple IdPs to process Step 7 ,
the RP must know which IdP a user wanted to use for authorization. There are two different approaches
to this used in practice: First, the RP can use different redirection URIs to distinguish different IdPs.
We call this naïve user intention tracking. Second, the RP can store the user intention in a session after
Step 1 and use this information later. We call this explicit user intention tracking. The same applies to
the implicit mode of OAuth presented below.
Implicit Mode. This mode is similar to the authorization code mode, but instead of providing an autho-
rization code, the IdP directly delivers an access token to the RP via the user’s browser.
More specifically, in the implicit mode, Steps 1 – 5 (see Figure 1) are the same as in the authorization
code mode. Instead of creating an authorization code, the IdP issues an access token right away and
redirects the user’s browser to RP’s redirection endpoint with the access token contained in the fragment
of the URI. (Recall that a fragment is a special part of a URI indicated by the ‘#’ symbol.)
As fragments are not sent in HTTP requests, the access token is not immediately transferred when
the browser contacts the RP. Instead, the RP needs to use a JavaScript to retrieve the contents of the
fragment. Typically, such a JavaScript is sent in RP’s answer at the redirection endpoint. Just as in
the authorization code mode, the RP can now use the access token for authorization or authentication
(analogously to Steps 10 – 14 of Figure 1).5
Resource Owner Password Credentials Mode. In this mode, the user gives her credentials for an IdP
directly to an RP. The RP can then authenticate to the IdP on the user’s behalf and retrieve an access
token. This mode is intended for highly-trusted RPs, such as the operating system of the user’s device
or highly-privileged applications, or if the previous two modes are not possible to perform (e.g., for
applications without a web browser).
Client Credentials Mode. In contrast to the modes shown above, this mode works without the user’s
interaction. Instead, it is started by an RP in order to fetch an access token to access the resources of
RP at an IdP. For example, Facebook allows RPs to use the client credentials mode to obtain an access
token to access reports of their advertisements’ performance.
3. Attacks
As mentioned in the introduction, while trying to prove the security of OAuth based on the FKS web
model and our OAuth model, we found four attacks on OAuth, which we call 307 redirect attack, IdP
mix-up attack, state leak attack, and naïve RP session integrity attack, respectively. In this section, we
provide detailed descriptions of these attacks along with easily implementable fixes. Our formal analysis
of OAuth (see Section 5) then shows that these fixes are indeed sufficient to establish the security of
4 Authentication is not part of RFC6749, but this method for authentication is commonly used in practice, for example by
Amazon, Facebook, LinkedIn, and StackExchange, and is also defined in OpenID Connect [35].
5 The response from the IdP in Step 13 includes the RP’s OAuth client id, which is checked by the RP when authenticating
a user (cf. RFC7662 [33]). This check prevents re-use of access tokens across RPs in the OAuth implicit mode, as explained
in [42]. This check is not needed for authorization.
9
attack on OAuth applicable to OpenID Connect
auth code mode implicit mode auth code mode implicit mode hybrid mode
307 Redirect Attack az + an az + an az + an az + an az + an
IdP Mix-Up Attack az* + an az + an az* + an – az + an**
State Leak Attack si si si si si
Naïve RP Session Integrity Att. si si si si si
az: breaks authorization. an: breaks authentication. si: breaks session integrity. –: not applicable. * if client secrets are not
used. ** restriction: if client secrets are used, either authorization or authentication is broken, depending on implementation
details.
OAuth. The attacks also apply to OpenID Connect (see Section 3.5). Figure 2 provides an overview
of where the attacks apply. We have verified our attacks on actual implementations of OAuth and
OpenID Connect and reported the attacks to the respective working groups who confirmed the attacks
(see Section 3.6).
Assumption (2). This assumption is reasonable as many examples for redirects immediately after enter-
ing the user credentials can be found in practice, for example at github.com (where, however, assump-
tion (1) is not satisfied.)
Attack. When a user uses the authorization code or implicit mode of OAuth to log in at a malicious
RP, then she is redirected to the IdP and prompted to enter her credentials. The IdP then receives these
credentials from the user’s browser in a POST request. It checks the credentials and redirects the user’s
browser to the RP’s redirection endpoint in the response to the POST request. Since the 307 status code
is used for this redirection, the user’s browser will send a POST request to RP that contains all form data
from the previous request, including the user credentials. Since the RP is run by the attacker, he can use
these credentials to impersonate the user.
Fix. Contrary to the current wording in the OAuth standard, the exact method of the redirect is not an
implementation detail but essential for the security of OAuth. In the HTTP standard [19], only the 303
redirect is defined unambiguously to drop the body of an HTTP POST request. Therefore, the OAuth
standard should require 303 redirects for the steps mentioned above in order to fix this problem.
10
Browser RP Attacker (AIdP) HIdP
1 POST /start
idp
2 POST /start
attacker
3 Response
Redirect to Attacker /authEP with client_id′ , redirect_uri, state
4 Response
Redirect to HIdP /authEP with client_id, redirect_uri, state
5 GET /authEP
client_id, redirect_uri, state
6 Response
7 POST /authEP
username, password
8 Response
Redirect to RP redirect_uri with code, state
9 GET redirect_uri
code, state
10 POST /tokenEP
code, client_id′ , redirect_uri, client_secret′
11
We here present the attack in the authorization code mode. In the implicit mode, the attack is very
similar and is shown in detail in Appendix B.
Assumptions. For the IdP mix-up attack to work, we need three assumptions that we further discuss
below: (1) the presence of a network attacker who can manipulate the request in which the user sends her
identity to the RP as well as the corresponding response to this request (see Steps 1 and 2 in Figure 1),
(2) an RP which allows users to log in with identities provided by (some) HIdP and identities provided
by AIdP, and (3) an RP that uses explicit user intention tracking and issues the same redirection URI to
all IdPs.7 We emphasize that we do not assume that the user sends any secret (such as passwords) over
an unencrypted channel.
Assumption (1). It would be unrealistic to assume that a network attacker can never manipulate Steps 1
and 2 in Figure 1.
First, these messages are sent between the user and the RP, i.e., the attacker does not need to intercept
server-to-server communication. He could, e.g., use ARP spoofing in a wifi network to mount the attack.
Second, the need for HTTPS for these steps is not obvious to users or RPs, and the use of HTTPS is
not suggested by the OAuth security recommendations, since the user only selects an IdP at this point;
credentials are not transferred.
Third, even if an RP intends to use HTTPS also for the first request (as in our model), it has to protect
itself against TLS stripping by adding the RP domain to a browser preloaded Strict Transport Security
(STS) list [11]. Other mitigations, such as the STS header, can be circumvented (see [37]), and do not
work on the very first connection between the user’s browser and RP. For example, when a user enters
the address of an RP into her browser, browsers by default try unencrypted connections. It is therefore
unrealistic to assume that all RPs are always protected against TLS stripping.
Our formal analysis presented in Section 5 shows that OAuth can be operated securely even if no
HTTPS is used for the initial request (given that our fix, presented below, is applied).
Assumption (2). RPs may use different IdPs, some of which might be malicious, and hence, OAuth
should provide security in this case. Using a technique called dynamic client registration, OAuth RPs
can even allow the ad-hoc use of any IdP, including malicious ones. This is particularly relevant in
OpenID Connect, where this technique was first implemented.
Assumption (3). Typically, RPs that use explicit user intention tracking do not register different redirec-
tion URIs for different IdPs, as in this case the RP records the IdP a user wants to authenticate with. In
particular, for RPs that allow for dynamic registration, using the same URI is an obvious implementation
choice. This is for example the case in the OAuth/OpenID Connect implementations mod_auth_openidc
and pyoidc (see below).
Attack on Authorization Code Mode. We now describe the IdP Mix-Up attack on the OAuth autho-
rization code mode. As mentioned, a very similar attack also applies to the implicit mode. Both attacks
also work if IdP supports just one of these two modes.
The IdP mix-up attack for the authorization code mode is depicted in Figure 3. Just as in a regular flow,
the attack starts when the user selects that she wants to log in using HIdP (Step 1 in Figure 3). Now, the
attacker intercepts the request intended for the RP and modifies the content of this request by replacing
HIdP by AIdP.8 The response of the RP 3 (containing a redirect to AIdP) is then again intercepted and
modified by the attacker such that it redirects the user to HIdP 4 . The attacker also replaces the OAuth
7 Alternatively, the attack would work if the RP issues different redirection URIs to different IdPs, but treats them as the
same URI.
8 At this point, the attacker could also read the session id for the user’s session at RP. Our attack, however, is not based on
this possibility and works even if the RP changes this session id as soon as the user is logged in and the connection is protected
by HTTPS (a best practice for session management).
12
client id of the RP at AIdP with the client id of the RP at HIdP (which is public information). (Note
that we assume that from this point on, in accordance with the OAuth security recommendations, the
communication between the user’s browser and HIdP and the RP is encrypted by using HTTPS, and thus,
cannot be inspected or altered by the attacker.) The user then authenticates to HIdP and is redirected
back to the RP 8 . The RP thinks, due to Step 2 of the attack, that the nonce code contained in this
redirect was issued by AIdP, rather than HIdP. The RP therefore now tries to redeem this nonce for an
access token at AIdP 10 , rather than HIdP. This leaks code to the attacker.
Breaking Authorization. If HIdP has not issued an OAuth client secret to RP during registration, the
attacker can now redeem code for an access token at HIdP (in 11 and 12 ).9 This access token allows the
attacker to access protected resources of the user at HIdP. This breaks the authorization property (see
Section 5.2). We note that at this point, the attacker might even provide false information about the user
or her protected resources to the RP: he could issue a self-created access token which RP would then
use to access such information at the attacker.
Breaking Authentication. To break the authentication property (see Section 5.2) and impersonate the
honest user, the attacker, after obtaining code in Step 10 , starts a new login process (using his own
browser) at the RP. He selects HIdP as the IdP for this login process and receives a redirect to HIdP,
which he ignores. This redirect contains a cookie for a new login session and a fresh state parameter.
The attacker now sends code to the RP imitating a real login (using the cookie and fresh state value from
the previous response). The RP then retrieves an access token at HIdP using code and uses this access
token to fetch the (honest) user’s id. Being convinced that the attacker owns the honest user’s account,
the RP issues a session cookie for this account to the attacker. As a result, the attacker is logged in at the
RP under the honest user’s id. (Note that the attacker does not learn an access token in this case.)
Variant. There is also a variant of the IdP mix-up attack that only requires a web attacker (which does
not intercept and manipulate network messages). In this variant, the user wants to log in with AIdP, but
is redirected by AIdP to log in at HIdP; a fact a vigilant user might detect.
In detail, the first four steps in Figure 3 are replaced by the following steps: First, the user starts a new
OAuth flow with RP using AIdP. She is then redirected by RP to AIdP’s authorization endpoint. Now,
instead of prompting the user for her password, AIdP redirects the user to HIdP’s authorization endpoint.
(Note that, as above, in this step, the attacker uses the state value he received from the browser plus the
client id of RP at HIdP.) From here on, the attack proceeds exactly as in Step 5 in Figure 3.
Related Attacks. An attack in the same class, cross social-network request forgery, was outlined by
Bansal, Bhargavan, Delignat-Lavaud, and Maffeis in [6]. It applies to RPs with naïve user intention
tracking (rather than explicit user intention tracking assumed in our IdP mix-up attack above) in combi-
nation with IdPs, such as Facebook, that only loosely check the redirect URI.10 Our IdP mix-up attack
works even if an IdP strictly checks redirect URIs. While the attack in [6] is described in the context of
concrete social network implementations, our findings show that this class of attacks is not merely an
implementation error, but a more general problem in the OAuth standard. This was confirmed by the
IETF OAuth Working Group, who, as mentioned, are in the process of amending the OAuth standard
according to our fixes (see Section 3.6).
Another attack with a similar outcome, called Malicious Endpoints Attack, leveraging the OpenID
Connect Discovery mechanism and therefore limited to OpenID Connect, was described in [30]. This
attack assumes a CSRF vulnerability on the RP’s side.
Fix. A fundamental problem in the authorization code and implicit modes of the OAuth standard is a
9 In the case that RP has to provide a client secret, this would not work in this mode (see also Figure 2). Recall that in this
13
lack of reliable information in the redirect in Steps 6 and 7 in Figure 1 (even if HTTPS is used). The RP
does not receive information from where the redirect was initiated (when explicit user intention tracking
is used) or receives information that can easily be spoofed (when naïve user intention tracking is used
with IdPs such as Facebook). Hence, the RP cannot check whether the information contained in the
redirect stems from the IdP that was indicated in Step 1 .
Our fix therefore is to include the identity of the IdP in the redirect URI in some form that cannot be
influenced by the attacker, e.g., using a new URI parameter. Each IdP should add such a parameter to the
redirect URI.11 The RP can then check that the parameter contains the identity of the IdP it expects to
receive the response from. (This could be used with either naïve or explicit user intention tracking, but
to mitigate the naïve RP session integrity attack described below, we advise to use explicit user intention
tracking only, see below.)
We show in Section 5 that this fix is indeed sufficient to mitigate the IdP mix-up attack (as well as the
attacks pointed out in [6, 30]).
11 The OAuth Working Group indeed created a draft for an RFC [24] that includes this fix, where this parameter is called
iss (issuer).
14
or loads resources for some web page. The Referer header can be blocked entirely, or it can, for example,
be stripped down to the origin of the URI of the web page. Referrer policies are supported by all modern
browsers.
Our OAuth model includes this fix (such that only the origin is permitted in the Referer header for
links on web pages of RPs/IdPs) and our security proof shows its effectiveness (see Section 5). The fix
also protects the authorization code from leaking as in the attack described in [22].
15
up attack on the python implementation pyoidc. We verified the state leak attack on the current version
of the Facebook PHP SDK and the naïve RP session integrity attack on nytimes.com.13
We reported all attacks to the OAuth and OpenID Connect working groups who confirmed the attacks.
The OAuth working group invited us to present our findings to them and prepared a draft for an RFC that
mitigates the IdP mix-up attack (using the fix described in Section 3.2) [24]. Fixes regarding the other
attacks are currently under discussion. We also notified nytimes.com, Facebook, and the developers of
mod_auth_openidc and pyoidc.
4. FKS Model
Our formal security analysis of OAuth is based on a slightly extended version (see Section 5.1) of the
FKS model, a general Dolev-Yao (DY) style web model proposed by Fett et al. in [14, 17]. This model
is designed independently of a specific web application and closely mimics published (de-facto) stan-
dards and specifications for the web, for example, the HTTP/1.1 and HTML5 standards and associated
(proposed) standards. The FKS model defines a general communication model, and, based on it, web
systems consisting of web browsers, DNS servers, and web servers as well as web and network attackers.
Here, we only briefly recall the FKS model (see [14, 17] for a full description, comparison with other
models, and a discussion of its limitations); see also Appendices C–E.
Communication Model. The main entities in the model are (atomic) processes, which are used to model
browsers, servers, and attackers. Each process listens to one or more (IP) addresses. Processes commu-
nicate via events, which consist of a message as well as a receiver and a sender address. In every step of
a run, one event is chosen non-deterministically from a “pool” of waiting events and is delivered to one
of the processes that listens to the event’s receiver address. The process can then handle the event and
output new events, which are added to the pool of events, and so on.
As usual in DY models (see, e.g., [1]), messages are expressed as formal terms over a signature
Σ. The signature contains constants (for (IP) addresses, strings, nonces) as well as sequence, projec-
tion, and function symbols (e.g., for encryption/decryption and signatures). For example, in the web
model, an HTTP request is represented as a term r containing a nonce, an HTTP method, a domain
name, a path, URI parameters, headers, and a message body. For example, a request for the URI
http://example.com/s?p=1 is represented as
where the body and the headers are empty. An HTTPS request for r is of the form enca (hr, k′ i, pub(kexample.com )),
where k′ is a fresh symmetric key (a nonce) generated by the sender of the request (typically a browser);
the responder is supposed to use this key to encrypt the response.
The equational theory associated with Σ is defined as usual in DY models. The theory induces a
congruence relation ≡ on terms, capturing the meaning of the function symbols in Σ. For instance, the
equation in the equational theory which captures asymmetric decryption is deca (enca (x, pub(y)), y) = x.
With this, we have that, for example,
i.e., these two terms are equivalent w.r.t. the equational theory.
A (DY) process consists of a set of addresses the process listens to, a set of states (terms), an initial
state, and a relation that takes an event and a state as input and (non-deterministically) returns a new
13 mod_auth_openidc and nytimes.com are not susceptible to the state leak attack since after the login/authorization, the
16
state and a sequence of events. The relation models a computation step of the process. It is required that
the output can be computed (more formally, derived in the usual DY style) from the input event and the
state.
The so-called attacker process is a DY process which records all messages it receives and outputs
all events it can possibly derive from its recorded messages. Hence, an attacker process carries out all
attacks any DY process could possibly perform. Attackers can corrupt other parties.
A script models JavaScript running in a browser. Scripts are defined similarly to DY processes. When
triggered by a browser, a script is provided with state information. The script then outputs a term repre-
senting a new internal state and a command to be interpreted by the browser (see also the specification
of browsers below). Similarly to an attacker process, the so-called attacker script may output everything
that is derivable from the input.
A system is a set of processes. A configuration of this system consists of the states of all processes
in the system, the pool of waiting events, and a sequence of unused nonces. Systems induce runs, i.e.,
sequences of configurations, where each configuration is obtained by delivering one of the waiting events
of the preceding configuration to a process, which then performs a computation step.
A web system formalizes the web infrastructure and web applications. It contains a system consisting
of honest and attacker processes. Honest processes can be web browsers, web servers, or DNS servers.
Attackers can be either web attackers (who can listen to and send messages from their own addresses
only) or network attackers (who may listen to and spoof all addresses and therefore are the most powerful
attackers). A web system further contains a set of scripts (comprising honest scripts and the attacker
script).
In our analysis of OAuth, we consider either one network attacker or a set of web attackers (see
Section 5). In our OAuth model, we need to specify only the behavior of servers and scripts. These
are not defined by the FKS model since they depend on the specific application, unless they are corrupt
or become corrupted in which case they behave like attacker processes and attacker scripts; browsers
are specified by the FKS model (see below). The modeling of OAuth servers and scripts is outlined in
Section 5.1 and defined in detail in Appendices F and G.
Web Browsers. An honest browser is thought to be used by one honest user, who is modeled as part
of the browser. User actions, such as following a link, are modeled as non-deterministic actions of the
web browser. User credentials are stored in the initial state of the browser and are given to selected web
pages when needed. Besides user credentials, the state of a web browser contains (among others) a tree
of windows and documents, cookies, and web storage data (localStorage and sessionStorage).
A window inside a browser contains a set of documents (one being active at any time), modeling
the history of documents presented in this window. Each represents one loaded web page and contains
(among others) a script and a list of subwindows (modeling iframes). The script, when triggered by
the browser, is provided with all data it has access to, such as a (limited) view on other documents and
windows, certain cookies, and web storage data. Scripts then output a command and a new state. This
way, scripts can navigate or create windows, send XHRs and postMessages, submit forms, set/change
cookies and web storage data, and create iframes. Navigation and security rules ensure that scripts can
manipulate only specific aspects of the browser’s state, according to the web standards.
A browser can output messages on the network of different types, namely DNS and HTTP(S) requests
as well as XHRs, and it processes the responses. Several HTTP(S) headers are modeled, including, for
example, cookie, location, strict transport security (STS), and origin headers. A browser, at any time, can
also receive a so-called trigger message upon which the browser non-deterministically chooses an action,
for instance, to trigger a script in some document. The script now outputs a command, as described
above, which is then further processed by the browser. Browsers can also become corrupted, i.e., be
taken over by web and network attackers. Once corrupted, a browser behaves like an attacker process.
17
5. Analysis
We now present our security analysis of OAuth (with the fixes mentioned in Section 3 applied). We
first present our model of OAuth. We then formalize the security properties and state the main theorem,
namely the security of OAuth w.r.t. these properties. We provide full details of the model and our proof
in Appendices F–I.
5.1. Model
As mentioned above, our model for OAuth is based on the FKS model outlined in Section 4. For the
analysis, we extended the model to include HTTP Basic Authentication [20] and Referrer Policies [13]
(the Referer header itself was already part of the model). We developed the OAuth model to adhere to
RFC6749, the OAuth 2.0 standard, and follow the security considerations described in [29].
Design. Our comprehensive model of OAuth includes all configuration options of OAuth and makes as
few assumptions as possible in order to strengthen our security results:
OAuth Modes. Every RP and IdP may run any of the four OAuth modes, even simultaneously.
Corruption. RPs, IdPs, and browsers can be corrupted by the attacker at any time.
Redirection URIs. RP chooses redirection URIs explicitly or the IdP selects a redirection URI that was
registered before. Redirection URIs can contain patterns. This covers all cases specified in the OAuth
standard. We allow that IdPs do not strictly check the redirection URIs, and instead apply loose checking,
i.e., only the origin is checked (this is the default for Facebook, for example). This only strengthens the
security guarantees we prove.
Client Secrets. Just as in the OAuth standard, RPs can, for a certain IdP, have a secret or not have a secret
in our model.
Usage of HTTP and HTTPS. Users may visit HTTP and HTTPS URIs (e.g., for RPs) and parties are
not required to use Strict-Transport-Security (STS), although we still recommend STS in practice (for
example, to reduce the risk of password eavesdropping). Again, this only strengthens our results.
General User Interaction. As usual in the FKS model, the user can at any time navigate backwards or
forward in her browser history, navigate to any web page, open multiple windows, start simultaneous
login flows using different or the same IdPs, etc. Web pages at RPs can contain regular links to arbitrary
external web sites.
Authentication at IdP. User authentication at the IdP, which is out of the scope of OAuth, is performed
using username and password.
Session Mechanism at RP. OAuth does not prescribe a specific session mechanism to be used at an RP.
Our model therefore includes a standard cookie-based session mechanism (as suggested in [8]).
Attack Mitigations. To prove the security properties of OAuth, our model includes the fixes against the
new attacks presented in Section 3 as well as standard mitigations against known attacks. Altogether
this offers clear implementation guidelines, without which OAuth would be insecure:
Honest Parties. RPs and IdPs, as long as they are honest, do not include (untrusted) third-party JavaScript
on their websites, do not contain open redirectors, and do not have Cross-Site Scripting vulnerabilities.
Otherwise, access tokens and authorization codes can be stolen in various ways, as described, among
others, in [6, 21, 29, 41].
CSRF Protection. The state parameter is used with a nonce that is bound to the user’s session (see [8])
to prevent CSRF vulnerabilities on the RP redirection endpoint. Omitting or incorrectly using this
parameter can lead to attacks described in [6, 21, 28, 29, 41].
18
More specifically, a new state nonce is freshly chosen for each login attempt. Otherwise, the following
attack is applicable: First, a user starts an OAuth flow at some RP using a malicious IdP. The IdP learns
the state value that is used in the current user session. Then, as soon as the user starts a new OAuth flow
with the same RP and an honest IdP, the malicious IdP can use the known state value to mount a CSRF
attack, breaking the session integrity property.14
We also model CSRF protection for some URIs as follows: For RPs, we model origin header check-
ing15 (1) at the URI where the OAuth flow is started (for the implicit and authorization code mode), (2)
at the password login for the resource owner password credentials mode, and (3) at the URI to which
the JavaScript posts the access token in the implicit mode. For IdPs, we do the same at the URI to
which the username and password pairs are posted. The CSRF protection of these four URIs is out of
the scope of OAuth and therefore, we follow good web development practices by checking the origin
header. Without this or similar CSRF protection, IdPs and RPs would be vulnerable to CSRF attacks
described in [6, 41].
Referrer Policy and Status Codes. RPs and IdPs use the Referrer Policy [13] to specify that Referer
headers on links from any of their web pages may not contain more than the origin of the respective
page. Otherwise, RPs or IdPs would be vulnerable to the state leak attack described in Section 3.3 and
the code leak attack described in [22]. IdPs use 303 redirects following our fix described in Section 3.1.
HTTPS Endpoints. All endpoint URIs use HTTPS to protect against attackers eavesdropping on tokens
or manipulating messages (see, e.g., [29, 41]). Obviously, IdPs or RPs do not register URIs that point to
servers other than their own. (Otherwise, access tokens or authorization codes can be stolen trivially.)
Session Cookies. Cookies are always set with the secure attribute, ensuring that the cookie value is only
transmitted over HTTPS. Otherwise, a network attacker could read cookie values by eavesdropping on
non-HTTPS connections to RPs. After successful login at an RP, the RP creates a fresh session id for
that user. Otherwise, a network attacker could set a login session cookie that is bound to a known state
value into the user’s browser (see [44]), lure the user into logging in at the corresponding RP, and then
use the session cookie to access the user’s data at the RP (session fixation, see [31]).
Authentication to the IdP. It is assumed that the user only ever sends her password over an encrypted
channel and only to the IdP this password was chosen for (or to trusted RPs, as mentioned above). (The
user also does not re-use her password for different IdPs.) Otherwise, a malicious IdP would be able to
use the account of the user at an honest IdP.
Authentication using Access Tokens. When an RP sends an access token to the introspection endpoint of
an IdP for authentication (Step 12 in Figure 1), the IdP returns the user identifier and the client id for
which the access token was issued (Step 13 ). The RP must check that the returned client id is its own,
otherwise a malicious RP could impersonate an honest user at an honest RP (see [21, 42]). We therefore
require this check.
User Intention Tracking. We use explicit user intention tracking. Otherwise, the attack described in
Section 3.4 can be applied.
Concepts Used in Our Model. In our model and the security properties, we use the following concepts:
Protected Resources. Closely following RFC6749 [21], OAuth protected resources are an abstract con-
cept for any resource an RP could use at an IdP after successful authorization. For example, if Facebook
14 Note that in this attack, the state value does not leak unintentionally (in contrast to the state leak attack). Also note that
this attack and the mitigation we describe here, while not surprising, do not seem to have been explicitly documented so far.
For example, nytimes.com is vulnerable also to this attack.
15 The origin header is added to certain HTTP(S) requests by browsers to declare the origin of the document that caused
the request. For example, when a user submits a form loaded from the URI http://a/form and this form is sent to http:
//b/path then the browser will add the origin header http://a in the request to b. All modern browsers support origin
headers. See [12] for details.
19
gives access to the friends list of a user to an RP, this would be considered a protected resource. In our
model, there is a mapping from (IdP, RP, identity) to nonces (which model protected resources). In this
mapping, the identity part can be ⊥, modeling a resource that is acquired in the client credentials mode
and thus not bound to a user.
Service Tokens. When OAuth is used for authentication, we assume that after successful login, the RP
sends a service token to the browser. The intuition is that with this service token a user can use the
services of the RP. The service token consists of a nonce, the user’s identifier, and the domain of the IdP
which was used in the login process. The service token is a generic model for any session mechanism the
RP could use to track the user’s login status (e.g., a cookie). We note that the actual session mechanism
used by the RP after a successful login is out of the scope of OAuth, which is why we use the generic
concept of a service token. In our model, the service token is delivered by an RP to a browser as a
cookie.
Trusted RPs. In our model, among others, a browser can choose to launch the resource owner password
credentials mode with any RP, causing this RP to know the password of the user. RPs, however, can
become corrupted and thus leak the password to the attacker. Therefore, to define the security properties,
we define the concept of trusted RPs. Intuitively, this is a set of RPs a user entrusts with her password.
In particular, whether an RP is trusted depends on the user. In our security properties, when we state that
an adversary should not be able to impersonate a user u in a run, we would assume that all trusted RPs
of u have not become corrupted in this run.
OAuth Web System with a Network Attacker. We model OAuth as a class of web systems (in the
sense of Section 4) that can contain an unbounded finite number of RPs, IdPs, and browsers. We call a
n
web system OWS an OAuth web system with a network attacker if it is of the form described in what
follows.
Outline. The system consists of a network attacker, a finite set of web browsers, a finite set of web servers
n
for the RPs, and a finite set of web servers for the IdPs. Recall that in OWS , since we have a network
attacker, we do not need to consider web attackers (as our network attacker subsumes all web attackers).
The set of scripts consists of the three scripts script_rp_index, script_rp_implicit, and script_idp_form.
We now briefly sketch RPs, IdPs, and the scripts, with full details provided in Appendix F.
Relying Parties. Each RP is a web server modeled as an atomic DY process following the description in
Section 2, including all OAuth modes, as well as the fixes and mitigations discussed before. The RP can
either (at any time) launch a client credentials mode flow or wait for users to start any of the other flows.
RP manages two kinds of sessions: The login sessions, which are used only during the user login phase,
and the service sessions (modeled by a service token as described above). When receiving a special
message, an RP can become corrupted and then behaves like an attacker process.
Identity Providers. Each IdP is a web server modeled as an atomic DY process following the description
in Section 2, again including all OAuth modes, as well as the fixes and mitigations discussed before.
Users can authenticate to an IdP with their credentials. Just as RPs, IdPs can become corrupted at any
time.
Scripts. The scripts which run in a user’s browser are defined as follows: The script script_rp_index is
loaded from an RP into a user’s browser when the user visits the RP’s web site. It starts the authorization
or login process. The script script_rp_implicit is loaded into the user’s browser from an RP during an
implicit mode flow to retrieve the data from the URI fragment. It extracts the access token and state
from the fragment part of its own URI. The script then sends this information in the body of an HTTPS
POST request to the RP. The script script_idp_form is loaded from an IdP into the user’s browser for
user authentication at the IdP.
n
OAuth Web System with Web Attackers. In addition to OWS , we also consider a class of web systems
20
where the network attacker is replaced by an unbounded finite set of web attackers. We denote such a
w
system by OWS and call it an OAuth web system with web attackers, Such web systems are used to
analyze session integrity, see below.
Limitations of Our OAuth Model. While our model of OAuth is very comprehensive, a few aspects of
OAuth were not taken into consideration in our analysis:
We do not model expiration of access tokens and session ids. Also, IdPs may issue so-called refresh
tokens in Step 9 of Figure 1. In practice, an RP may use such a (long-living) refresh token to obtain
a new (short-lived) access token. In our model, we overapproximate this by not expiring access tokens.
We also do not model revocation of access tokens and user log out.
OAuth IdPs support controlling the scope of resources made available to an RP. For example, a Face-
book user can grant a third party the right to read her user profile but deny access to her friends list. The
scope is a property of the access token, but handled internally by the IdP with its implementation, details,
and semantics highly dependent on the IdP. We therefore model that RPs always get full access to the
user’s data at the IdP.
In practice, IdPs can send error messages (mostly static strings) to RPs. We do not model these.
Limitations of the underlying FKS model are discussed in [14].
21
is honest, then the flow was completed for the same identity for which the OAuth flow was started by
the user. We say that the OAuth flow was completed (for some identity v) iff the RP gets access to a
protected resource (of v).
w
We say that OWS is secure w.r.t. session integrity for authentication if the following holds true: (a)
w
if in a run ρ of OWS a user is logged in with some identity v, then the user started an OAuth flow. (b)
If in addition the IdP that is used in that flow is honest, then the user is logged in under exactly the same
identity for which the OAuth flow was started by the user.
We note that for session integrity, as opposed to authorization and authentication, we use the web
attacker as an adversary. The rationale behind this is that a network attacker can always forcefully log
in a user under his own account (by setting cookies from non-secure to secure origins [44]), thereby
defeating existing CSRF defenses in OAuth (most importantly, the state parameter). This is a common
problem in the session management of web applications, independently of OAuth. This is why we
restrict our analysis of session integrity to web attackers since otherwise session integrity would trivially
be broken. We note, however, that more robust solutions for session integrity are conceivable (e.g.,
using JavaScript and HTML5 features such as web messaging and web storage). While some proprietary
approaches exist, such approaches are less common and typically do not conform to the OAuth standard.
Main Theorem. We prove the following theorem (see Appendix I for the proof):
n n
Theorem 1. Let OWS be an OAuth web system with a network attacker, then OWS is secure w.r.t. au-
w
thorization and secure w.r.t. authentication. Let OWS be an OAuth web system with web attackers, then
w
OWS is secure w.r.t. session integrity for authorization and authentication.
Note that this trivially implies that authentication and authorization properties are satisfied also if web
attackers are considered.
6. Related Work
We focus on work closely related to OAuth 2.0 or formal security analysis of web standards and web
applications.
The work closest to our work is the already mentioned work by Bansal, Bhargavan, Delignat-Lavaud,
and Maffeis [6]. Bansal et al. analyze the security of OAuth using the applied pi-calculus and the WebSpi
library, along with the protocol analysis tool ProVerif. They model various settings of OAuth 2.0, often
assuming the presence of common web implementation flaws resulting in, for example, CSRF and open
redirectors in RPs and IdPs. They identify previously unknown attacks on the OAuth implementations
of Facebook, Yahoo, Twitter, and many other websites. Compared to our work, the WebSpi model
used in [6] is less expressive and comprehensive (see also the discussion in [14]), and the models of
22
OAuth they employ are more limited.16 As pointed out by Bansal et al., the main focus of their work
is to discover attacks on OAuth, rather than proving security. They have some positive results, which,
however, are based on their more limited model. In addition, in order to prove these results further
restrictions are assumed, e.g., they consider only one IdP per RP and all IdPs are assumed to be honest.
Wang et al. [42] present a systematic approach to find implicit assumptions in SDKs (e.g., the Face-
book PHP SDK) used for authentication and authorization, including SDKs that implement OAuth 2.0.
In [32], Pai et al. analyze the security of OAuth in a very limited model that does not incorporate
generic web features. They show that using their approach, based on the Alloy finite-state model checker,
known weaknesses can be found. The same tool is used by Kumar [27] in a formal analysis of the older
OAuth 1.0 protocol (which, as mentioned, is very different to OAuth 2.0).
Chari, Jutla, and Roy [9] analyze the security of the authorization code mode in the universally com-
posability model, again without considering web features, such as semantics of HTTP status codes,
details of cookies, or window structures inside a browser.
Besides these formal approaches, empirical studies were conducted on deployed OAuth implementa-
tions. In [41], Sun and Beznosov analyze the security of three IdPs and 96 RPs. In [28], Li and Mitchell
study the security of 10 IdPs and 60 RPs based in China. In [43], Yang et al. perform an automated
analysis of 4 OAuth IdPs and 500 RPs. Shernan et al. [39] evaluate the lack of CSRF protection in
various OAuth deployments. In [10, 38], practical evaluations on the security of OAuth implementations
of mobile apps are performed.
In [30], Mladenov et al. perform an informal analysis of OpenID Connect. They present several
attacks related to discovery and dynamic client registration, which are extensions of OpenID Connect;
see also the discussion in Section 3.2 (related attacks) concerning their malicious endpoint attack.
Note that many of the works listed here led to improved security recommendations for OAuth as listed
in RFC6749 [21] and RFC6819 [29]. These are already taken into account in our model and analysis of
OAuth.
More generally, there have been only very few analysis efforts for web applications and standards
based on formal web models so far. Work outside of the context of OAuth includes [2–5, 14, 16, 17, 26].
7. Conclusion
In this paper, we carried out the first extensive formal analysis of OAuth 2.0 based on a comprehensive
and expressive web model. Our analysis, which aimed at the standard itself, rather than specific OAuth
implementations and deployments, comprises all modes (grant types) of OAuth and available options
and also takes malicious RPs and IdPs as well as corrupted browsers/users into account. The generic
web model underlying our model of OAuth and its analysis is the most comprehensive web model to
date.
Our in-depth analysis revealed four attacks on OAuth as well as OpenID connect, which builds on
OAuth. We verified the attacks, proposed fixes, and reported the attacks and our fixes to the working
groups for OAuth and OpenID Connect. The working groups confirmed the attacks. Fixes to the stan-
dard and recommendations are currently under discussion or already incorporated in a draft for a new
RFC [24].
With the fixes applied, we were able to prove strong authorization, authentication, and session integrity
properties for OAuth 2.0. Our security analysis assumes that OAuth security recommendations and
16 For example, only two OAuth modes are considered, the model is monotonic (e.g., cookies can only be added, but not
deleted or modified), fixed bounded number of cookies per request, no precise handling of windows, documents, and iframes,
no web messaging, omission of headers, such as origin. We note that while OAuth does not make use of all web features,
taking such features into account is important to make positive security results more meaningful.
23
certain best practices are followed. We show that otherwise the security of OAuth cannot be guaranteed.
By this, we also provide clear guidelines for implementations. The fact that OAuth is one of the most
widely deployed authorization and authentication systems in the web and the basis for other protocols
makes our analysis particularly relevant.
As for future work, our formal analysis of OAuth offers a good starting point for the formal analysis
of OpenID Connect, and hence, such an analysis is an obvious next step for our research.
8. Acknowledgements
This work was partially supported by Deutsche Forschungsgemeinschaft (DFG) through Grant KU
1434/10-1.
References
[1] M. Abadi and C. Fournet. Mobile Values, New Names, and Secure Communication. In POPL
2001, pages 104–115. ACM Press, 2001.
[2] D. Akhawe, A. Barth, P. E. Lam, J. Mitchell, and D. Song. Towards a Formal Foundation of Web
Security. In CSF 2010, pages 290–304. IEEE Computer Society, 2010.
[4] A. Armando, R. Carbone, L. Compagna, J. Cuéllar, and M. L. Tobarra. Formal Analysis of SAML
2.0 Web Browser Single Sign-on: Breaking the SAML-based Single Sign-on for Google Apps. In
FMSE 2008, pages 1–10. ACM, 2008.
[5] C. Bansal, K. Bhargavan, A. Delignat-Lavaud, and S. Maffeis. Keys to the Cloud: Formal Analysis
and Concrete Attacks on Encrypted Web Storage. In POST 2013, volume 7796 of LNCS, pages
126–146. Springer, 2013.
[7] A. Barth, C. Jackson, and J. C. Mitchell. Robust defenses for cross-site request forgery. In CCS
2008, pages 75–88. ACM, 2008.
[8] J. Bradley, T. Lodderstedt, and H. Zandbelt. Encoding claims in the OAuth 2 state
parameter using a JWT – draft-bradley-oauth-jwt-encoded-state-05. IETF. Dec. 2015.
https://tools.ietf.org/html/draft-bradley-oauth-jwt-encoded-state-05.
[9] S. Chari, C. S. Jutla, and A. Roy. Universally Composable Security Analysis of OAuth v2.0. IACR
Cryptology ePrint Archive, 2011:526, 2011.
[10] E. Y. Chen, Y. Pei, S. Chen, Y. Tian, R. Kotcher, and P. Tague. OAuth Demystified for Mobile
Application Developers. In CCS 2014, pages 892–903, 2014.
24
[12] Cross-Origin Resource Sharing - W3C Recommendation 16 January 2014.
http://www.w3.org/TR/2014/REC-cors-20140116/.
[13] J. Eisinger and E. Stark. Referrer Policy – Editor’s Draft, 28 March 2016. W3C. Mar. 2016.
https://w3c.github.io/webappsec-referrer-policy/.
[14] D. Fett, R. Küsters, and G. Schmitz. An Expressive Model for the Web Infrastructure: Definition
and Application to the BrowserID SSO System. In S&P 2014, pages 673–688. IEEE Computer
Society, 2014.
[15] D. Fett, R. Küsters, and G. Schmitz. Analyzing the BrowserID SSO System with Primary Identity
Providers Using an Expressive Model of the Web. Technical Report arXiv:1411.7210, arXiv, 2014.
http://arxiv.org/abs/1411.7210.
[16] D. Fett, R. Küsters, and G. Schmitz. Analyzing the BrowserID SSO System with Primary Identity
Providers Using an Expressive Model of the Web. In ESORICS 2015, volume 9326 of LNCS, pages
43–65. Springer, 2015.
[17] D. Fett, R. Küsters, and G. Schmitz. SPRESSO: A Secure, Privacy-Respecting Single Sign-On
System for the Web. In CCS 2015, pages 1358–1369. ACM, 2015.
[18] D. Fett, R. Küsters, and G. Schmitz. A Comprehensive Formal Security Analysis of OAuth 2.0. In
CCS 2016. ACM, 2016. To appear.
[19] R. Fielding (ed.) and J. Reschke (ed.). RFC7231 – Hypertext Transfer Protocol (HTTP/1.1): Se-
mantics and Content. IETF. Jun. 2014. https://tools.ietf.org/html/rfc7231.
[21] D. Hardt (ed.). RFC6749 – The OAuth 2.0 Authorization Framework. IETF. Oct. 2012.
https://tools.ietf.org/html/rfc6749.
[25] P. Jones, G. Salgueiro, M. Jones, and J. Smarr. RFC7033 – WebFinger. IETF. Sep. 2013.
https://tools.ietf.org/html/rfc7033.
[26] F. Kerschbaum. Simple Cross-Site Attack Prevention. In SecureComm 2007, pages 464–472. IEEE
Computer Society, 2007.
[27] A. Kumar. Using automated model analysis for reasoning about security of web protocols. In
ACSAC 2012. ACM, 2012.
[28] W. Li and C. J. Mitchell. Security issues in OAuth 2.0 SSO implementations. In ISC 2014, volume
8783 of LNCS, pages 529–541, 2014. Springer, 2014.
25
[29] T. Lodderstedt (ed.), M. McGloin, and P. Hunt. RFC6819 – OAuth 2.0 Threat Model and Security
Considerations. IETF. Jan. 2013. https://tools.ietf.org/html/rfc6819.
[32] S. Pai, Y. Sharma, S. Kumar, R. M. Pai, and S. Singh. Formal Verification of OAuth 2.0 Using
Alloy Framework. In CSNT 2011, pages 655–659. IEEE, 2011.
[33] J. Richer (ed.). RFC7662 – OAuth 2.0 Token Introspection. IETF. Oct. 2015.
https://tools.ietf.org/html/rfc7662.
[34] N. Sakimura, J. Bradley, and M. Jones. OpenID Connect Dynamic Client Reg-
istration 1.0 incorporating errata set 1. OpenID Foundation. Nov. 8, 2014.
http://openid.net/specs/openid-connect-registration-1_0.html.
[37] J. Selvi. Bypassing HTTP Strict Transport Security. In Blackhat (Europe) 2014, 2014.
[38] M. Shehab and F. Mohsen. Towards Enhancing the Security of OAuth Implementations in Smart
Phones. In IEEE MS 2014. IEEE, 2014.
[39] E. Shernan, H. Carter, D. Tian, P. Traynor, and K. R. B. Butler. More Guidelines Than Rules:
CSRF Vulnerabilities from Noncompliant OAuth 2.0 Implementations. In DIMVA 2015, volume
9148 of LNCS, pages 239–260. Springer, 2015.
[40] SimilarTech. Facebook Connect Market Share and Web Usage Statistics. Last visited Nov. 7, 2015.
https://www.similartech.com/technologies/facebook-connect.
[41] S.-T. Sun and K. Beznosov. The Devil is in the (Implementation) Details: An Empirical Analysis
of OAuth SSO Systems. In CCS 2012, pages 378–390. ACM, 2012.
[42] R. Wang, Y. Zhou, S. Chen, S. Qadeer, D. Evans, and Y. Gurevich. Explicating SDKs: Uncovering
Assumptions Underlying Secure Authentication and Authorization. In USENIX Security 2013,
pages 399–314. USENIX Association, 2013.
[43] R. Yang, G. Li, W. C. Lau, K. Zhang, and P. Hu. Model-based Security Testing: An Empirical
Study on OAuth 2.0 Implementations. In AsiaCCS 2016, pages 651–662. ACM, 2016.
[44] X. Zheng, J. Jiang, J. Liang, H. Duan, S. Chen, T. Wan, and N. Weaver. Cookies Lack Integrity:
Real-World Implications. In USENIX Security 2015), pages 707–721, 2015. USENIX Association,
2015.
26
A. OAuth 2.0
The OAuth authorization code mode was presented in Section 2. Here, we present the three other OAuth
modes in detail.
A.1. Preliminaries
We now first provide some preliminary information regarding OAuth.
Endpoints. In OAuth, RPs and IdPs have to provide certain URIs to each other. The parties and
services these URIs point to are called endpoints; often the URIs themselves are called endpoints. An
IdP provides an authorization endpoint at which the user can authenticate to the IdP and authorize an
RP to access her user data. The IdP also provides a token endpoint at which the RP can request access
tokens. An RP provides one or more redirection endpoints to which the user’s browser gets redirected
by an IdP after the user authenticated to the IdP. The URIs of the endpoints are not fixed by the standard,
but are communicated when RPs register at IdPs, as described below.
The OAuth standard [21] and the accompanying security recommendations [29] suggest that all end-
points use HTTPS. We follow this recommendation in our analysis of OAuth.
Registration. Before an RP can interact with an IdP, the RP needs to be registered at the IdP. The details
of the registration process are out of the scope of the OAuth protocol. In practice, this process is usually
a manual task. During the registration process, the IdP assigns to the RP a fixed OAuth client id and
client secret.17 The RP may later use the client secret to authenticate to the IdP. If the RP cannot keep the
OAuth client secret confidential, e.g., if the RP is an in-browser app or a native application, the secret
can be omitted. Note that the OAuth client id is public information. It is, for example, revealed to users
in redirects issued by the RP.
Also, an RP registers one or more redirection endpoints at an IdP. As we will see below, in some
OAuth modes, the IdP redirects the user’s browser to one of these redirect URIs. If more than one
redirect URI is registered, the RP must specify which redirect URI is to be used in each run of the
OAuth protocol. For simplicity of presentation, we will assume that an RP always specifies its choice,
although this can be omitted if there exits only one (fixed) redirect URI. Note that (depending on the
implementation of an IdP) an RP may also register a pattern as a redirect URI and then specify the exact
redirect URI during the OAuth run. In this case, the IdP checks if the specified redirect URI matches
this pattern.
During the registration process, the (fixed) endpoints belonging to an IdP are configured at an RP as
well.
Our analysis presented in Section 5 covers all the above mentioned options: absence and presence of
client secrets, specified redirect URIs, and URI patterns.
Login Sessions. As mentioned before, in some OAuth modes, an RP redirects the user’s browser to
an IdP which later redirects the browser back to the RP. In order to prevent cross-site request forgery
(CSRF) attacks, the RP typically establishes a session with the browser before the first redirect. The
OAuth standard recommends that an RP selects the so-called state parameter and binds this value to
the session, e.g., by choosing a fresh nonce and storing the nonce in the session state. When the user
later gets redirected back to the RP, the state value must be identical. The intention is that this value
should always be unknown to an attacker in order to prevent CSRF attacks. In our analysis, we follow
the recommendation of using the state parameter.18
17 Recall that in the terminology of the OAuth standard the term “client” stands for RP.
18 Note that the OAuth standard [21] as well as the accompanying security recommendations [29] do not specify the session
27
Browser RP IdP
1 POST /start
idp
2 Response
Redirect to IdP /authEP with client_id, redirect_uri, state
3 GET /authEP
client_id, redirect_uri, state
4 Response
5 POST /authEP
username, password
6 Response
Redirect to RP redirect_uri, fragment: access_token, state
7 GET redirect_uri
8 Response
9 POST /token
access_token, state
10 GET /resource
access_token
11 Response
protected resource
Further Recommendations and Options. The standard and the recommendations do not specify all
implementation details. For example, the precise user interaction with an RP, formatting details of
messages, and the authentication of the user to an IdP (e.g., user name and password or some other
mechanism) are not covered. In our security analysis of OAuth we follow all OAuth security recommen-
dations as well as common best practices for state-of-the-art web applications in order to avoid known
attacks.
OAuth allows RPs to specify which scope of the user’s data they are requesting access to at an IdP.
The scopes themselves are not defined in the standard and are considered an implementation detail of
IdPs. Therefore, in our description and analysis of OAuth, we omit the scope parameter and assume that
the user always grants full access to her data at the IdP.
Implicit Mode. This mode is a simplified version of the authorization code mode: instead of providing
an authorization code to an RP, an IdP directly delivers an access token to the RP (via the user’s browser).
Step-by-Step Protocol Flow. We now provide a step-by-step description of the protocol flow (see also
Figure 4). As in the authorization code mode, the user starts the OAuth flow, e.g., by clicking on a
button to select an IdP, triggering the browser to send request 1 to the RP. The RP selects the redirect
mechanism for RPs. In our analysis we assume the usual session mechanism with session cookies following common best
practices. For more details, see Section 5.1.
28
Browser RP IdP
1 POST /start
idp, username, password
2 POST tokenEP
username, password, client_id, client_secret
3 Response
access_token
4 GET /resource
access_token
5 Response
protected resource
URI redirect_uri (which will be used later in 7 ) and a value state. The RP then redirects the browser
with its client_id, redirect_uri, and state to the authorization endpoint at the IdP19 in 2 and 3 . The IdP
prompts the user to enter her username and password in 4 . The user’s browser sends this information
to the IdP in 5 . If the user’s credentials are correct, the IdP creates an access token access_token and
redirects the user’s browser to the RP’s redirection endpoint redirect_uri in 6 and 7 , where the IdP
appends access_token and state to the fragment of the redirection URI. (Recall that a fragment is a
special part of a URI indicated by the ‘#’ symbol. When the browser opens a URI, the information in the
fragment is not transferred to the server.) Hence, in Step 7 access_token and state are not transferred to
the RP. To retrieve these values, the RP in 8 delivers a document containing JavaScript code. It retrieves
access_token and state from the fragment and sends these to the RP in 9 . The RP then checks if state
is the same as above. Just as in the authorization code mode, the RP can now use access_token for
authorization (illustrated in Steps 10 and 11 ); authentication is analogous to Steps 12 , 13 , and 14 of
Figure 1.
For authentication, note that the response from the IdP includes the RP’s OAuth client id, which is
also checked by the RP. This check prevents re-usage of access tokens across RPs in the OAuth implicit
mode as explained in [42].
We note that in the implicit mode, an IdP cannot verify the identity of the receiver of the access token,
as an RP does not authenticate itself to the IdP (using client_secret). Hence, this mode is more suitable
for RPs that do not have access to a secure, long-lived storage (for a client_secret) such as in-browser
applications.
Resource Owner Password Credentials Mode. In this mode, the user gives her credentials for an IdP
directly to an RP. The RP can then authenticate to the IdP on the user’s behalf and retrieve an access
token. The resource owner password credentials mode is intended for highly-trusted RPs, such as the
operating system of the user’s device or highly-privileged applications, or if the previous two modes are
not possible to perform (e.g., for applications without a web browser). In the following, we assume that
the authorization/login process is started by the user using a web browser.
Step-by-Step Protocol Flow. We now provide a step-by-step description of the resource owner password
credentials mode (see also Figure 5): The user provides her username and password for the IdP to the
19 Note that also a fixed string “token” indicating to the IdP that implicit mode is used is appended as a parameter to the
URI.
29
Browser RP IdP
1 POST /tokenEP
client_id, client_secret
2 Response
access_token
3 GET /resource
access_token
4 Response
protected resource
RP in 1 . Now, the RP sends the username, the password, its client_id and client_secret 20 to the IdP
in 2 . The IdP then issues an access token access_token to the RP in 3 .21 Just as in the authorization
code mode, the RP can now use access_token for authorization (illustrated in Steps 4 and 5 ) and
authentication (as in Steps 12 , 13 , and 14 of Figure 1).
Client Credentials Mode. In contrast to the modes shown above, this mode works without the user’s
interaction. Instead, it is started by an RP in order to fetch an access token to access RP’s own resources
at an IdP or to access resources at an IdP the RP is authorized to by other means. For example, Face-
book allows RPs to use the client credentials mode to obtain an access token to access reports of their
advertisements’ performance.
Step-by-Step Protocol Flow. The step-by-step description of the client credentials mode is as follows (see
also Figure 6): First, the RP contacts the IdP with RP’s client_id and client_secret in 1 . The IdP now
issues an access_token in 2 . Just as in the authorization code mode, the RP can now use access_token
for authorization (illustrated in Steps 3 and 4 ). In contrast to the other modes presented above, the
access token is not bound to a specific user account, but only to the RP.
20 Note that in this mode, if an RP does not have an OAuth client secret for an IdP, the client_secret and client_id parameters
are both omitted in this request. This option is also covered by our analysis.
21 As in the authorization code mode, an IdP may also issue a refresh token to the RP here.
30
B. IdP Mix-Up Attack in the OAuth Implicit Mode
Here, we present the IdP Mix-Up attack in the implicit mode. It is depicted in Figure 7.
Just as in the authorization code mode, the attack starts when the user selects that she wants to log
in using HIdP (Step 1 in Figure 7). Now, the attacker intercepts the request intended for the RP and
modifies the content of this request by replacing HIdP by AIdP. The response of the RP 3 (containing
a redirect to AIdP) is then again intercepted and modified by the attacker such that it redirects the user
to HIdP 4 . The attacker also replaces the OAuth client id of the RP at AIdP with the client id of the
RP at HIdP.22 (Note that we assume that from this point on, in accordance with the OAuth security
recommendations, the communication between the user’s browser and HIdP and the RP is encrypted by
using HTTPS, and thus, cannot be inspected or altered by the attacker.) The user then authenticates to
HIdP and is redirected back to the RP 8 . The RP, however, still assumes that the access token contained
in this redirect is an access token issued by AIdP, rather than HIdP. The RP therefore now uses this
access token to retrieve protected resources of the user (or the user id) at AIdP 12 , rather than HIdP.
This leaks the access token to the attacker who can now access protected resources of the user at IdP.
This breaks the authorization property (see Section 5.2 below). (We note that at this point, the attacker
might even provide false information about the user or her protected resources to the RP.)
To break authentication and impersonate the honest user, the attacker now starts a new login process
(using his own browser) at the RP. In 13 he selects HIdP as the IdP for this login process. He receives
a redirect to HIdP, which he skips.23 The attacker now sends the access token access_token captured in
Step 12 to the RP imitating a real login 15 . The RP now uses this access token to retrieve the user id
at HIdP 16 and receives the (honest) user’s id as well as its own OAuth client id 17 . Being convinced
that the attacker owns the honest user’s account, the RP issues a session cookie for this account to the
attacker 18 . As a result, the attacker is logged in at the RP under the honest user’s id. This breaks the
authentication property of OAuth (see Section 5.2 below).
31
Browser RP Attacker (AIdP) HIdP
1 POST /start
idp
2 POST /start
attacker
3 Response
Redirect to Attacker /authEP with client_id′ , redirect_uri, state
4 Response
Redirect to HIdP /authEP with client_id, redirect_uri, state
5 GET /authEP
client_id, redirect_uri, state
6 Response
7 POST /authEP
username, password
8 Response
Redirect to RP redirect_uri, fragment: access_token, state
9 GET redirect_uri
10 Response
11 POST /token
access_token, state
12 GET /resource
access_token
15 POST /token
access_token, state′
16 GET /introspectionEP
access_token
17 Response
user_id, client_id
18 Response
session_cookie
32
Browser RP IdP
1 POST /start
email
2 GET /.wk/webfinger
email
3 Response
idp
4 GET /.wk/openid-configuration
5 Response
issuer, authEP, tokenEP, registrationEP, jwksURI, userinfoEP
6 POST registrationEP
redirect_uris
7 Response
client_id, client_secret
8 Response
Redirect to IdP authEP with client_id, redirect_uri, state
9 GET authEP
client_id, redirect_uri, state
10 Response
11 POST authEP
username, password
12 Response
Redirect to RP redirect_uri, fragment: access_token, code, state
13 GET redirect_uri
14 Response
15 POST /token
access_token, code, state
16 POST tokenEP
code, client_id, redirect_uri, client_secret
17 Response
access_token′ , id_token
18 GET jwksURI
19 Response
pubSignKey
20 GET userinfoEP
access_token
21 Response
user_id
22 Response
session_cookie
Figure 8. OpenID Connect 1.0 hybrid mode with discovery and dynamic client registration
33
hybrid mode only. First, the user starts the login process by entering her email address24 in her browser
(at some web page of an RP), which sends the email address to the RP in 1 .
Now, the RP uses the OpenID Connect Discovery protocol [36] to gain information about the IdP:
The RP uses the WebFinger [25] mechanism to discover information about which IdP is responsible for
this user. For this discovery, the RP contacts the server of the user’s email domain (depicted as the same
party as the IdP in the figure) in 2 . The result of the WebFinger request in 3 contains the domain of
the server responsible for the OpenID Connect configuration (the IdP). The configuration is requested
from the IdP in 4 and returned in 5 . The configuration contains meta data about the IdP, including all
endpoints at the IdP. This concludes the OpenID Discovery in this login flow.
Next, if the RP is not registered at the IdP, the RP starts the OpenID Connect dynamic client regis-
tration [34] protocol: the RP contacts the IdP in 6 providing its redirect URIs. Now, the IdP issues an
(OAuth) client id and (optionally) an (OAuth) client secret to the RP in 7 . This concludes the OpenID
Connect dynamic client registration.
Now, the core part of the OpenID Connect protocol (based on OAuth) starts: the RP redirects the
user’s browser to the IdP in 8 . This redirect contains information that the hybrid mode is used and
which tokens are requested. In this description, we assume that an authorization code and an access
token are requested.25 Also, this redirect contains the (OAuth) client id of the RP, a redirect URI and a
state value. As in the OAuth flows, this data is sent to the IdP 9 , the user authenticates to the IdP 10 ,
11 , and the IdP redirects the user’s browser back to the RP in 12 and 13 (using the redirect URI from
the request in 9 ). This redirect contains an authorization code, an access token, and the state value in
the fragment part of the URL.26 Now, the RP in 14 sends a document containing JavaScript code which
sends the parameters contained in the fragment back to the RP (in 15 ). If the state value matches, the
RP contacts the IdP in 16 with the received authorization code, its (OAuth) client id, its (OAuth) client
secret, and the redirect URI used to obtain the authorization code. The IdP sends a response with the
same or a fresh access token and an id token to the RP in 17 . Now, the RP retrieves the key that was
used to sign the id token from the IdP in 18 and 19 and verifies the id token’s signature. As the id
token typically contains only a unique user identifier, but no other meta data about the user, RP requests
this meta data (such as nickname, birthday, or address) from the IdP in 20 and 21 using one of the
authorization tokens received before. Finally, the RP considers the user to be logged in and may set a
session cookie at the user’s browser in 22 .
Note that the authorization code mode and the implicit mode are similar to the hybrid mode: Roughly
speaking, the Steps 12 – 17 of the OpenID Connect hybrid mode are replaced by the corresponding
steps of the OAuth authorization code or implicit mode, respectively. These OAuth modes are then
extended with the transfer of an id token. In the authorization code mode, the id token is appended to the
response 9 of Figure 1 and in the implicit mode, the id token is appended to the fragment of the redirect
URI in 6 of Figure 4 (and later sent to the RP in Step 9 ).
The 307 Redirect Attack. The 307 redirect attack presented in Section 3.1 can also be applied to
OpenID Connect. Note that the critical part of OAuth, namely the redirect of the user’s browser from the
IdP to the RP after the authentication of the user to the IdP, is also present in OpenID Connect. Hence, if
the IdP uses an HTTP status 307 redirect immediately after the user’s browser has transferred the user’s
credentials to IdP in a POST request, the RP receives these credentials.
The IdP Mix-Up Attack. When applying the attack presented in Section 3.2 to OpenID Connect,
the attacker needs to circumvent some additional security measures: In the implicit mode of OpenID
Connect, an id_token (as described above) is sent along with access_token in the redirect from HIdP
24 Note that OpenID Connect also allows other types of user identifiers, such as a personal URL.
25 The Hybrid Flow allows to request several different combinations of authorization code, access token, and id token.
26 Note that depending on the parameters in step 9 , also an id token may be contained in the fragment part of the URL.
34
Browser RP Attacker (AIdP) HIdP
1 POST /start
email
2 POST /start
email′
3 GET /.wk/webfinger
email′
4 Response
attacker
5 GET /.wk/openid-configuration
6 Response
issuer , authEP, tokenEP , registrationEP′ , jwksURI, userinfoEP′ ,
′ ′
responseTypes
7 POST registrationEP ′
redirect_uris
8 Response
client_id, client_secret′
9 Response
Redirect to HIdP authEP with client_id, redirect_uri, state
10 GET authEP
client_id, redirect_uri, state
11 Response
12 POST authEP
username, password
13 Response
Redirect to RP redirect_uri, fragment: access_token, code, state
14 GET redirect_uri
15 Response
16 POST /token
access_token, code, state
17 POST tokenEP′
code, client_id, redirect_uri, client_secret′
18 Response
access_token′ , id_token
19 GET userinfoEP
access_token
20 GET /protectedResource
access_token
21 Response
secret user data
Figure 9. Attack on OpenID Connect 1.0 hybrid mode with discovery and dynamic client registration
35
to the RP. As this redirect might use HTTPS, the attacker cannot inspect or modify the corresponding
network messages. As mentioned above, the id token contains the domain of the issuer of both, the
access token and the id token. Therefore, the RP can detect that the user did not use AIdP (which the RP
redirected to).
An attacker could try to use the authorization code mode of OpenID Connect to mount a similar attack
as described above. In this case, however, the attacker does not learn a valid access token for the user’s
account at HIdP if a client secret is used.
In the hybrid mode, however, an attacker can learn an access token and mount the attack as follows
(see also Figure 9):
As above, the user first visits the RP. When the user sends her email address to the RP in order to
login 1 , the attacker manipulates the domain part of the email address, to be the domain of AIdP 2 . The
RP then looks up the IdP to be used (which is now AIdP) using the WebFinger protocol in Steps 3 and 4 .
The RP fetches the OpenID Connect configuration from the attacker ( 5 and 6 ). In this document, the
attacker states that the authorization endpoint is located at HIdP while all other endpoints are located at
the attacker. Using parameters not shown in the figures, the attacker can also state that this IdP does not
support delivering an id token in the redirect and can state that no signatures are supported. Since no
signatures need to be checked, also the key retrieval is skipped in the protocol.
After retrieving the OpenID configuration, the RP registers at AIdP, as the attacker uses a domain
previously unknown to the RP. (If the domain was known to the RP, this step would be skipped.) The
attacker issues the same client_id with which the RP is registered at HIdP ( 7 and 8 ). Now, the RP
redirects the user’s browser to HIdP in order to log in. After the user authenticated to HIdP, HIdP
redirects the user’s browser back to the RP. The fragment part of the URL contains an authorization
code and an access token 14 . The RP then sends the authorization code to the attacker in 17 .
If the RP does not have a client secret registered at HIdP, the attacker can redeem this authorization
code at HIdP in order to receive an access token to access the honest user’s protected resources at
HIdP. This breaks the authorization of OpenID Connect (compare the OAuth authorization property in
Section 5.2).
Alternatively, the attacker responds to the RP with a faked access token and a faked id token 18 (which
the attacker can create, because he controls all security settings for this id token, see Step 6 ).
Next, the RP retrieves other meta information about the user from AIdP. The RP is now in possession
of two access tokens. The OpenID Connect standard explicitly allows this situation, but fails to state
which access token has to be used in subsequent requests. The RP can now chose either of the access
tokens for the next steps, with different outcomes for the attacker:
First Access Token is Selected. In this case the access token originating from HIdP is selected by the
RP and sent to the attacker 19 . (This behavior was observed by us in the real-world implementation
mod_auth_openidc.)
Now the attacker can use this access token to access other protected resources of the user at HIdP. This
breaks authorization for OpenID Connect (compare our OAuth authorization property in Section 5.2).
Second Access Token is Selected. In this case the access token originating from AIdP is selected. This
means that the attacker does not learn a valid access token for HIdP. The attacker can, however, reuse the
authorization code for HIdP, which he learned in 17 and which is still valid as it has not been redeemed at
HIdP, yet. Using this method, the attacker can impersonate the honest user at the RP. To accomplish this,
the attacker starts a new login flow at the RP with the user’s email address. In Step 15 of Figure 8, he
provides the authorization code he has learned along with some (invalid) access token and the state from
his (new) login flow to the RP. The RP then requests an access token and an id token from HIdP with
this (still valid) authorization code. The RP receives a valid access token and a valid id token (for the
honest user) from HIdP. As the RP uses this valid access token in this case, all subsequent requests from
36
the RP to HIdP are successful and the RP receives the user id of the honest user, the RP considers the
attacker to be logged in as the honest user. This breaks the authentication of OpenID Connect (compare
our OAuth authentication property in Section 5.2).
37
deca (enca (x, pub(y)), y) = x (1)
decs (encs (x, y), y) = x (2)
checksig(sig(x, y), x, pub(y)) = ⊤ (3)
extractmsg(sig(x, y)) = x (4)
πi (hx1 , . . . , xn i) = xi if 1 ≤ i ≤ n (5)
π j (hx1 , . . . , xn i) = ✸ if j 6∈ {1, . . . , n} (6)
38
By ≡ we denote the congruence relation on TN (X ) induced by the theory associated with Σ. For
example, we have that π1 (deca (enca (ha, bi, pub(k)), k)) ≡ a.
Definition 2 (Ground Terms, Messages, Placeholders, Protomessages). By TN = TN (0), / we denote
the set of all terms over Σ ∪ N without variables, called ground terms. The set M of messages (over N )
is defined to be the set of ground terms TN .
We define the set Vprocess = {ν1 , ν2 , . . . } of variables (called placeholders). The set M ν := TN (Vprocess )
is called the set of protomessages, i.e., messages that can contain placeholders.
Example 1. For example, k ∈ N and pub(k) are messages, where k typically models a private key
and pub(k) the corresponding public key. For constants a, b, c and the nonce k ∈ N , the message
enca (ha, b, ci, pub(k)) is interpreted to be the message ha, b, ci (the sequence of constants a, b, c) en-
crypted by the public key pub(k).
Definition 3 (Normal Form). Let t be a term. The normal form of t is acquired by reducing the function
symbols from left to right as far as possible using the equational theory shown in Figure 10. For a term
t, we denote its normal form as t↓.
Definition 4 (Pattern Matching). Let pattern ∈ TN ({∗}) be a term containing the wildcard (variable
∗). We say that a term t matches pattern iff t can be acquired from pattern by replacing each occurrence
of the wildcard with an arbitrary term (which may be different for each instance of the wildcard). We
write t ∼ pattern. For a sequence of patterns patterns we write t ∼patterns
˙ to denote that t matches at
least one pattern in patterns.
For a term t ′ we write t ′ | pattern to denote the term that is acquired from t ′ by removing all immediate
subterms of t ′ that do not match pattern.
Example 2. For example, for a pattern p = h⊤, ∗i we have that h⊤, 42i ∼ p, h⊥, 42i 6∼ p, and
hh⊥, ⊤i, h⊤, 23i, ha, bi, h⊤, ⊥ii| p = hh⊤, 23i, h⊤, ⊥ii .
Definition 6 (Events and Protoevents). An event (over IPs and M ) is a term of the form ha, f , mi, for
a, f ∈ IPs and m ∈ M , where a is interpreted to be the receiver address and f is the sender address. We
denote by E the set of all events. Events over IPs and M ν are called protoevents and are denoted E ν .
By 2E hi (or 2E hi , respectively) we denote the set of all sequences of (proto)events, including the empty
ν
p = (I p , Z p , R p , s0p )
where I p ⊆ IPs, Z p ∈ TN is a set of states, R p ⊆ (E × Z p ) × (2E hi × TN (Vprocess )) (input event and old
ν
state map to sequence of output events and new state), and s0p ∈ Z p is the initial state of p. For any new
state s and any sequence of nonces (η1 , η2 , . . . ) we demand that s[η1 /ν1 , η2 /ν2 , . . . ] ∈ Z p . A system P is
a (possibly infinite) set of atomic processes.
39
Definition 8 (Configurations). A configuration of a system P is a tuple (S, E, N) where the state of the
system S maps every atomic process p ∈ P to its current state S(p) ∈ Z p , the sequence of waiting events
E is an infinite sequence28 (e1 , e2 , . . . ) of events waiting to be delivered, and N is an infinite sequence of
nonces (n1 , n2 , . . . ).
Definition 10 (Subtracting from Sequences). For a sequence X and a set or sequence Y we define
X \ Y to be the sequence X where for each element in Y , a non-deterministically chosen occurence of
that element in X is removed.
where
1. (S, E, N) and (S′ , E ′ , N ′ ) are configurations of P ,
3. p ∈ P is a process,
2. a term sν ∈ TN (Vprocess ),
2. Eout = Eout
ν [m /v , . . . , m /v ]
1 1 i i
4. E ′ = Eout · (E \ {ein })
5. N ′ = N \ N ν
We may omit the superscript and/or subscript of the arrow.
Intuitively, for a processing step, we select one of the processes in P , and call it with one of the events
in the list of waiting events E. In its output (new state and output events), we replace any occurences of
placeholders νx by “fresh” nonces from N (which we then remove from N). The output events are then
prepended to the list of waiting events, and the state of the process is reflected in the new configuration.
28 Here: Not in the sense of terms as defined earlier.
40
Definition 12 (Runs). Let P be a system, E 0 be sequence of events, and N 0 be a sequence of nonces. A
run ρ of a system P initiated by E 0 with nonces N 0 is a finite sequence of configurations ((S0 , E 0 , N 0 ), . . . ,
(Sn , E n , N n )) or an infinite sequence of configurations ((S0 , E 0 , N 0 ), . . . ) such that S0 (p) = s0p for all
p ∈ P and (Si , E i , N i ) −
→ (Si+1 , E i+1 , N i+1 ) for all 0 ≤ i < n (finite run) or for all i ≥ 0 (infinite run).
We denote the state Sn (p) of a process p at the end of a run ρ by ρ(p).
Usually, we will initiate runs with a set E 0 containing infinite trigger events of the form ha, a, TRIGGERi
for each a ∈ IPs, interleaved by address.
Atomic Dolev-Yao Processes. We next define atomic Dolev-Yao processes, for which we require that
the messages and states that they output can be computed (more formally, derived) from the current
input event and state. For this purpose, we first define what it means to derive a message from given
messages.
Definition 13 (Deriving Terms). Let M be a set of ground terms. We say that a term m can be derived
from M with placeholders V if there exist n ≥ 0, m1 , . . . , mn ∈ M, and τ ∈ T0/ ({x1 , . . . , xn } ∪V ) such that
m ≡ τ [m1 /x1 , . . . , mn /xn ]. We denote by dV (M) the set of all messages that can be derived from M with
variables V .
Definition 15 (Atomic Attacker Process). An (atomic) attacker process for a set of sender addresses
A ⊆ IPs is an atomic DY process p = (I, Z, R, s0 ) such that for all events e, and s ∈ TN we have that
((e, s), (E, s′ )) ∈ R iff s′ = he, E, si and E = hha1 , f1 , m1 i, . . . , han , fn , mn ii with n ∈ N, a1 , . . . , an ∈ IPs,
f0 , . . . , fn ∈ A, m1 , . . . , mn ∈ dVprocess ({e, s}).
C.2. Scripts
We define scripts, which model client-side scripting technologies, such as JavaScript. Scripts are defined
similarly to DY processes.
Definition 16 (Placeholders for Scripts). By Vscript = {λ1 , . . . } we denote an infinite set of variables
used in scripts.
Definition 17 (Scripts). A script is a relation R ⊆ TN × TN (Vscript ) such that for all s ∈ TN , s′ ∈
TN (Vscript ) with (s, s′ ) ∈ R it follows that s′ ∈ dVscript (s).
A script is called by the browser which provides it with state information (such as the script’s last state
and limited information about the browser’s state) s. The script then outputs a term s′ , which represents
the new internal state and some command which is interpreted by the browser. The term s′ may contain
variables λ1 , . . . which the browser will replace by (otherwise unused) placeholders ν1 , . . . which will
be replaced by nonces once the browser DY process finishes (effectively providing the script with a way
to get “fresh” nonces).
Similarly to an attacker process, we define the attacker script Ratt :
Definition 18 (Attacker Script). The attacker script Ratt outputs everything that is derivable from the
input, i.e., Ratt = {(s, s′ ) | s ∈ TN , s′ ∈ dVscript (s)}.
41
C.3. Web System
The web infrastructure and web applications are formalized by what is called a web system. A web
system contains, among others, a (possibly infinite) set of DY processes, modeling web browsers, web
servers, DNS servers, and attackers (which may corrupt other entities, such as browsers).
Definition 19. A web system WS = (W , S , script, E 0 ) is a tuple with its components defined as follows:
The first component, W , denotes a system (a set of DY processes) and is partitioned into the sets Hon,
Web, and Net of honest, web attacker, and network attacker processes, respectively.
Every p ∈ Web ∪ Net is an attacker process for some set of sender addresses A ⊆ IPs. For a web
attacker p ∈ Web, we require its set of addresses I p to be disjoint from the set of addresses of all other
′
web attackers and honest processes, i.e., I p ∩ I p = 0/ for all p′ ∈ Hon ∪ Web. Hence, a web attacker
cannot listen to traffic intended for other processes. Also, we require that A = I p , i.e., a web attacker can
only use sender addresses it owns. Conversely, a network attacker may listen to all addresses (i.e., no
restrictions on I p ) and may spoof all addresses (i.e., the set A may be IPs).
Every p ∈ Hon is a DY process which models either a web server, a web browser, or a DNS server,
as further described in the following subsections. Just as for web attackers, we require that p does not
spoof sender addresses and that its set of addresses I p is disjoint from those of other honest processes
and the web attackers.
The second component, S , is a finite set of scripts such that Ratt ∈ S . The third component, script, is
an injective mapping from S to S, i.e., by script every s ∈ S is assigned its string representation script(s).
Finally, E 0 is an (infinite) sequence of events, containing an infinite number of events of the form
S
ha, a, TRIGGERi for every a ∈ p∈W I p .
A run of WS is a run of W initiated by E 0 .
42
D. Message and Data Formats
We now provide some more details about data and message formats that are needed for the formal
treatment of the web model and the analysis of BrowserID presented in the rest of the appendix.
D.1. Notations
Definition 20 (Sequence Notations). For a sequence t = ht1 , . . . ,tn i and a set s we use t ⊂hi s to say that
t1 , . . . ,tn ∈ s. We define x ∈hi t ⇐⇒ ∃i : ti = x . We write t +hi y to denote the sequence ht1 , . . . ,tn , yi.
For a finite set M with M = {m1 , . . . , mn } we use hMi to denote the term of the form hm1 , . . . , mn i. (The
order of the elements does not matter; one is chosen arbitrarily.)
hhk1 , v1 i, . . . , hkn , vn ii
We note that the empty dictionary is equivalent to the empty sequence, i.e., [] = hi. Figure 11 shows the
short notation for dictionary operations that will be used when describing the browser atomic process.
For a dictionary z = [k1 : v1 , k2 : v2 , . . . , kn : vn ] we write k ∈ z to say that there exists i such that k = ki .
We write z[k j ] := v j to extract elements. If k 6∈ z, we set z[k] := hi.
Given a term t = ht1 , . . . ,tn i, we can refer to any subterm using a sequence of integers. The subterm is
determined by repeated application of the projection πi for the integers i in the sequence. We call such
a sequence a pointer:
Definition 22. A pointer is a sequence of non-negative integers. We write τ .p for the application of the
pointer p to the term τ . This operator is applied from left to right. For pointers consisting of a single
integer, we may omit the sequence braces for brevity.
Example 3. For the term τ = ha, b, hc, d, he, f iii and the pointer p = h3, 1i, the subterm of τ at the
position p is c = π1 (π3 (τ )). Also, τ .3.h3, 1i = τ .3.p = τ .3.3.1 = e.
To improve readability, we try to avoid writing, e.g., o.2 or π2 (o) in this document. Instead, we will
use the names of the components of a sequence that is of a defined form as pointers that point to the
corresponding subterms. E.g., if an Origin term is defined as hhost, protocoli and o is an Origin term,
then we can write o.protocol instead of π2 (o) or o.2. See also Example 4.
43
D.2. URLs
Definition 23. A URL is a term of the form
with
protocol
∈ {P, S} (for plain (HTTP) and secure (HTTPS)), host ∈ Doms, path ∈ S, parameters ∈
S × TN , and fragment ∈ TN . The set of all valid URLs is URLs.
The fragment part of a URL can be omitted when writing the URL. Its value is then defined to be ⊥.
Example 4. For the URL u = hURL, a, b, c, di, u.protocol = a. If, in the algorithm described later, we
say u.path := e then u = hURL, a, b, c, ei afterwards.
D.3. Origins
Definition 24. An origin is a term of the form hhost, protocoli with host ∈ Doms and protocol ∈ {P, S}.
We write Origins for the set of all origins.
Example 5. For example, hFOO, Si is the HTTPS origin for the domain FOO, while hBAR, Pi is the HTTP
origin for the domain BAR.
D.4. Cookies
Definition 25. A cookie is a term of the form hname, contenti where name ∈ TN , and content is a term
of the form hvalue, secure, session, httpOnlyi where value ∈ TN , secure, session, httpOnly ∈ {⊤, ⊥}. We
write Cookies for the set of all cookies and Cookiesν for the set of all cookies where names and values
are defined over TN (V ).
If the secure attribute of a cookie is set, the browser will not transfer this cookie over unencrypted
HTTP connections. If the session flag is set, this cookie will be deleted as soon as the browser is closed.
The httpOnly attribute controls whether JavaScript has access to this cookie.
Note that cookies of the form described here are only contained in HTTP(S) requests. In responses,
only the components name and value are transferred as a pairing of the form hname, valuei.
44
• status ∈ S is the HTTP status code (i.e., a number between 100 and 505, as defined by the HTTP
standard)
• parameters ∈ S × TN contains URL parameters
• headers ∈ S × TN , containing request/response headers. The dictionary elements are terms of
one of the following forms:
• hOrigin, oi where o is an origin,
• hSet-Cookie, ci where c is a sequence of cookies,
• hCookie, ci where c ∈, S × TN (note that in this header, only names and values of cookies
are transferred),
• hLocation, li where l ∈ URLs,
• hReferer, ri where r ∈ URLs,
• hStrict-Transport-Security, ⊤i,
• hAuthorization, hu, pii where u, p ∈ S,
• hReferrerPolicy, pi where p ∈ {noreferrer, origin}
• body ∈ TN in requests and responses.
We write HTTPRequests/HTTPResponses for the set of all HTTP requests or responses, respectively.
An HTTP GET request for the URL http://example.com/show?index=1 is shown in (11), with an
Origin header and a body that contains hfoo, bari. A possible response is shown in (12), which contains
an httpOnly cookie with name SID and value n2 as well as the string representation somescript of the
script script−1 (somescript) (which should be an element of S ) and its initial state x.
Encrypted HTTP Messages.. For HTTPS, requests are encrypted using the public key of the server.
Such a request contains an (ephemeral) symmetric key chosen by the client that issued the request. The
server is supported to encrypt the response using the symmetric key.
Definition 27. An encrypted HTTP request is of the form enca (hm, k′ i, k), where k, k′ ∈ N and m ∈
HTTPRequests. The corresponding encrypted HTTP response would be of the form encs (m′ , k′ ), where
m′ ∈ HTTPResponses. We call the sets of all encrypted HTTP requests and responses HTTPSRequests
or HTTPSResponses, respectively.
Example 7.
The term (13) shows an encrypted request (with r as in (11)). It is encrypted using the public key
pub(kexample.com ). The term (14) is a response (with s as in (12)). It is encrypted symmetrically using the
(symmetric) key k′ that was sent in the request (13).
45
D.6. DNS Messages
Definition 28. A DNS request is a term of the form hDNSResolve, domain, ni where domain ∈ Doms,
n ∈ N . We call the set of all DNS requests DNSRequests.
Definition 29. A DNS response is a term of the form hDNSResolved, domain, result, ni with domain
∈ Doms, result ∈ IPs, n ∈ N . We call the set of all DNS responses DNSResponses.
DNS servers are supposed to include the nonce they received in a DNS request in the DNS response
that they send back so that the party which issued the request can match it with the request.
Definition 30. A DNS server d (in a flat DNS model) is modeled in a straightforward way as an atomic
DY process (I d , {sd0 }, Rd , sd0 ). It has a finite set of addresses I d and its initial (and only) state sd0 encodes
a mapping from domain names to addresses of the form
46
E. Detailed Description of the Browser Model
Following the informal description of the browser model in Section 4, we now present a formal model.
We start by introducing some notation and terminology.
Definition 31. A window is a term of the form w = hnonce, documents, openeri with nonce ∈ N ,
documents ⊂hi Documents (defined below), opener ∈ N ∪ {⊥} where d.active = ⊤ for exactly one
d ∈hi documents if documents is not empty (we then call d the active document of w). We write Windows
for the set of all windows. We write w.activedocument to denote the active document inside window
w if it exists and hi else.
Definition 33. The set of states Z p of a web browser atomic process p consists of the terms of the form
where
• ids ⊂hi TN ,
• secrets ∈ Origins × TN ,
47
• localStorage ∈ Origins × TN ,
• sessionStorage ∈ OR × TN for OR := {ho, ri| o ∈ Origins, r ∈ N },
• keyMapping ∈ Doms × TN ,
• DNSaddress ∈ IPs,
• pendingDNS ∈ N × TN ,
• pendingRequests ∈ TN ,
w ∈hi w′ .activedocument.subwindows .
childof+
We write −−−−→ for the transitive closure.
In the following description of the web browser relation R p we use the helper functions Subwindows,
Docs, Clean, CookieMerge and AddCookie.
Given a browser state s, Subwindows(s) denotes the set of all pointers29 to windows in the window list
s.windows, their active documents, and (recursively) the subwindows of these documents. We exclude
subwindows of inactive documents and their subwindows. With Docs(s) we denote the set of pointers
to all active documents in the set of windows referenced by Subwindows(s).
Definition 35. For a browser state s we denote by Subwindows(s) the minimal set of pointers that sat-
isfies the following conditions: (1) For all windows w ∈hi s.windows there is a p ∈ Subwindows(s)
such that s.p = w. (2) For all p ∈ Subwindows(s), the active document d of the window s.p and every
subwindow w of d there is a pointer p′ ∈ Subwindows(s) such that s.p′ = w.
Given a browser state s, the set Docs(s) of pointers to active documents is the minimal set such that
for every p ∈ Subwindows(s), there is a pointer p′ ∈ Docs(s) with s.p′ = s.p.activedocument.
By Subwindows+ (s) and Docs+ (s) we denote the respective sets that also include the inactive docu-
ments and their subwindows.
The function Clean will be used to determine which information about windows and documents the
script running in the document d has access to.
Definition 36. Let s be a browser state and d a document. By Clean(s, d) we denote the term that
equals s.windows but with (1) all inactive documents removed (including their subwindows etc.), (2) all
subterms that represent non-same-origin documents w.r.t. d replaced by a limited document d ′ with the
same nonce and the same subwindow list, and (3) the values of the subterms headers for all documents
set to hi. (Note that non-same-origin documents on all levels are replaced by their corresponding limited
document.)
The function CookieMerge merges two sequences of cookies together: When used in the browser,
oldcookies is the sequence of existing cookies for some origin, newcookies is a sequence of new cookies
that was output by some script. The sequences are merged into a set of cookies using an algorithm that
is based on the Storage Mechanism algorithm described in RFC6265.
29 Recall the definition of a pointer in Definition 22.
48
Definition 37. For a sequence of cookies (with pairwise different names) oldcookies and a sequence
of cookies newcookies, the set CookieMerge(oldcookies, newcookies) is defined by the following al-
gorithm: From newcookies remove all cookies c that have c.content.httpOnly ≡ ⊤. For any c,
c′ ∈hi newcookies, c.name ≡ c′ .name, remove the cookie that appears left of the other in newcookies.
Let m be the set of cookies that have a name that either appears in oldcookies or in newcookies, but not
in both. For all pairs of cookies (cold , cnew ) with cold ∈hi oldcookies, cnew ∈hi newcookies, cold .name ≡
cnew .name, add cnew to m if cold .content.httpOnly ≡ ⊥ and add cold to m otherwise. The result of
CookieMerge(oldcookies, newcookies) is m.
The function AddCookie adds a cookie c received in an HTTP response to the sequence of cookies
contained in the sequence oldcookies. It is again based on the algorithm described in RFC6265 but
simplified for the use in the browser model.
Definition 38. For a sequence of cookies (with pairwise different names) oldcookies and a cookie c, the
sequence AddCookie(oldcookies, c) is defined by the following algorithm: Let m := oldcookies. Remove
any c′ from m that has c.name ≡ c′ .name. Append c to m and return m.
The function NavigableWindows returns a set of windows that a document is allowed to navigate. We
closely follow [23], Section 5.1.4 for this definition.
Definition 39. The set NavigableWindows(w, s′ ) is the set W ⊆ Subwindows(s′ ) of pointers to windows
that the active document in w is allowed to navigate. The set W is defined to be the minimal set such
that for every w′ ∈ Subwindows(s′ ) the following is true:
49
for some variables x, y, a string Constant, and some term t to express that x := π2 (t), and y := π3 (t)
if Constant ≡ π1 (t) and if |hConstant, x, yi| = |t|, and that otherwise x and y are not set and doSome-
thingElse is executed.
Placeholders.. In several places throughout the algorithms presented next we use placeholders to gener-
ate “fresh” nonces as described in our communication model (see Definition 1). Figure 12 shows a list
of all placeholders used.
Placeholder Usage
ν1 Algorithm 9, new window nonces
ν2 Algorithm 9, new HTTP request nonce
ν3 Algorithm 9, lookup key for pending HTTP requests entry
ν4 Algorithm 7, new HTTP request nonce (multiple lines)
ν5 Algorithm 7, new subwindow nonce
ν6 Algorithm 8, new HTTP request nonce
ν7 Algorithm 8, new document nonce
ν8 Algorithm 4, lookup key for pending DNS entry
ν9 Algorithm 1, new window nonce
ν10 , . . . Algorithm 7, replacement for placeholders in script output
Before we describe the main browser algorithm, we first define some functions.
Functions. In the description of the following functions we use a, f , m, and s as read-only global input
variables. All other variables are local variables or arguments.
The following function, GETNAVIGABLEWINDOW, is called by the browser to determine the win-
dow that is actually navigated when a script in the window s′ .w provides a window reference for nav-
igation (e.g., for opening a link). When it is given a window reference (nonce) window, this function
returns a pointer to a selected window term in s′ :
• If window is the string _BLANK, a new window is created and a pointer to that window is returned.
• If window is a nonce (reference) and there is a window term with a reference of that value in the
windows in s′ , a pointer w′ to that window term is returned, as long as the window is navigable by
the current window’s document (as defined by NavigableWindows above).
In all other cases, w is returned instead (the script navigates its own window).
50
11: let w′ ← NavigableWindows(w, s′ ) such that s′ .w′ .nonce ≡ window
֒→ if possible; otherwise return w
12: return w′
13: end function
The following function takes a window reference as input and returns a pointer to a window as above,
but it checks only that the active documents in both windows are same-origin. It creates no new windows.
51
14: if referrerPolicy ≡ origin then
15: let referrer := hURL, referrer.protocol, referrer.host, /, hi, ⊥i ⊲ Referrer stripped down to
origin.
16: end if
17: let referrer.fragment := ⊥ ⊲ Browsers do not send fragment identifiers in the Referer header.
18: let message.headers[Referer] := referrer
19: end if
20: let s′ .pendingDNS[ν8 ] := hreference, message, urli
21: stop hhs′ .DNSaddress, a, hDNSResolve, message.host, ν8 iii, s′
22: end function
The following functions navigate a window forward or backward. More precisely, they deactivate one
document and activate that document’s succeeding document or preceding document, respectively. If no
such successor/predecessor exists, the functions do not change the state.
52
֒→ cookies′ ← Cookiesν ,
֒→ localStorage′ ← TN (V ),
֒→ sessionStorage′ ← TN (V ),
֒→ command ← TN (V ),
֒→ outλ := hstate′ , cookies′ , localStorage′ , sessionStorage′ , commandi
֒→ such that (in, outλ ) ∈ R
11: let out := outλ [ν 10 /λ1 , ν11 /λ2 , . . . ]
12: let s′ .cookies s′ .d.origin.host
֒→ := hCookieMerge(s′ .cookies s′ .d.origin.host , cookies′ )i
13: let s′ .localStorage s′ .d.origin := localStorage′
14: let s′ .sessionStorage hs′ .d.origin, tlw.noncei := sessionStorage′
15: let s′ .d.scriptstate := state′
16: switch command do
17: case hHREF, url, hrefwindow, noreferreri
18: let w′ := GETNAVIGABLEWINDOW(w, hrefwindow, noreferrer, s′ )
19: let req := hHTTPReq, ν4 , GET, url.host, url.path, hi, url.parameters, hii
20: if noreferrer ≡ ⊤ then
21: let referrerPolicy := noreferrer
22: else
23: let referrerPolicy := s′ .d.headers[ReferrerPolicy]
24: end if
25: let s′ := CANCELNAV(s′ .w′ .nonce, s′ )
26: SEND(s′ .w′ .nonce, req, url, ⊥, referrer, referrerPolicy, s′ )
27: case hIFRAME, url, windowi
28: let w′ := GETWINDOW(w, window, s′ )
29: let req := hHTTPReq, ν4 , GET, url.host, url.path, hi, url.parameters, hii
30: let referrer := s′ .w′ .activedocument.location
31: let referrerPolicy := s′ .d.headers[ReferrerPolicy]
32: let w′ := hν5 , hi, ⊥i
33: let s′ .w′ .activedocument.subwindows
֒→ := s′ .w′ .activedocument.subwindows+hi w′
34: SEND(ν5 , req, url, ⊥, referrer, referrerPolicy, s′ )
35: case hFORM, url, method, data, hrefwindowi
36: if method 6∈ {GET, POST} then 30
37: stop hi, s′
38: end if
39: let w′ := GETNAVIGABLEWINDOW(w, hrefwindow, ⊥, s′ )
40: if method = GET then
41: let body := hi
42: let parameters := data
43: let origin := ⊥
44: else
45: let body := data
46: let parameters := url.parameters
47: let origin := s′ .d.origin
48: end if
49: let req := hHTTPReq, ν4 , method, url.host, url.path, hi, parameters, bodyi
50: let referrer := s′ .d.location
51: let referrerPolicy := s′ .d.headers[ReferrerPolicy]
52: let s′ := CANCELNAV(s′ .w′ .nonce, s′ )
53: SEND(s′ .w′ .nonce, req, url, origin, referrer, referrerPolicy, s′ )
30 The working draft for HTML5 allowed for DELETE and PUT methods in HTML5 forms. However, these have since
53
54: case hSETSCRIPT, window, scripti
55: let w′ := GETWINDOW(w, window, s′ )
56: let s′ .w′ .activedocument.script := script
57: stop hi, s′
58: case hSETSCRIPTSTATE, window, scriptstatei
59: let w′ := GETWINDOW(w, window, s′ )
60: let s′ .w′ .activedocument.scriptstate := scriptstate
61: stop hi, s′
62: case hXMLHTTPREQUEST, url, method, data, xhrreferencei
63: if method ∈ {CONNECT, TRACE, TRACK} ∧ xhrreference 6∈ {N , ⊥} then
64: stop hi, s′
65: end if
66: if url.host 6≡ s′ .d.origin.host
֒→ ∨ url 6≡ s′ .d.origin.protocol then
67: stop hi, s′
68: end if
69: if method ∈ {GET, HEAD} then
70: let data := hi
71: let origin := ⊥
72: else
73: let origin := s′ .d.origin
74: end if
75: let req := hHTTPReq, ν4 , method, url.host, url.path, , url.parameters, datai
76: let referrer := s′ .d.location
77: let referrerPolicy := s′ .d.headers[ReferrerPolicy]
78: SEND(hs′ .d.nonce, xhrreferencei, req, url, origin, referrer, referrerPolicy, s′ )
79: case hBACK, windowi 31
80: let w′ := GETNAVIGABLEWINDOW(w, window, ⊥, s′ )
81: NAVBACK(w, s′ )
82: stop hi, s′
83: case hFORWARD, windowi
84: let w′ := GETNAVIGABLEWINDOW(w, window, ⊥, s′ )
85: NAVFORWARD(w, s′ )
86: stop hi, s′
87: case hCLOSE, windowi
88: let w′ := GETNAVIGABLEWINDOW(w, window, ⊥, s′ )
89: remove s′ .w′ from the sequence containing it
90: stop hi, s′
91: case hPOSTMESSAGE, window, message, origini
92: let w′ ← Subwindows(s′ ) such that s′ .w′ .nonce ≡ window
93: if ∃ j ∈ N such that s′ .w′ .documents. j.active ≡ ⊤
֒→ ∧(origin 6≡ ⊥ =⇒ s′ .w′ .documents. j.origin ≡ origin) then
94: let s′ .w′ .documents. j.scriptinputs
֒→ := s′ .w′ .documents. j.scriptinputs
֒→ +hi hPOSTMESSAGE, s′ .w.nonce, s′ .d.origin, messagei
95: end if
96: stop hi, s′
97: case else
31 Note that navigating a window using the back/forward buttons does not trigger a reload of the affected documents. While
real world browser may chose to refresh a document in this case, we assume that the complete state of a previously viewed
document is restored. A reload can be triggered non-deterministically at any point (in the main algorithm).
54
98: stop hi, s′
99: end function
The function PROCESSRESPONSE is responsible for processing an HTTP response (response) that
was received as the response to a request (request) that was sent earlier. In reference, either a window
or a document reference is given (see explanation for Algorithm 4 above). requestUrl contains the URL
used when retrieving the document.
The function first saves any cookies that were contained in the response to the browser state, then
checks whether a redirection is requested (Location header). If that is not the case, the function creates
a new document (for normal requests) or delivers the contents of the response to the respective receiver
(for XHR responses).
55
40: stop {}, s′
41: end if
42: let script := π1 (response.body)
43: let scriptstate := π2 (response.body)
44: let referrer := request.headers[Referer]
45: let d := hν7 , requestUrl, response.headers, referrer, script, scriptstate, hi, hi, ⊤i
46: if s′ .w.documents ≡ hi then
47: let s′ .w.documents := hdi
48: else
49: let i ← N such that s′ .w.documents.i.active ≡ ⊤
50: let s′ .w.documents.i.active := ⊥
51: remove s′ .w.documents.(i + 1) and all following documents
֒→ from s′ .w.documents
52: let s′ .w.documents := s′ .w.documents +hi d
53: end if
54: stop {}, s′
55: else if ∃ w ∈ Subwindows(s′ ), d such that s′ .d.nonce ≡ π1 (reference)
֒→ ∧ s′ .d = s′ .w.activedocument then ⊲ process XHR response
56: let headers := response.headers − Set-Cookie
57: let s′ .d.scriptinputs := s′ .d.scriptinputs +hi
hXMLHTTPREQUEST, headers, response.body, π2 (reference)i
58: end if
59: end function
Main Algorithm.. This is the main algorithm of the browser relation. It receives the message m as input,
as well as a, f and s as above.
56
24: let protocol ← {P, S}
25: let host ← Doms
26: let path ← S
27: let fragment ← S
28: let parameters ← [S × S]
29: let url := hURL, protocol, host, path, parameters, fragmenti
30: let req := hHTTPReq, ν2 , GET, host, path, hi, parameters, hii
31: SEND(windownonce, req, url, ⊥, ⊥, ⊥, s′ )
32: else if switch ≡ reload then ⊲ Reload some document.
33: let w ← Subwindows(s′ ) such that s′ .w.documents 6= hi
֒→ if possible; otherwise stop hi, s′
34: let url := s′ .w.activedocument.location
35: let req := hHTTPReq, ν2 , GET, url.host, url.path, hi, url.parameters, hii
36: let referrer := s′ .w.activedocument.referrer
37: let s′ := CANCELNAV(s′ .w.nonce, s′ )
38: SEND(s′ .w.nonce, req, url, ⊥, referrer, ⊥, s′ )
39: else if switch ≡ forward then
40: NAVFORWARD(w, s′ )
41: else if switch ≡ back then
42: NAVBACK(w, s′ )
43: end if
44: else if m ≡ FULLCORRUPT then ⊲ Request to corrupt browser
45: let s′ .isCorrupted := FULLCORRUPT
46: stop hi, s′
47: else if m ≡ CLOSECORRUPT then ⊲ Close the browser
48: let s′ .secrets := hi
49: let s′ .windows := hi
50: let s′ .pendingDNS := hi
51: let s′ .pendingRequests := hi
52: let s′ .sessionStorage := hi
53: let s′ .cookies ⊂hi Cookies such that
֒→ (c ∈hi s′ .cookies) ⇐⇒ (c ∈hi s.cookies ∧ c.content.session ≡ ⊥)
54: let s′ .isCorrupted := CLOSECORRUPT
55: stop hi, s′
56: else if ∃ hreference, request, url, key, f i ∈hi s′ .pendingRequests
֒→ such that π1 (decs (m, key)) ≡ HTTPResp then ⊲ Encrypted HTTP response
57: let m′ := decs (m, key)
58: if m′ .nonce 6≡ request.nonce then
59: stop hi, s
60: end if
61: remove hreference, request, url, key, f i from s′ .pendingRequests
62: PROCESSRESPONSE(m′, reference, request, url, s′ )
63: else if π1 (m) ≡ HTTPResp ∧ ∃ hreference, request, url, ⊥, f i ∈hi s′ .pendingRequests
֒→ such that m′ .nonce ≡ request.key then
64: remove hreference, request, url, ⊥, f i from s′ .pendingRequests
65: PROCESSRESPONSE(m, reference, request, url, s′ )
66: else if m ∈ DNSResponses then ⊲ Successful DNS response
67: if m.nonce 6∈ s.pendingDNS ∨ m.result 6∈ IPs ∨ m.domain 6≡ π2 (s.pendingDNS).host then
68: stop hi, s
69: end if
70: let hreference, message, urli := s.pendingDNS[m.nonce]
71: if url.protocol ≡ S then
72: let s′ .pendingRequests := s′ .pendingRequests
֒→ +hi hreference, message, url, ν3 , m.resulti
57
73: let message := enca (hmessage, ν3 i, s′ .keyMapping[message.host])
74: else
75: let s′ .pendingRequests := s′ .pendingRequests
֒→ +hi hreference, message, url, ⊥, m.resulti
76: end if
77: let s′ .pendingDNS := s′ .pendingDNS− m.nonce
78: stop hhm.result, a, messageii, s′
79: end if
80: stop hi, s
58
F. Formal Model of OAuth with a Network Attacker
We here present the full details of our formal model of OAuth which we use to analyze all but one of
the authentication and authorization properties. This model contains a network attacker. We will later
derive from this model a model where the network attacker is replaced by a web attacker.
n
We model OAuth as a web system (in the sense of Appendix C.3). We call a web system OWS =
(W , S , script, E 0 ) an OAuth web system with a network attacker if it is of the form described in what
follows.
F.1. Outline
The system W = Hon ∪ Net consists of a network attacker process (in Net), a finite set B of web
browsers, a finite set RP of web servers for the relying parties, a finite set IDP of web servers for the
identity providers, with Hon := B ∪ RP ∪ IDP. More details on the processes in W are provided below.
We do not model DNS servers, as they are subsumed by the network attacker. Figure 13 shows the set
of scripts S and their respective string representations that are defined by the mapping script. The set E 0
contains only the trigger events as specified in Appendix C.3.
s∈S script(s)
Ratt att_script
script_rp_index script_rp_index
script_rp_implicit script_rp_implicit
script_idp_form script_idp_form
n n
This outlines OWS . We will now define the DY processes in OWS and their addresses, domain
names, and secrets in more detail.
N = N ∪ ˙ RPSecrets′ ∪
˙ Passwords ∪
˙ KSSL ∪ ˙ ProtectedResources .
|{z} |{z} | {z } | {z } | {z }
infinite sequence finite finite finite finite
We then define RPSecrets := RPSecrets ∪ {⊥}. These sets are used as follows:
59
• The set N contains the nonces that are available for each DY process in W (it can be used to create
a run of W ).
• The set KSSL contains the keys that will be used for SSL encryption. Let sslkey : Doms → KSSL
be an injective mapping that assigns a (different) private key to every domain. For an atomic DY
process p we define sslkeys p = h{hd, sslkey(d)i | d ∈ dom(p)}i.
• The set Passwords is the set of passwords (secrets) the browsers share with the identity providers.
These are the passwords the users use to log in at the IdPs.
• The set RPSecrets is the set of passwords (secrets) the relying parties share with the identity
providers. These are the passwords the relying parties use to log in at the IdPs. The passwords
can also be blank (⊥).
• The set ProtectedResources contains a secret for each combination of IdP, client, and user. These
are thought of as protected resources that only the owner of the resource (i.e., the user) should be
able to read. (See also Definition 45.)
• By secretOfID : ID → Passwords we denote the bijective mapping that assigns secrets to all iden-
tities.
• Let ownerOfSecret : Passwords → B denote the mapping that assigns to each secret a
browser that owns this secret. Now, we define the mapping ownerOfID : ID → B, i 7→
ownerOfSecret(secretOfID(i)), which assigns to each identity the browser that owns this iden-
tity (we say that the identity belongs to the browser).
• Let trustedRPs : Passwords → 2RP denote a mapping that assigns a set of trusted relying parties
to each password. Intuitively a trusted relying party is a relying party the user entrusts with her
password (in the resource owner password credentials grant mode of OAuth).
• Let clientIDOfRP : (RP ∪ {⊥}) × IDP → S ∪ {⊥} denote a mapping that assigns an OAuth client
id for an relying party to each combination of a relying party and an identity provider. We require
that clientIDOfRP(·, i) is bijective for all i ∈ IDP and that clientIDOfRP(r, i) = ⊥ iff r = ⊥ for all
i ∈ IDP.
• Let secretOfRP : RP × IDP → RPSecrets denote a bijective mapping that assigns a relying party
password (or the empty password ⊥) to each combination of a relying party and an identity
provider.
60
• As a shortcut, we define the mapping secretOfClientID : S × IDP → RPSecrets to return the
relying party password to a relying party identified by an OAuth client id (at some specific
identity provider), i.e., secretOfClientID(s, i) maps to secretOfRP(r, i) with r such that s =
clientIDOfRP(r, i).
• By resourceOf : IDP × (RP ∪ {⊥}) × (ID ∪ {⊥}) → ProtectedResources we denote the injective
mapping that assigns a protected resource to each combination of user identity, IdP and client
(RP). We also include protected resources that are not assigned to a specific user (in this case, the
user is ⊥) and those that are not assigned to a specific RP (the RP then is ⊥). Note that a protected
resource depends not only on the IdP and user ID but also the RP. This is motivated by the fact
that different RPs may get access to different protected resources at one IdP, even if they access
the resources of the same user. In the resource owner password credentials mode, RPs can also
access resources that do not depend on the RP, we then have that RP is ⊥.32
F.5. Corruption
RPs and IdPs can become corrupted: If they receive the message CORRUPT, they start collecting all
incoming messages in their state and (upon triggering) send out all messages that are derivable from
their state and collected input messages, just like the attacker process. We say that an RP or an IdP is
honest if the according part of their state (s.corrupt) is ⊥, and that they are corrupted otherwise.
We are now ready to define the processes in W as well as the scripts in S in more detail.
32 In the resource owner password credentials mode, the RP gets the user’s credentials and thus has full access to the user’s
account at IdP. This access is not bound to potential limitations that depend on the RP’s identity.
61
F.7. Network Attackers
As mentioned, the network attacker na is modeled to be a network attacker as specified in Appendix C.3.
We allow it to listen to/spoof all available IP addresses, and hence, define I na = IPs. The initial state is
sna
0 = hattdoms, sslkeys, signkeysi, where attdoms is a sequence of all domains along with the correspond-
ing private keys owned by the attacker na, sslkeys is a sequence of all domains and the corresponding
public keys, and signkeys is a sequence containing all public signing keys for all IdPs.
F.8. Browsers
Each b ∈ B is a web browser as defined in Appendix E, with I b := addr(b) being its addresses.
To define the inital state, first let IDb := ownerOfID−1 (b) be the set of all IDs of b. We then define the
set of passwords that a browser b gives to an origin o to consist of two parts: (1) If the origin belongs
to an IdP, then the user’s passwords of this IdP are contained in the set. (2) If the origin belongs to an
RP, then those passwords with which the user entrusts this RP are contained in the set. To define this
mapping in the initial state, we first define for some process p
n
Secretsb,p = s b = ownerOfSecret(s) ∧ (∃ i : s = secretOfID(i) ∧ i ∈ governor −1 (p))
o
∨ (∃ R : p ∈ R ∧ s ∈ trustedRPs−1 (R)) .
Then, the initial state sb0 is defined as follows: the key mapping maps every domain to its public (ssl)
key, according to the mapping sslkey; the DNS address is an address of the network attacker; the list of
secrets contains an entry hhd, Si, hSecretsb,p ii for each p ∈ RP ∪ IDP and d ∈ dom(p); ids is hIDb i; sts
is empty.
62
one of the entries in this subterm, the HTTPS request is sent out over the network (to the resolved IP
address) and stored in the subterm pendingRequests of the RP’s state. Note that this mechanism is very
similar to (generic) browsers (see Appendix E).
Initial Request. In a typical flow, r will first receive an HTTP GET request from a browser for the path /.
In this case, r returns the script script_rp_index. Besides providing arbitrary links, this script allows
users to start an OAuth flow in the browser. If an OAuth flow is started, this script non-deterministically
chooses an identity of the user, i.e., a combination of a username and a domain of an IdP. Further
this script non-deterministically decides whether an interactive login (i.e., authorization code mode or
implicit mode) or a non-interactive login (i.e., resource owner password credentials mode) is used. If an
interactive login is chosen, the script instructs the browser to send an HTTPS POST request to r for the
path /startInteractiveLogin. This POST request contains in its body the domain of the IdP.33 If
the script chooses a non-interactive login, the domain of the IdP, the username, and the user’s password
are sent to r in an HTTPS POST request for the path /passwordLogin.
As the flow now forks into different branches, we will explain (the first part of) each of these branches
separately: If the script has chosen to run an interactive login, we continue our description in the para-
graph Interactive Login below. Else, if the script has chosen to run a non-interactive login, we continue
our description of this in the paragraph Non-Interactive Login.
Interactive Login. In this case, script_rp_index has sent an HTTPS POST request for the path
/startInteractiveLogin to r containing the name of an IdP in its body. When r receives such a
request, r non-deterministically decides whether the OAuth authorization code mode or the OAuth im-
plicit mode is used. Also, r non-deterministically selects a redirect URI redirect_uri of its redirection
endpoints (and appends the domain of the IdP to this redirect URI) or selects no redirect URI. Further, r
non-deterministically selects a (fresh) nonce state and a (fresh) nonce as login session id. Then, r saves
all the chosen information in its state. Now, r constructs and sends an HTTPS response containing an
HTTP 303 location redirect or an HTTP 307 location redirect34 (chosen non-deterministically) which
points to the corresponding authorization endpoint at the IdP along with r’s OAuth client id for this
IdP, state and information which OAuth mode r has chosen. Additionally, this response also contains
a Set-Cookie header, which sets a cookie containing the login session id. r also stores a record in the
subterm loginSessions of its state. This record contains the login session id, the chosen OAuth mode,
and the domain of the IdP.
Later, when IdP redirects the user’s browser to r’s redirection endpoint, r will receive an HTTPS
GET request for the path /redirectionEndpoint. This request must contain a login session id cookie,
which refers to the information stored in the subterm loginSessions in r’s state. The request must also
contain a parameter with the domain of the IdP and this domain must match the domain stored for this
login session.
If r has stored that for this login session the OAuth authorization code mode is used, r checks if the
state value contained in a parameter is correct (i.e., the value of this parameter is congruent to the value
recorded in r’s state). Then, r extracts the authorization code code from the parameters of the incoming
request and prepares an HTTPS POST request to the IdP’s token endpoint to obtain an access token as
follows: r adds the authorization code to the request’s body. If a redirect URI has been set by r before
(according to r’s state for this login session), the redirect URI is included in the request’s body. If r
knows an OAuth client secret for the IdP, r adds its OAuth client id and its OAuth client secret for the
IdP to the header of the request, else r adds its OAuth client id for the IdP to the request’s body. Now,
33 Note that while the script has selected an identity of the user, only the domain of the IdP is used in this case and during
the authentication to the IdP, a different username may be chosen.
34 Note that while in this paper we present an attack against OAuth based on an HTTP 307 location redirect, our analysis
shows that an HTTP 307 location redirect is safe at this point in the protocol flow.
63
r sends a DNS request for the domain of the IdP’s token endpoint to the DNS server (according to r’s
state), saves this (prepared) request and all information belonging to the (incoming) HTTPS request r
received from the browser (such as IP addresses, temporary HTTPS keys) in pendingDNS in its state.
We will continue our description of which requests r will process next in the OAuth authorization code
mode in the paragraph Token Response below.
If the (incoming) HTTPS request’s login session at r states that implicit mode is used, r instead sends
an HTTPS response to the sender of the incoming message. This HTTPS response contains the script
script_rp_implicit and the initial state for this script in this response contains the domain of the IdP.
In a browser, this script extracts access_token and state from the fragment part of its URL and extracts
the domain of the IdP from its initial state. The script then sends this information in the body of an
HTTPS POST request for the path /receiveTokenFromImplicitGrant to r.
When r receives such an HTTPS POST request (for the path /receiveTokenFromImplicitGrant),
r checks if this request contains a login session id cookie, which refers to the information stored in its
state and if the values of state and idp (contained in the request) match the information there. Next, r
prepares an HTTPS request to IdP’s introspection endpoint containing the access token just received. r
saves all information belonging to this new request and the (incoming) request it had just received in
pendingDNS in its state and sends out a DNS request for the domain of the IdP’s introspection endpoint
to the DNS server.
We describe what happens when r later receives the response from IdP in the paragraph Introspection
Response below.
Non-Interactive Login. In this case, script_rp_index has sent an HTTPS POST request for the path
/passwordLogin to r containing a domain of an IdP, a username and a user’s password in its body.
Next, r constructs an HTTPS POST request to the token endpoint of the IdP. This request contains
the username and the user’s password in its body and if r knows an OAuth client secret for the IdP,
the request contains an HTTP header with r’s OAuth client id and OAuth client secret. r saves all
information belonging to this new request and the (incoming) request r has just received in the subterm
pendingDNS in r’s state and sends out a DNS request for the domain of the IdP’s token endpoint to the
DNS server.
We describe what happens when r later receives the response from the IdP in the paragraph Token
Response below.
Client Credentials Mode. When r receives a TRIGGER message (which models that r non-
deterministically starts an OAuth flow in the client credentials mode), r first non-deterministically se-
lects a domain of an IdP. Then, r constructs an HTTPS POST request to the token endpoint of the IdP.
This request contains an HTTP header with r’s OAuth client id and OAuth client secret.35 r saves all
information belonging to this (prepared) request in pendingDNS and sends out a DNS request for the
domain of the IdP’s token endpoint to the DNS server.
We describe what happens when r later receives the response from IdP in the paragraph Token Re-
sponse below.
Token Response. When r receives an encrypted HTTP response that matches a record in the subterm
pendingRequests of its state and belongs to a request for an access token from an IdP (according to
the information recorded in pendingRequests), then r extracts the access token and prepares an HTTPS
request to the IdP’s introspection endpoint containing the access token. r saves all information belonging
to this new request in pendingDNS. Further, r also stores selected information, which is passed along in
r’s state in the corresponding record of the incoming request, such as the IP address of the sender and
35 Note that in our model, r may even construct such a request if r does not have an OAuth client secret for the IdP. In this
case, the symbol ⊥ is placed in this header instead of an OAuth client secret. The IdP, however, will drop such a request, as it
is not authenticated.
64
the HTTPS response key of the request which initiated r’s request for the access token before. Then, r
sends out a DNS request for the domain of the IdP’s introspection endpoint to the DNS server.
Introspection Response. When r receives an encrypted HTTP response that matches a record in the sub-
term pendingRequests in its state and this record belongs to a request to an IdP’s introspection endpoint,
r checks whether the response belongs to a flow in client credentials mode (according to the record). If
that is the case, r stops. Otherwise, r non-deterministically proceeds with either an authorization flow or
an authentication flow:
• If authorization is selected, r retrieves the protected resource from the IdP’s response and sends out
an HTTPS response to the IP address recorded in the record in pendingRequests (which contains
the IP address of the browser, which initially sent either user credentials, an authorization code, or
an access token).
• Else, authentication is selected. Now, if the response does not contain r’s OAuth client id, r stops.
Otherwise, r retrieves the user id from the response and non-deterministically chooses a fresh
nonce as a service token. r records in its state that the service token belongs to the user identified
by the user id at the IdP. Now, r sends out a response (as above) which contains the service token
in a cookie.
In both cases, r replies with the script script_rp_index, which provides arbitrary links and the possibility
to start a new OAuth flow (see above).
This concludes the description of the behaviour of an RP.
Formal description. We now provide the formal definition of r as an atomic DY process (I r , Z r , Rr , sr0 ).
As mentioned, we define I r = addr(r). Next, we define the set Z r of states of r and the initial state sr0
of r.
Definition 41. An IdP registration record is a term of the form
htokenEndpoint, authorizationEndpoint, introspectionEndpoint, clientId, clientPasswordi
with tokenEndpoint, authorizationEndpoint, introspectionEndpoint ∈ URLs, clientId ∈ S, and
clientPassword ∈ N .
An IdP registration record for an identity provider i at a relying party r is an IdP registration
record with tokenEndpoint.host, authorizationEndpoint.host, introspectionEndpoint.host ∈ dom(i),
clientId = clientIDOfRP(r, i), and clientPassword = secretOfRP(r, i).
We now specify the relation Rr . Just like in Appendix E, we describe this relation by a non-
deterministic algorithm. In several places throughout this algorithm we use placeholders to generate
“fresh” nonces as described in our communication model (see Definition 1). Figure 14 shows a list of all
placeholders used.
65
Placeholder Usage
ν1 new HTTP request nonce
ν2 lookup key for pending DNS entry
ν3 new service token
ν4 fresh HTTPS response key
ν5 new HTTP request nonce
ν6 lookup key for pending DNS entry
ν7 new CSRF token
ν8 new login session cookie
ν9 new HTTP request nonce
ν10 lookup key for pending DNS entry
ν11 new HTTP request nonce
ν12 lookup key for pending DNS entry
ν13 new HTTP request nonce
ν14 lookup key for pending DNS entry
66
29: stop hi, s ⊲ In client credential grant mode, no service token is issued.
30: end if
31: let goal ← {authz, authn} ⊲ Proceed with authorization or authentication.
32: if goal ≡ authz then
33: let headers := hi
34: else
35: if clientId ≡ s′ .idps[idp].clientId ∨ (clientId ≡ hi ∧ mode ≡ password∧
֒→ s′ .idps[idp].clientPassword ≡ ⊥) then
36: if user ≡ hi then
37: stop hi, s
38: end if
39: else
40: stop hi, s
41: end if
42: let serviceToken := ν3
43: let s′ .serviceTokens[serviceToken] := huser, idpi
44: let headers := hhSet-Cookie, hhserviceToken, hserviceToken, ⊥, ⊥, ⊤iiiii
45: end if
46: let headers := headers +hi hReferrerPolicy, origini
47: let m′ := encs (hHTTPResp, n′ , 200, headers, hscript_rp_index, hiii, k′ )
48: stop hh f ′ , a′ , m′ ii, s′
49: end if
50: stop hi, s
51: else if m ∈ DNSResponses then ⊲ Successful DNS response
52: if m.nonce 6∈ s.pendingDNS ∨ m.result 6∈ IPs ∨ m.domain 6≡ s.pendingDNS[m.domain].2.host then
53: stop hi, s
54: end if
55: let hreference, requesti := s.pendingDNS[m.nonce]
56: let s′ .pendingRequests := s′ .pendingRequests
֒→ +hi hreference, request, ν4 , m.resulti
57: let message := enca (hrequest, ν4 i, s′ .keyMapping[request.host])
58: let s′ .pendingDNS := s′ .pendingDNS− m.nonce
59: stop hhm.result, a, messageii, s′
60: else if m ≡ TRIGGER then ⊲ Start Client Credentials Grant
61: let idpEntry ← s′ .idps
62: let idp := π1 (idpEntry)
63: let tokenEndpoint := s′ .idps[idp].tokenEndpoint ⊲ tokenEndpoint is a URL
64: let host := tokenEndpoint.domain
65: let path := tokenEndpoint.path
66: let parameters := tokenEndpoint.parameters
67: let headers := hhAuthorization, hs′ .idps[idp].clientId, s′ .idps[idp].clientPasswordiii
68: let message :=
֒→ hHTTPReq, ν5 , POST, host, path, parameters, headers, hhgrant_type, client_credentialsiii
69: let s′ .pendingDNS[ν6 ] := hhclient_credentials, idp, ⊥, ⊥, ⊥, ⊥i, messagei
70: stop hhs′ .DNSaddress, a, hDNSResolve, idp.tokenEndpoint.domain, ν6 iii, s′
71: else ⊲ Handle HTTP requests
72: let mdec , k, k′ , inDomain such that
֒→ hmdec , ki ≡ deca (m, k′ ) ∧ hinDomain, k′i ∈ s.sslkeys
֒→ if possible; otherwise stop hi, s
73: let n, method, path, parameters, headers, body such that
֒→ hHTTPReq, n, method, inDomain, path, parameters, headers, bodyi ≡ mdec
֒→ if possible; otherwise stop hi, s
74: if path ≡ / then ⊲ Serve index page.
75: let headers := hhReferrerPolicy, originii
67
76: let m′ := encs (hHTTPResp, n, 200, headers, hscript_rp_index, hiii, k)
77: stop hh f , a, m′ ii, s′
78: else if path ≡ /startInteractiveLogin∧ method ≡ POST then ⊲ Serve start interactive login request.
79: if headers[Origin] 6≡ hinDomain, Si then ⊲ CSRF protection.
80: stop hi, s
81: end if
82: let idp := body
83: if idp 6∈ s′ .idps then
84: stop hi, s
85: end if
86: let state := ν7
87: let mode ← {code, token}
88: let responseStatus ← {303, 307}
89: let authEndpoint := s′ .idps[idp].authorizationEndpoint ⊲ authEndpoint is a URL
90: let authEndpoint.parameters := authEndpoint.parameters +hi hresponse_type, modei
91: let authEndpoint.parameters := authEndpoint.parameters +hi
֒→ hclient_id, s′ .idps[idp].clientIdi
92: let authEndpoint.parameters := authEndpoint.parameters +hi hstate, statei
93: let redirectUri ← {⊥, ⊤}
94: if redirectUri ≡ ⊤ then
95: let sslkey′ ← s′ .sslkeys ⊲ Choose one of RP’s domains non-deterministically
96: let host′ := π1 (sslkey′ )
97: let redirectUri := hURL, S, host′ , /redirectionEndpoint, hhidp, idpii, hii
98: end if
99: let loginSessionId := ν8
100: let s′ .loginSessions := s′ .loginSessions +hi hloginSessionId, hidp, state, mode, redirectUriii
101: let headers := hhLocation, authEndpointii
102: let headers := headers +hi hSet-Cookie, hhloginSessionId, hloginSessionId, ⊤, ⊤, ⊤iiii
103: let headers := headers +hi hReferrerPolicy, origini
104: let m′ := encs (hHTTPResp, n, responseStatus, headers, ⊥i, k)
105: stop hh f , a, m′ ii, s′
106: else if path ≡ /redirectionEndpoint then
107: let loginSessionId := headers[Cookie][loginSessionId]
108: let idp, state, mode, redirectUri such that hidp, state, mode, redirectUrii ≡
֒→ s′ .loginSessions[loginSessionId] if possible; otherwise stop hi, s
109: let clientId := s′ .idps[idp].clientId
110: if idp 6≡ parameters[iss] ∨ clientId 6≡ parameters[client_id] then
111: stop hi, s
112: end if
113: if mode ≡ code then ⊲ Continue Authorization Code Grant
114: if parameters[state] 6≡ state then
115: stop hi, s
116: end if
117: let code := parameters[code]
118: let tokenRequestHeaders := hi
119: let tokenRequestBody := hhgrant_type, authorization_codei, hcode, codeii
120: if redirectUri 6≡ ⊥ then
121: let tokenRequestBody := tokenRequestBody +hi hredirect_uri, redirectUrii
122: end if
123: let clientPassword := s′ .idps[idp].clientPassword
124: if clientPassword ≡ ⊥ then
125: let tokenRequestBody := tokenRequestBody +hi hclient_id, clientIdi
126: else
127: let tokenRequestHeaders := tokenRequestHeaders +hi
68
֒→ hAuthorization, hclientId, clientPasswordii
128: end if
129: let tokenEndpoint := s′ .idps[idp].tokenEndpoint
130: let message := hHTTPReq, ν9 , POST, tokenEndpoint.domain, tokenEndpoint.path,
tokenEndpoint.parameters, tokenRequestHeaders, tokenRequestBodyi
131: let s′ .pendingDNS[ν10 ] := hhcode, idp, a, f , n, ki, messagei
132: stop hhs′ .DNSaddress, a, hDNSResolve, tokenEndpoint.domain, ν10 iii, s′
133: else if mode ≡ token then ⊲ Continue Implicit Grant
134: let headers := hhReferrerPolicy, originii
135: let m′ := encs (hHTTPResp, n, 200, headers, hscript_rp_implicit, idpii, k)
136: stop hh f , a, m′ ii, s′
137: end if
138: stop hi, s
139: else if path ≡ /passwordLogin∧ method ≡ POST then
140: if headers[Origin] 6≡ hinDomain, Si then ⊲ CSRF protection.
141: stop hi, s
142: end if
143: let idp, username, password such that hhusername, idpi, passwordi ≡ body if possible; otherwise
֒→ stop hi, s
144: let tokenRequestHeaders := hi
145: let tokenRequestBody := hhgrant_type, passwordi, husername, husername, idpii,
֒→ hpassword, passwordii
146: let clientId := s′ .idps[idp].clientId
147: let clientPassword := s′ .idps[idp].clientPassword
148: if clientPassword 6≡ ⊥ then
149: let tokenRequestHeaders := tokenRequestHeaders +hi
֒→ hAuthorization, hclientId, clientPasswordii
150: end if
151: let tokenEndpoint := s′ .idps[idp].tokenEndpoint
152: let message := hHTTPReq, ν11 , POST, tokenEndpoint.domain, tokenEndpoint.path,
tokenEndpoint.parameters, tokenRequestHeaders, tokenRequestBodyi
153: let s′ .pendingDNS[ν12 ] := hhpassword, idp, a, f , n, ki, messagei
154: stop hhs′ .DNSaddress, a, hDNSResolve, tokenEndpoint.domain, ν12 iii, s′
155: else if path ≡ /receiveTokenFromImplicitGrant∧ method ≡ POST then
156: if headers[Origin] 6≡ hinDomain, Si then ⊲ CSRF protection.
157: stop hi, s
158: end if
159: let loginSessionId := headers[Cookie][loginSessionId]
160: let idp, state, mode, redirectUri such that hidp, state, mode, redirectUrii ≡
֒→ s′ .loginSessions[loginSessionId] if possible; otherwise stop hi, s
161: let token such that htoken, state, idpi ≡ body if possible; otherwise stop hi, s
162: let introspectionEndpoint := s′ .idps[idp].introspectionEndpoint ⊲ introspectionEndpoint is a
URL
163: let parameters′ := introspectionEndpoint.parameters
164: let parameters′ := parameters′ +hi htoken, tokeni
165: let host := introspectionEndpoint.domain
166: let path′ := introspectionEndpoint.path
167: let message := hHTTPReq, ν13 , GET, host, path′ , parameters′ , hi, hii
168: let s′ .pendingDNS[ν14 ] := hhintrospect, implicit, idp, a, f , n, ki, messagei
169: stop hhs′ .DNSaddress, a, hDNSResolve, introspectionEndpoint.domain, ν14 iii, s′
170: end if
171: end if
172: stop hi, s
In the following scripts, to extract the current URL of a document, the function
69
GETURL(tree, docnonce) is used. We define this function as follows: It searches for the document
with the identifier docnonce in the (cleaned) tree tree of the browser’s windows and documents. It then
returns the URL u of that document. If no document with nonce docnonce is found in the tree tree, ✸ is
returned.
We use the helper function GETDOCWINDOW(tree, docnonce). It returns the nonce of the window
in tree that contains the document identified by docnonce.
70
messages and non-deterministically sending out whatever messages are derivable from its state.
Otherwise, IdPs react to three types of requests:
Requests to the authorization endpoint path: In this case, the IdP expects a POST request contain-
ing valid user credentials. If the user credentials are not supplied, or the request is not a POST request,
the answer contains a script which shows a form to the user to enter her user credentials. In our model,
the script just extracts the user credentials from the browser and sends a request to the IdP containing the
user credentials and any OAuth parameters contained in the original request (e.g., the intended redirect
URI).
If the IdP received a POST request with valid user credentials, it checks the contained client identifier
against its own list of clients. If the client identifier is unknown, the IdP aborts. Otherwise, it ensures
that the redirect URI, if contained in the request, is valid. For this, it checks the list of redirect URIs
stored along with the client identifier. If none of the redirect URIs match the redirect URI presented in
the request (see “Matching Redirect URIs” below), the IdP aborts. If no redirect URI is provided in the
request, the first URI in the list of redirect URIs is chosen as the redirect URI.
Now the IdP creates a new authorization code and saves this code together with the client identifier
and the redirect URI (if provided in the request) to the list of authorization codes.
Now, if the response type parameter in the request is “code”, the IdP issues a Location redirect header
to the redirect URI, appending (as parameters) the newly created authorization code and the state (if
provided in the request).
If the reponse type is “token”, the IdP redirects the browser to the redirect URI, but appends the
authorization code, the state (if provided) and a fixed string (containing the token type, which is “bearer”)
to the hash of the redirect URI.
Requests to the token endpoint path: Requests to the token endpoint path are only accepted by the
IdP if they are POST requests. The IdP then checks that the request either contains a valid client ID,
provided as a parameter, or a pair of client ID and client password in a basic authentication header.
If the grant type parameter is authorization code, then the IdP checks that the authorization code
delivered to it is contained in the list of codes. It checks that the client ID and redirect URI are the same
as those stored in the list of codes. It then creates an access token and returns it in the HTTPS response
(with token type “bearer”).
If the grant type is password, the IdP checks the provided username and password and creates an
access token as above.
If the grant type is client credentials, the IdP checks that the client was authorized with client ID and
client password above. If so, it creates an access token as above.
Requests to the introspection endpoint path: In this case, the IdP expects an access token in the
parameters of the request. If the access token is valid, the IdP returns the client and user id for which the
access token was issued along with the protected resource for this client, user, and IdP.
Formal description. In the following, we will first define the (initial) state of i formally and afterwards
present the definition of the relation Ri .
To define the initial state, we will need to add a list of all protected resources that this IdP manages.
We therefore define srlist i := h{resourceOf(i, c, u) | c ∈ RP ∪ {⊥}, u ∈ ID}i for some IdP i. (Note that we
do not use this term for term manipulations in the algorithm. Instead, this term ensures that the output
of the atomic process is derivable from the input.)
Definition 43. A state s ∈ Z i of an IdP i is a term of the form hsslkeys, srlist, authEndpoint,
tokenEndpoint, introspectEndpoint, clients, codes, corrupti where sslkeys= sslkeysi , srlist = srlist i ,
authEndpoint, tokenEndpoint, introspectEndpoint ∈ S, clients ∈ S × TN , codes ∈ TN , atokens ∈
[N × S].
An initial state si0 of i is a state of the form hsslkeysi , srlist i , w, x, y, clients i , hi, hi, ⊥i for some strings
71
w, x and y and a dictionary clientsi that for each relying party r contains an entry of the form
hclientIDOfRP(r, i), zi where z is a sequence of URL terms that may contain the wildcard ∗ (see Defini-
tion 4) where for every u ∈hi z we have that u.protocol ≡ S, u.host ∈ dom(r), u.parameters[iss] ≡
d for some d ∈ dom(i), u.parameters[client_id] ≡ clientIDOfRP(r, i), u.fragment ≡ hi, and
u.path ≡ /redirectionEndpoint. (Note that this includes the changes proposed by )
The relation Ri that defines the behavior of the IdP i is defined as follows:
Algorithm 13 Relation of IdP Ri
Input: ha, f , mi, s
1: if s′ .corrupt 6≡ ⊥ ∨ m ≡ CORRUPT then
2: let s′ .corrupt := hha, f , mi, s′ .corrupti
3: let m′ ← dV (s′ )
4: let a′ ← IPs
5: stop hha′ , a, m′ ii, s′
6: end if
7: let s′ := s
8: let mdec , k, k′ , inDomain such that
֒→ hmdec , ki ≡ deca (m, k′ ) ∧ hinDomain, k′i ∈ s.sslkeys
֒→ if possible; otherwise stop hi, s
9: let n, method, path, parameters, headers, body such that
֒→ hHTTPReq, n, method, inDomain, path, parameters, headers, bodyi ≡ mdec
֒→ if possible; otherwise stop hi, s
10: if path ≡ s.authEndpoint then ⊲ Authorization Endpoint.
11: if method ≡ GET ∨ (method ≡ POST ∧ (body[username] ≡ hi ∨ body[password] ≡ hi)) then
12: let data := parameters
13: let m′ := encs (hHTTPResp, n, 200, hhReferrerPolicy, originii, hscript_idp_form, dataii, k)
14: stop hh f , a, m′ ii, s′
15: else if method ≡ POST then
16: if headers[Origin] 6≡ hinDomain, Si then ⊲ CSRF protection.
17: stop hi, s
18: end if
19: let username := body[username]
20: let password := body[password]
21: let clientid := body[client_id]
22: let allowedredirects := s.clients[clientid]
23: if password 6≡ secretOfID(username) then
24: stop hi, s
25: end if
26: if allowedredirects ≡ hi then
27: stop hi, s
28: end if
29: let redirecturi := body[redirect_uri]
30: if redirecturi 6≡ hi then
31: if not redirecturi ∼˙ allowedredirects then
32: stop hi, s
33: end if
34: else
35: let redirecturi ← allowedredirects ⊲ Take one from list of redir URIs.
36: end if
37: if body[response_type] ≡ code then
38: let s′ .codes := s′ .codes +hi hν1 , hclientid, body[redirect_uri], usernameii ⊲ Create
authorization code.
39: let redirecturi.parameters := redirecturi.parameters +hi hcode, ν1 i
72
40: let redirecturi.parameters := redirecturi.parameters +hi hstate, body[state]i
41: let m′ := encs (hHTTPResp, n, 303, hhLocation, redirecturiii, hii, k)
42: stop hh f , a, m′ ii, s′
43: else ⊲ Assume response type token.
44: let s′ .atokens := s′ .atokens +hi hν1 , clientid, usernamei
45: let redirecturi.fragment := redirecturi.fragment +hi haccess_token, ν1 i
46: let redirecturi.fragment := redirecturi.fragment +hi htoken_type, beareri
47: let redirecturi.fragment := redirecturi.fragment +hi hstate, body[state]i
48: let m′ := encs (hHTTPResp, n, 303, hhLocation, redirecturiii, hii, k)
49: stop hh f , a, m′ ii, s′
50: end if
51: end if
52: else if path ≡ s.tokenEndpoint then ⊲ Token Endpoint.
53: if method 6≡ POST then
54: stop hi, s
55: end if
56: let auth := ⊥
57: let clientid := ⊥
58: if body[client_id] 6≡ hi then ⊲ Only client ID is provided, no password.
59: let clientid := body[client_id]
60: let clientinfo := s.clients[clientid]
61: if clientinfo ≡ hi ∨ secretOfClientID(clientid, i) 6≡ ⊥ then ⊲ Empty client secret allowed?
62: stop hi, s
63: end if
64: else if headers[Authorization].1 6≡ hi then
65: let clientid := headers[Authorization].1
66: let clientpw := headers[Authorization].2
67: if secretOfClientID(clientid, i) 6≡ clientpw ∨ clientpw ≡ ⊥ then
68: stop hi, s
69: end if
70: let auth := clientid ⊲ Authentication with client credentials.
71: end if
72: if body[grant_type] ≡ authorization_code then
73: if clientid ≡ ⊥ then
74: stop hi, s
75: end if
76: let codeinfo := s.codes[body[code]]
77: if codeinfo ≡ hi ∨ codeinfo.1 6≡ clientid ∨ codeinfo.2 6≡ body[redirect_uri] then
78: stop hi, s
79: end if
80: let s′ .codes := s′ .codes − body[code]
81: let s′ .atokens := s′ .atokens +hi hν1 , clientid, codeinfo.3i ⊲ Add nonce, client ID and user ID to list
of tokens.
82: let m′ := encs (hHTTPResp, n, 200, hi, hhaccess_token, ν1 i, htoken_type, beareriii, k)
83: stop hh f , a, m′ ii, s′
84: else if body[grant_type] ≡ password then
85: let username := body[username]
86: let password := body[password]
87: if password 6≡ secretOfID(username) then
88: stop hi, s
89: end if
90: let s′ .atokens := s′ .atokens +hi hν1 , clientid, usernamei
91: let m′ := encs (hHTTPResp, n, 200, hi, hhaccess_token, ν1 i, htoken_type, beareriii, k)
92: stop hh f , a, m′ ii, s′
73
93: else if body[grant_type] ≡ client_credentials then
94: if auth ≡ ⊥ then
95: stop hi, s
96: end if
97: let s′ .atokens := s′ .atokens +hi hν1 , clientid, ⊥i
98: let m′ := encs (hHTTPResp, n, 200, hi, hhaccess_token, ν1 i, htoken_type, beareriii, k)
99: stop hh f , a, m′ ii, s′
100: end if
101: else if path ≡ s.introspectEndpoint then ⊲ Introspection Endpoint.
102: if method 6≡ GET then
103: stop hi, s
104: end if
105: let atoken := parameters[token]
106: let clientid, userid such that hatoken, clientid, useridi ∈hi s′ .atokens if possible; otherwise stop hi, s
107: let secret := resourceOf(i, clientid, userid)
108: let body′ := hhprotected_resource, secreti, hclient_id, clientidi, huser, useridii
109: let m′ := encs (hHTTPResp, n, 200, hi, body′ i, k)
110: stop hh f , a, m′ ii, s′
111: end if
112: stop hi, s
74
G. Formal Model of OAuth with Web Attackers
w n
We now derive OWS (an OAuth web system with web attackers) from OWS by replacing the network
attacker with a finite set of web attackers.
w n
Definition 44. An OAuth web system with web attackers, OWS , is an OAuth web system OWS =
(W , S , script, E 0 ) with the following changes:
• We have W = Hon ∪ Web, in particular, there is no network attacker. The set Web contains a finite
number of web attacker processes. The set Hon is as described above, and additionally contains a
DNS server d as defined below.
• The set of IP addresses IPs contains no IP addresses for the network attacker, but instead a finite
set of IP addresses for each web attacker.
• The set of Domains Doms contains no domains for the network attacker, but instead a finite set of
domains for each web attacker.
• All honest parties use the DNS server d as their DNS server.
75
H. Formal Security Properties
The security properties for OAuth are formally defined as follows.
H.1. Authorization
n
Intuitively, authorization for OWS means that an attacker should not be able to obtain or use a protected
resource available to some honest RP at an IdP for some user unless certain parties involved in the
authorization process are corrupted.
n
Definition 45 (Authorization Property). Let OWS be an OAuth web system with a network attacker.
n n
We say that OWS is secure w.r.t. authorization iff for every run ρ of OWS , every state (S j , E j , N j ) in ρ,
j
every IdP i ∈ IDP, every r ∈ RP ∪ {⊥} with r being honest in S unless r = ⊥, every u ∈ ID ∪ {⊥}, for
n = resourceOf(i, r, u), n is derivable from the attackers knowledge in S j (i.e., n ∈ d0/ (S j (attacker))), it
follows that
1. i is corrupted in S j , or
Note that the protected resource n being available to the attacker also models that the attacker can use
a service of the IdP i under the name of the user u (e.g., the attacker can post to the Facebook wall of the
victim).
H.2. Authentication
n
Intuitively, authentication for OWS means that an attacker should not be able to login at an (honest)
RP under the identity of a user unless certain parties involved in the login process are corrupted. As
explained above, being logged in at an RP under some user identity means to have obtained a service
token for this identity from the RP.
n
Definition 46 (Authentication Property). Let OWS be an OAuth web system with a network attacker.
n n
We say that OWS is secure w.r.t. authentication iff for every run ρ of OWS , every state (S j , E j , N j )
in ρ, every r ∈ RP that is honest in S j , every i ∈ IDP, every g ∈ dom(i), every u ∈ S, every RP service
token of the form hn, hu, gii recorded in S j (r).serviceTokens, and n being derivable from the attackers
knowledge in S j (i.e., n ∈ d0/ (S j (attacker))), then the browser b owning u is fully corrupted in S j (i.e.,
the value of isCorrupted is FULLCORRUPT), some r′ ∈ trustedRPs(secretOfID(hu, gi)) is corrupted in
S j , or i is corrupted in S j .
76
Definition 47 (Emitting Events). Given an atomic process p, an event e, and a finite run ρ =
((S0 , E 0 , N 0 ), . . . , (Sn , E n , N n )) or an infinite run ρ = ((S0 , E 0 , N 0 ), . . . ) we say that p emits e iff there is
a processing step in ρ of the form
for some i ≥ 0 and a set of events E with e ∈ E. We also say that p emits m iff e = hx, y, mi for some
addresses x, y.
Sessions and OAuth Sessions. We now define a relation between processing steps. Intuitively, we say
that two processing steps are connected if one processing step causes the other. This can happen either
directly (i.e., one DY process handles an event output by another process) or indirectly (e.g., a script that
was loaded from an earlier message runs in a browser and outputs a new message).
are connected iff (1) ein,y ∈ Eout,x , or (2) py is a browser, ein,y is a trigger event, the browser py selects to
run a script (i.e., selects script in Line 9 of Algorithm 9), and the document selected in Line 13 was
created as the result of an HTTP(S) message in Eout,x .
Based on the notion of connected processing steps, we now define sessions to be sequences of con-
nected processing steps.
Definition 49 (Sessions). A Session (in a run ρ of a web system) is a sequence of processing steps
(Q0 , . . . , Qn ) or (Q0 , Q1 , . . .) such that (1) for all Qi with i > 0, Qi is connected to some processing step
in (Q0 , . . . , Qi−1 ), and (2) all processing steps appear in the same order as in ρ.
We can now define OAuth Sessions. Intuitively, an OAuth session starts when a user expresses her
wish to use some identity at some RP. Each session can only contain one such request. A session ends
when a authorization or log in is complete (which does not necessarily happen in all OAuth Sessions).
Definition 50 (Start and End Processing Steps for OAuth). We write startsOA(Q, b, r, i) iff in the
processing step Q the browser b triggers the script script_rp_index which selects some domain of i
(in Line 6 of Algorithm 11) and instructs the browser b to send a message to r in Line 16.
We write endsOA(Q, b, r, i,t) iff the RP r in the processing step Q receives an HTTPS response with a
body of the form hhprotected_resource,ti, hclient_id, ci, huser, uii for some terms c and u from
i and emits an event in Line 48 of Algorithm 10 that is addressed to b.
w
Definition 51 (OAuth Sessions). Let OWS be an OAuth web system with web attackers and ρ be a
w
run of OWS . An OAuth Session in ρ by a browser b with an RP r and an IdP i is a infinite session
(Q0 , Q1 , . . .) or a finite session (Q0 , . . . , Qn ) in ρ such that startsOA(Q0 , b, r, i), but there is no j > 0,
i′ such that startsOA(Q j , b, r, i′ ). If there are j > 0, t such that endsOA(Q j , b, r, i,t), then the OAuth
Session is finite and n = j.
We write OASessions(ρ, b, r, i) for the set of all OAuth Sessions in ρ by b with the RP r and the IdP i.
77
We now introduce a notation to associate an OAuth Session with the identity that the browser selected
during that session. This models the user intention to log in/authorize using a specific identity. Note that
this expression of intent can take place in two places, either during the first step of an OAuth Session (in
the resource owner password credentials mode) or at a later time when the user logs in at the IdP (in the
implicit mode and the authorization code mode).
Definition 52 (Selected Identity in an OAuth Session). Given a run ρ of an an OAuth web system with
a web attacker, a browser b, an RP r, some IdP i, and an OAuth Session o ∈ OASessions(ρ, b, r, i) we
write selectednia (o, b, r, hu, gi) iff b in (the first processing step of) o selected id ≡ hu, gi in Line 4 of
Algorithm 11 and selected interactive ≡ ⊥ in Line 7.
We write selectedia (o, b, r, hu, gi) iff b in (the first processing step of) o selected interactive ≡ ⊤ in
Line 7 and there is some Q′ in o such that b triggers the script script_idp_form in Q′ and selects hu, gi in
Line 4 of Algorithm 14 and sends a message out to i.
Session Integrity Property for Authorization. This security property captures that (a) an RP should
only be authorized to access some resources when the user actually expressed the wish to start an OAuth
flow before, and (b) if a user expressed the wish to start an OAuth flow using some honest identity
provider and a specific identity, then the OAuth flow is never completed with a different identity.
w
Definition 53 (Session Integrity for Authorization). Let OWS be an OAuth web system with web at-
w w
tackers. We say that OWS is secure w.r.t. session integrity for authorization iff for every run ρ of OWS ,
every processing step Q in ρ, every browser b that is honest in Q, every r ∈ RP that is honest in Q, every
i ∈ IDP, every identity hu, gi, some protected resource t, the following holds true: If endsOA(Q, b, r, i,t),
then
(a) there is an OAuth Session o ∈ OASessions(ρ, b, r, i), and
(b) if i is honest in Q then Q is in o and we have that
selectedia (o, b, r, hu, gi) ⇐⇒ t ≡ resourceOf(i, r, hu, gi)
or
selectednia (o, b, r, hu, gi) ⇐⇒ t ≡ resourceOf(i, r′ , hu, gi)
for some r′ ∈ {r, ⊥}.
Session Integrity Property for Authentication. This security property captures that (a) a user should
only be logged in when the user actually expressed the wish to start an OAuth flow before, and (b) if
a user expressed the wish to start an OAuth flow using some honest identity provider and a specific
identity, then user is not logged in under a different identity.
w
Definition 54 (Session Integrity for Authentication). Let OWS be an OAuth web system with web
w
attackers. We say that OWS is secure w.r.t. session integrity for authentication iff for every run ρ of
OWS w , every processing step Qlogin in ρ, every browser b that is honest in Qlogin , every r ∈ RP that is
honest in Qlogin , every i ∈ IDP, every identity hu, gi, the following holds true: If in Qlogin a service token
of the form hn, hhu′ , g′ i, mii for a domain m ∈ dom(i) and some n, u′ , g′ is created in r (in Line 43 of
Algorithm 10) and n is sent to the browser b, then
(a) there is an OAuth Session o ∈ OASessions(ρ, b, r, i), and
(b) if i is honest in Qlogin then Qlogin is in o and we have that
selectedia (o, b, r, hu, gi) ∨ selected nia (o, b, r, hu, gi) ⇐⇒ hu, gi ≡ hu′ , g′ i .
78
I. Proof of Theorem 1
Before we present the proof for Theorem 1, we first provide a high-level proof outline. We then show
some general properties of OAuth web systems with a network attacker. Afterwards, we first prove the
authentication property and then the authorization property.
n
I.2. Properties of OWS
n
Let OWS = (W , S , script, E 0 ) be an OAuth web system with a network attacker. Let ρ be a run of
OWS n . We write sx = (Sx , E x , N x ) for the states in ρ.
79
Definition 55. We say that a term t is derivably contained in (a term) t ′ for (a set of DY processes) P (in
a processing step si → si+1 of a run ρ = (s0 , s1 , . . .)) if t is derivable from t ′ with the knowledge available
to P, i.e.,
[
t ∈ d0/ ({t ′ } ∪ Si+1 (p))
p∈P
Definition 56. We say that a set of processes P leaks a term t (in a processing step si → si+1 ) to a set of
processes P′ if there exists a message m that is emitted (in si → si+1 ) by some p ∈ P and t is derivably
contained in m for P′ in the processing step si → si+1 . If we omit P′ , we define P′ := W \ P. If P is a set
with a single element, we omit the set notation.
Definition 57. We say that an DY process p created a message m (at some point) in a run if m is deriv-
ably contained in a message emitted by p in some processing step and if there is no earlier processing
step where m is derivably contained in a message emitted by some DY process p′ .
Definition 58. We say that a browser b accepted a message (as a response to some request) if the brow-
ser decrypted the message (if it was an HTTPS message) and called the function PROCESSRESPONSE,
passing the message and the request (see Algorithm 8).
Definition 59. We say that an atomic DY process p knows a term t in some state s = (S, E, N) of a run
if it can derive the term from its knowledge, i.e., t ∈ d0/ (S(p)).
Definition 60. We say that a script initiated a request r if a browser triggered the script (in Line 10
of Algorithm 7) and the first component of the command output of the script relation is either HREF,
IFRAME, FORM, or XMLHTTPREQUEST such that the browser issues the request r in the same step as a
result.
The following lemma captures properties of RP when it uses HTTPS. For example, the lemma says
that other parties cannot decrypt messages encrypted by RP.
Lemma 1 (RP messages are protected by HTTPS). If in the processing step si → si+1 of a run ρ of
OWS n an honest relying party r (I) emits an HTTPS request of the form
2. If there is a processing step s j → s j+1 where the RP r leaks k to W \ {u, r} there is a processing
step sh → sh+1 with h < j where u leaks the symmetric key k to W \ {u, r} or r is corrupted in s j .
3. The value of the host header in req is the domain that is assigned the public key pub(k′ ) in RP’s
keymapping s0 .keyMapping (in its initial state).
80
P ROOF. (1) follows immediately from the condition. If k′ is initially only known to u and u never leaks
k′ , i.e., even with the knowledge of all nonces (except for those of u), k′ can never be derived from any
network output of u, k′ cannot be known to any other party. Thus, nobody except for u can derive req
from m.
(2) We assume that r leaks k to W \ {u, r} in the processing step s j → s j+1 without u prior leaking
the key k to anyone except for u and r and that the RP is not fully corrupted in s j , and lead this to a
contradiction.
The RP is honest in si . From the definition of the RP, we see that the key k is always a fresh nonce
that is not used anywhere else. Further, the key is stored in pendingRequests (ν4 in Lines 56f. of
Algorithm 10). The information from pendingRequests is not extracted or used anywhere else, except
when handling the received messages, where the key is only checked against and used to decrypt the
message (Lines 7ff. of Algorithm 10). Hence, r does not leak k to any other party in s j (except for u and
r). This proves (2).
(3) Per the definition of RPs (Algorithm 10), a host header is always contained in HTTP requests by
RPs. From Line 57 of Algorithm 10 we can see that the encryption key for the request req was chosen
using the host header of the message. It is chosen from the keyMapping in RP’s state, which is never
changed during ρ. This proves (3).
(4) An HTTPS response m′ that is accepted by r as a response to m has to be encrypted with k. The
nonce k is stored by the RP in the pendingRequests state information (see Line 56 of Algorithm 10). The
RP only stores freshly chosen nonces there (i.e., the nonces are not used twice, or for other purposes than
sending one specific request). The information cannot be altered afterwards (only deleted) and cannot
be read except when the RP checks incoming messages. The nonce k is only known to u (which did not
leak it to any other party prior to s j ) and r (which did not leak it either, as u did not leak it and r is honest,
see (2)). This proves (4).
On a high level, the following lemma shows that the contents in the list of pending HTTP requests are
immutable.
Lemma 2 (Pending DNS messages become pending requests). Let r be some honest relying party in
OWS n , ν ∈ N , l > 0 such that (Sl , E l , N l ) is a state in ρ, and let ref ∈ TN , req ∈ HTTPRequests such
that Sl (r).pendingDNS ≡ Sl−1 (r).pendingDNS +hi hν, href , reqii. Then we have that ∀l ′ : if there exist
′
ref ′ , req′ , x, y ∈ TN with req.nonce ≡ req′ .nonce and href ′ , req′ , x, yi ∈hi Sl (r).pendingRequests then
req ≡ req′ ∧ ref ≡ ref ′ .
P ROOF. We first note that Algorithm 10 (of relying parties) modifies the subterm pendingDNS of the
RP’s state only in such a way that entries are appended to or removed from this subterm, but never
modified. Entries are appended in Lines 23, 69, 131, 153, and 168. At all these places in the algorithm,
an HTTP message term, say req, having a fresh (HTTP) nonce, is appended (together with some term
ref ) to the subterm pendingDNS. (A processing step executing one of these parts of the algorithm
results in the state (Sl , E l , N l ) of ρ.) Entries are only removed in Line 58. In this part of the algorithm,
a sequence href ′′ , req′′ , x, yi with x, y ∈ TN and req′′ ≡ req and ref ′′ ≡ ref (which could not have been
altered in any processing step) are appended to the subterm pendingRequests of RP’s state (in Line 56).
Besides Line 12, where some entry is removed from this subterm, there is no other part of the algorithm
′ ′ ′
that alters pendingRequests in any way. Hence, there we cannot have any state (Sl , E l , N l ) of ρ where
we have an request in pendingRequests with the same (HTTP) nonce but a different req′ or a different
ref ′ .
Lemma 3 (RPs never send requests to themselves). An honest RP never sends an HTTP request to
any RP (including itself), and only sends HTTPS requests to RPs that the receiving RP cannot decrypt.
81
P ROOF. Honest RPs send HTTP requests only in Lines 22, 68, 130, 152, and 167. In all of these cases,
they send the HTTPS request to an endpoint configured in the state (in idps). With Definition 42, it
follows that the domains to which these requests are sent, are never a domain of an RP. All requests are
sent over HTTPS, and the “correct” encryption keys (as stored in keyMapping) are used (i.e., even if the
attacker changes the DNS response such that an HTTPS request is sent to an RP, it cannot be decrypted
by the RP).
script_rp_index. If this script was loaded and has access to s, it must have been loaded from origin
hd, Si for a domain d of some trusted relying party, say t (∈ R). If script_rp_index selects the
secret s in Line 13 of Algorithm 11, we know that it must have selected the id u in Line 4. We
therefore know that in Line 14, the browser b is instructed to send (using HTTPS) hu, si to the path
/passwordLogin at d. If b sends such a request, t is the only party able to decrypt this request
(see the general security properties in [15]). This message is then processed by t according to
Lines 139ff. There, username and password are forwarded to some IdP, say i′ , using an HTTPS
POST request. More precisely, this request is sent to the domain of the token endpoint URL
contained in the IdP registration record for the domain contained in u. From Definitions 41 and 42
and the fact that this part of the state (of relying parties) is never changed, we can see that the
request is sent to a domain of i, and therefore i′ = i. (The attacker can also not modify or read this
request, see Lemma 1.) The body of the HTTPS POST request sent to i is of the following form:
Such a request can processed by IdP only in Lines 84ff. of Algorithm 13. There, IdP checks s and
discards it. Therefore, s does not leak from i, t, or b to the attacker (or any other party).
82
script_idp_form. If this script was loaded and has access to s, it must have been loaded from origin
hd, Si for a domain d of i. This script sends s to d in an HTTPS POST request. If b sends such a
request, i is the only party able to decrypt this request (see the general security properties in [15]).
This message is then processed by i according to Lines 15ff. of Algorithm 13. There, the IdP i
checks s and discards it. Therefore, s does not leak from i or b to the attacker (or any other party).
Lemma 5 (Attacker does not learn authorization codes). There exists no l ≤ j, (Sl , E l , N l ) being a
state in ρ, v ∈ N , y ∈ TN such that v ∈ d0/ (Sl (attacker)) and hv, hclientIDOfRP(r, i), y, uii ∈hi Sl (i).codes.
P ROOF. Sl (i).codes is initially empty and appended to only in Line 38 of Algorithm 13 (where an
authorization code is created). From Line 15ff. it is easy to see that the request which triggers the
creation of the authorization code must carry a valid password for the specific identity in the request
body. With Lemma 4, we can see that such a request can not come from the attacker, as the attacker
does not know the password needed in the request. It can also not originate from an IdP, as IdPs do not
send requests. Further, the request can not originate from any corrupted party or an attacker-controlled
origin in the honest browser (as otherwise there would be a flow where the attacker would learn the
password by sending it to himself, which can be ruled out by Lemma 4). It is also impossible that the
request originated from any non-attacker controlled origin in the honest browser: Such a request could be
caused by either a Location redirect or a script. (We will refer to the following as *.) A Location redirect
must have been issued by an honest party (otherwise, the attacker would have learned the password by
the time he issued the response, see Lemma 4). There are two occasions where honest parties issue
Location redirect headers:
IdP in Lines 41/48 of Algorithm 13 In this case, an HTTP status code of 303 is sent. While this
causes the browser to do a new request, the new request has an empty body in any case.36
RP in Line 104 of Algorithm 10 In this case, a 307 redirect could be issued, causing the browser
to preserve the request body. We therefore have to check what could have caused the brow-
ser to issue a request that caused this Location redirect response, and what body could be con-
tained in such a request. For clarity, we call the request causing the redirection m. It is clear
that m cannot come from the attacker (as it contains the password). It must therefore come
from an honest browser. If it was caused by a redirect in the honest browser, (*) applies recur-
sively. Otherwise, there are three scripts that could send such a request to RP: script_rp_index,
script_rp_implicit, and script_idp_form. Of these, only script_rp_index causes a request for the
path /startInteractiveLogin (which triggers the redirection in Line 104 of Algorithm 10),
which, however, does not contain any secret.
A Location redirect can therefore be ruled out as the cause of the request. There are three scripts that
could send such a request: script_rp_index, script_rp_implicit, and script_idp_form. The first two,
script_rp_index, script_rp_implicit, do not send requests to any IdP (instead, they only send requests to
the RP that sent the scripts to the browser, IdP does not send these scripts to the browser). The latter
script, script_idp_form, can send the request. In this (last remaining) case, the IdP responds with a
Location redirect header in the response, which, among others, carries a URL containing the critical
value v (in Line 41). In this case, the browser receives the response, and immediately triggers a new
36 Note that at this point it is important that a 303 redirect is performed, not a 307 redirect. See Line 29 of Algorithm 8 for
details.
83
request to the redirection URL. This URL was composed by the IdP using the list of valid redirection
URIs from Sl (i).clients, a part of the state of i that is not changed during any run. Definition 43
defines how Sl (i).clients is initialized: For the client id c := clientIDOfRP(r, i), all redirection URLs
carry hosts (domains) of r, have the protocol S (HTTPS), and contain a query parameter component
identifying the IdP i. In the checks in Lines 22ff., it is ensured that in any case, this restriction on
domain and protocol applies to the resulting redirection URI (called redirecturi in the algorithm) as well.
Therefore, the browser’s GET request which is triggered by the Location header and contains the value
v is sent to r over HTTPS.
The RP r can process such a GET request only in Lines 74 and 106 of Algorithm 10. It is clear, that
in Line 74, the value v does not leak to the attacker: An honest script is loaded into the browser, which
does not use v in any form. If this script causes a request to the attacker (or causes a request which would
be redirected to the attacker), the request does not contain v. In particular, v cannot be contained in the
Referer header, because this is prevented by the Referrer Policy.
In Lines 106ff., v is forwarded to the IdP for checking its validity and retrieving the access token
(there is also code for retrieving the access code from the implicit flow in this part of the code, which is
not of interest here). When sending the authorization code, it is critical to ensure that v is forwarded to
an honest IdP (in particular, i), and not to the attacker. This is ensured by checking the redirection URL
parameters, which, as mentioned above, contain a hint for the IdP in use, in this case i. In Line 110 it is
checked that the IdP, to which v is eventually sent, is i.
Therefore, we know that v is sent via POST to the honest IdP i. There, it can only be processed
in Lines 52ff. Here, it is easy to see that the value v (called body[code] in the algorithm) is checked.
However, the value is never sent out to any other party and therefore does not leak.
We have shown that the value v cannot be known to the attacker, which proves Lemma 5.
Lemma 6 (Attacker does not learn access tokens). There exists no l ≤ j, (Sl , E l , N l ) being a state in
ρ, v ∈ N , such that v ∈ d0/ (Sl (attacker)) and hv, clientIDOfRP(r, i), ui ∈hi Sl (i).atokens.
P ROOF. Initially, we have S0 (i).atokens ≡ hi. Sl (i).atokens is appended to only in Lines 44, 81, 90,
and 97 (where in each an access token is issued) of Algorithm 13 and not altered in any other way.
In Line 97, a term of the form h∗, ∗, ⊥i is appended, which is not of the form hv, clientIDOfRP(r, i), ui.
In what follows, we will distinguish between the lines of Algorithm 13 were hv, clientIDOfRP(r, i), ui is
created:
Line 44. It is easy to see, that i must have received an HTTPS POST request containing an Origin
header with one of its HTTPS origins and containing (in its body) a dictionary with the entries
husername, ui, hpassword, secretOfID(u)i, and hclient_id, clientIDOfRP(r, i)i. (Note that in
this case, clientIDOfRP(r, i) 6= ⊥, and therefore, r 6= ⊥.) From Lemma 4 it follows that such
a request cannot be assembled by the attacker. Also, neither an IdP nor an RP sends such a
request. Hence, this request must have be sent from a browser. In the browser, only the scripts
script_idp_form and the attacker script Ratt can instruct the browser to send such a request.
From Lemma 4 we know that the attacker script cannot access secretOfID(u) (otherwise, there
would be a run ρ′ in which the attacker script would send secretOfID(u) to the attacker instead).
Hence, this request must originate from a command returned by script_idp_form and it must
be created by the browser b (which is ownerOfID(u)). This script only sends such a request to its
own origin, which must be an HTTPS origin (it would not have access to secretOfID(u) otherwise).
The IdP responds with a Location redirect header in the response, which among others, carries a
URL containing the critical value v (in Line 48) in the fragment of the URL. In this case, the
browser receives the response, and immediately triggers a new request to the redirection URL.
84
This URL was composed by the IdP using the list of valid redirection URIs from Sl (i).clients, a
part of the state of i that is not changed during any run. Definition 43 defines how Sl (i).clients
is initialized: For the client id c := clientIDOfRP(r, i), all redirection URLs carry hosts (domains)
of r, have the protocol S (HTTPS), and contain a query parameter component identifying the IdP i.
In the checks in Lines 22ff., it is ensured that in any case, this restriction on domain and protocol
applies to the resulting redirection URI (called redirecturi in the algorithm) as well. Therefore,
the browser’s GET request which is triggered by the Location header and contains the value v in
the fragment, is sent to r over HTTPS.
The RP r can process such a GET request only in Lines 74 and 106 of Algorithm 10. It is clear,
that in Line 74, the value v does not leak to the attacker: The honest script script_rp_index is
loaded into the browser, which does not use v in any form.
In Lines 106ff., RP’s algorithm branches into two different flows: (1) RP takes some value from
the URL parameters (which do not contain v) and sends it to some process. RP defers its response
to the browser and will (later) only send out the response in Lines 42ff. This response, however,
does not contain a script and hence, the browser will not be instructed to create any new messages
from the resulting document. Hence, v does not leak in this case. (2) RP sends an HTTPS response
containing the script script_rp_implicit (and, in the script’s initial state, a domain of i derived from
the redirection URL), which takes v from the URL parameters and instructs the browser to send
an HTTPS POST request containing v and the domain of i to the script’s (secure) origin at path
/receiveTokenFromImplicitGrant. RP processes such a request in Lines 155ff. where it
forwards v to the IdP for checking its validity. Here, it is critical to ensure that v is forwarded
to an honest IdP (in particular, i), and not to the attacker. This is fulfilled since a domain of i is
contained in the request’s body, and, before forwarding, it is checked that v is only forwarded to
this domain.
Therefore, we know that v is sent via GET to the honest IdP i. There, it can only be processed in
Lines 101ff. Here, it is easy to see that the value v is never sent out to any other party and therefore
does not leak.
Line 81. In this case, i must have received an HTTPS POST request carrying a dictionary in its body
containing the entries hgrant_type, authorization_codei and hcode, codei with code ∈ N
′
such that hcode, hclientIDOfRP(r, i), y, uii ∈hi Sl (i).codes for some y ∈ TN and l ′ ≤ l.(Note that,
as above, clientIDOfRP(r, i) 6= ⊥, and therefore, r 6= ⊥.) From Lemma 5 it follows that such a
request can neither be constructed by the attacker nor by a browser instructed by the attacker script
Ratt . In a browser, the remaining honest scripts do not instruct the browser to send such a request.
(Honest) IdPs do not send such requests. Hence, such a request must have been constructed by
an (honest) RP. An RP prepares such a request only in Lines 119ff. (of Algorithm 10) and finally
sends out this request in Line 59 (after a DNS response). With Lemma 2 and Lemma 1 we know
that reference contains a term of the form hcode, idp, ∗, ∗, ∗, ∗i with idp ∈ dom(i) (as the request
was sent encrypted for and to i). When RP receives the response from i, RP processes this response
in Lines 7ff. where RP distinguishes between two cases based on the first subterm in reference.
As we know that this subterm is code, we have that the response is processed only in Lines 15ff.
RP takes a subterm from the response’s body which might contain37 v in Line 16 and prepares an
HTTPS POST request to an URL of i (which is taken from the subterm idps of RP’s state and this
subterm is never altered and initially configured such that the URLs under the dictionary key idp
are actually belonging to i). This HTTPS POST request contains v in the parameter token. This
request is finally sent out this request in Line 59 (after a DNS response) encrypted for and to i.
37 The subterm actually is v.
85
It is now easy to see that i only accepts the request only in Lines 101ff. (of Algorithm 13). There,
the IdP only checks the parameter token against its state and discards it afterwards. Hence, v
does not leak.
Line 90. In this case, i must have received an HTTPS POST request carrying a dictionary in its body
containing the entries hgrant_type, passwordi, husername, ui, and hpassword, secretOfID(u)i.
From Lemma 4 it follows that such a request cannot be constructed by the attacker, dishonest
scripts in browsers, or any other dishonest party. (Honest) IdPs do not construct such a request.
All honest scripts do not instruct a browser to send such a request. Hence, the request must
have been constructed by an honest RP. An RP prepares such a request only in Lines 145ff. (of
Algorithm 10) and finally sends out this request in Line 59 (after a DNS response). With Lemma 2
and Lemma 1 we know that reference contains a term of the form hpassword, idp, ∗, ∗, ∗, ∗i with
idp ∈ dom(i) (as the request was sent encrypted for and to i). When RP receives the response from
i, RP processes this response in Lines 7ff. where RP distinguishes between two cases based on
the first subterm in reference. As we know that this subterm is code, we have that the response is
processed only in Lines 15ff. RP takes a subterm from the response’s body which might contain38
v in Line 16 and prepares an HTTPS POST request to an URL of i (which is taken from the
subterm idps of RP’s state and this subterm is never altered and initially configured such that
the URLs under the dictionary key idp are actually belonging to i). This HTTPS POST request
contains v in the parameter token. This request is finally sent out this request in Line 59 (after a
DNS response) encrypted for and to i. It is now easy to see that i only accepts the request only in
Lines 101ff. (of Algorithm 13). There, the IdP only checks the parameter token against its state
and discards it afterwards. Hence, v does not leak.
We have shown that the value v cannot be known to the attacker, which proves Lemma 6.
P ROOF. The service token hn, hu, gii can only be created and added to the state S j (r).serviceTokens
in Line 42 of Algorithm 10. To get to this point in the algorithm, in Line 27, it is checked that reference
is a tupel of the form hintrospect, mode, g, a′ , f ′ , n′ , k′ i. This is taken from the pending requests, where
the value is transferred to from the pending DNS subterm (see Lemma 2). Such a term (starting with
introspect) is added to the pendingDNS subterm only in Lines 23 and 168. We can now do a case
distinction between these two possibilities to identify the request m′ to which the response containing
the service token will be sent.
Subterm was added in Line 23. In this case, in Line 15, an entry of the form hmode, g, a′ , f ′ , n′ , k′ i
must have existed as a reference in the pending HTTP requests, where mode is either code or
password.39 Such entries are created in the following lines:
Line 131. Here, a request m′ must have been received which contained a valid authorization code
for the identity u at the IdP i.40 The attacker cannot know such an authorization code (see
Lemma 5). The RP r does not send requests to itself or to other RPs (see Lemma 3), and no
IdPs send requests. Therefore, m′ must have originated from an honest browser.
38 The subterm actually is v.
39 If mode was client_credentials, no service token is created.
40 Otherwise, the IdP would not have returned an access token for the identity u. As g = idp is the value stored in the
reference, it is also clear that the authorization code was, in fact, sent to i for retrieving the access token, and not to the attacker
or another identity provider. Also, the request to i was sent over HTTPS, and therefore, Lemma 1 applies.
86
Line 153. In this case, a request m′ was received which contained a valid username and password
combination for u at i. (As above, we know that i was used to verify that information as g is
a domain of i, and idp = g. ) Only the honest browser b and some relying parties know this
password (see Lemma 4), but the RPs would not send such a request. The request m′ was
therefore sent from the browser b.
Subterm was added in Line 168. If the subterm hintrospect, mode, g, a′ , f ′ , n′ , k′ i was added in
this line, the request causing this (m′ ) must have carried a valid access token for the identity u at
i. (As above, the access token was sent to i for validation.) The attacker does not know such an
access token (see Lemma 6), and other RPs or IdPs cannot send m′ . Therefore, an honest browser
must have sent m′ .
We therefore have that in all cases, m′ was sent by an honest browser. Further, m′ must have been an
HTTPS request (by the definition of RPs). If the request was sent as the result of an XMLHTTPRequest
command from a script, that script must have been loaded from the origin hgr , Si with gr ∈ dom(r). This
is a contradiction (there are no honest scripts that use XMLHTTPRequest). Otherwise, it was a “regular”
request. In this case, the browser tries to load the service token as a document (which will fail). In
particular, the service token hn, hu, gii never leaks to the attacker.
We therefore know that the attacker cannot know the service token, which is a contradiction to the
assumption.
P ROOF. Following the definition of the initial states of all atomic processes (in particular Definition 42),
initially, secretOfRP(r, i) is only known to r.
The secret is being used and sent out in an HTTPS message in Lines 61ff. of Algorithm 10 The
message is being sent to the token endpoint configured for i, which, according to Definition 41, bears a
host name belonging to i. With the definition of sslkeys in Definition 42 and Lemma 1 it can be seen that
this outgoing HTTP POST request can therefore only be read by the intended receiver, i.
In i, the message cannot be processed in the authentication endpoint, Lines 15 to 51 of Algorithm 13,
since it does not carry an Origin header. It can be processed in Lines 52 to 100. It is easy to see that
the secret in the message is not used in any outgoing message, neither stored in the IdP’s data structures.
The message not be processed in Line 101ff., since it is a POST request.
The same applies when the client sends the password in Line 123ff. or Line 146ff. of Algorithm 10.
Therefore, the secret secretOfRP(r, i) cannot be known to the attacker.
87
Lemma 9. Assumption 2 is a contradiction.
P ROOF. At the beginning of each run, the attacker cannot know n (as defined in the initial states). Only
′ ′ ′
the IdP i can send out the protected resource n, in Line 109 of Algorithm 13. In a state (Sl , E l , N l ) in
ρ for some l ′ < j, for i to send out n, an HTTPS request must be received by i which contains, among
′
others, an access token a such that ha, clientIDOfRP(r, i), ui ∈hi Sl (i).atokens. We therefore note that
for the attacker to learn n, it has to know a. We also note that if r requests n at the IdP i, the attacker
cannot read n or a from such messages (see Lemma 1).
We now have to distinguish two cases:
Anonymous Resource, i.e., u ≡ ⊥. In this case, the access token a was chosen by i in Line 97 of
Algorithm 13. There, a is sent out in response to a request that must have contained the client
credentials for r, where the client secret cannot be ⊥ (see Line 64. With Lemma 8 we see that the
attacker cannot send such a request, and therefore, cannot learn a. This implies that the attacker
cannot send the request to learn n from i.
User Resource, i.e., u 6≡ ⊥. In this Case, Lemma 6 shows that it is not possible for the attacker to send
a request to learn n.
With this, we have shown that the attacker cannot learn n, and therefore, Assumption 2 is a contradic-
tion.
Lemma 10 (Third parties do not learn state). Let ρ be a run of an OAuth web system with web at-
w
tackers OWS , (S j , E j , N j ) be a state of ρ, r ∈ RP be an RP that is honest in S j , i ∈ IDP be an IdP that is
honest in S j , b be a browser that is honest in S j .
Then there exists no l ≤ j, with (Sl , E l , N l ) being a state in ρ, a nonce loginSessionId ∈
N , a nonce state ∈ N , a domain h ∈ dom(r) of r, terms x, y, x′ , y′ , z ∈ TN , cookie c :=
hloginSessionId, hloginSessionId, x′ , y′ , zii, an atomic DY process p ∈ W \ {b, i, r} such that state ∈
d0/ (Sl (p)), hloginSessionId, hg, state, x, yii ∈hi Sl (r).loginSessions and hh, ci ∈hi Sl (b).cookies.
P ROOF. To prove Lemma 10, we track where the login session identified by loginSessionId is created
and used.
We have that hh, ci ∈hi Sl (b).cookies. Login sessions are only created in Line 100 of Algorithm 10
(and never altered afterwards). After the session identifier loginSessionId was chosen, its value is sent
over the network to the party that requested the login. We have that for loginSessionId, this party must
be b because only r can set the cookie c for the domain h in the state of b41 and Line 100 of Algorithm 10
is actually the only place where r does so.
88
Since b is honest, b follows the location redirect contained in the response sent by r. This location
redirect contains the state (as a URL parameter). The redirect points to some domain of i.42 The browser
therefore sends (among others) state to i. Of all the endpoints at i where the request can be received,
the authorization endpoint is the only endpoint where state could potentially leak to another party. (For
all other endpoints, the value is dropped.) If the request is received at the authorization endpoint, state
is only sent back to b in the initial scriptstate of script_idp_form. In this case, the script sends state
back to i in a POST request to the authorization endpoint. Note that in the steps outlined here, the value
client_id = clientIDOfRP(r, i) is transferred alongside with state (and not altered in-between). Now,
after receiving state and client_id in a POST request at the authorization endpoint, i looks up some
redirection URI for client_id, which, by Definition 43, is some URI at a domain of r. The value state is
appended to this URI (either as a parameter or in the fragment). The redirection to the redirection URI
is then sent to the browser b. Therefore, b now sends a GET request to r.
If state is contained in the parameter, then state is immediately sent to r where it is compared to the
stored login session records but neither stored nor sent out again. In each case, a script is sent back to b.
The scripts that r can send out are script_rp_index and script_rp_implicit, none of which cause requests
that contain state. Also, since both scripts are always delivered with a restrictive Referrer Policy header,
any requests that are caused by these scripts (e.g., the start of a new login flow) do not contain state in
the referer header.43
If state is contained in the fragment, then state is not immediately sent to r, but instead, a request
without state is sent to r. Since this is a GET request, r either answers with an empty response
(Lines 44ff. of Algorithm 10), a response containing script_rp_index (Lines 74ff.), or a response con-
taining script_rp_implicit (Line 135). In case of the empty response, state is not used anymore by the
browser. In case of script_rp_index, the fragment is not used. (As above, there is no other way in which
state can be sent out, also because the fragment part of an URL is stripped in the referer header.) In the
case of script_rp_implicit being loaded into the browser, the script sends state in the body of an HTTPS
request to r (using the path /receiveTokenFromImplicitGrant). When r receives this request, it
does not send out state to any party (see Lines 155ff. of Algorithm 10).
This shows that state cannot be known to any party except for b, i, and r.
Definition 61. Let e1 = ha1 , f1 , m1 i and e2 = ha2 , f2 , m2 i be events with m1 being a DNS request and
m2 being a DNS response or m1 being an HTTP(S) request and m2 being an HTTP(S) response. We
say that the events correspond to each other if m1 and m2 use the same DNS/HTTP(S) message nonce,
a1 = f2 and a2 = f1 , and (for HTTP(S) messages) either both m1 and m2 are encrypted or both are not
encrypted.
Given a run ρ, and two events e1 and e2 where e1 is emitted in a processing step Q1 in ρ before e2 is
emitted in a processing step Q2 in ρ, we write e1 e2 if e1 corresponds to e2 and we write e1 99K e2 if
Q1 is connected to Q2 .
resp
Lemma 11. Given a run ρ, an RP r, and a browser b, if r, in the run ρ, emits an event, say eauth , in
Line 48 of Algorithm 10 that is addressed to b, and b and r are not corrupted at this point in the run, then
all of the following statements hold true:
89
req resp
dauth dauth 99K ereq req
auth 99K dcred
resp
dcred 99K ereq
cred eresp req
cred 99K dintr
resp
dintr 99K ereq
intr eresp resp
intr 99K eauth (15)
req req resp req resp req resp req resp resp
eauth 99K dtokn dtokn 99K etokn etokn 99K dintr dintr 99K eintr eintr 99K eauth (16)
req req resp req resp resp
eauth 99K dintr dintr 99K eintr eintr 99K eauth (17)
Figure 15. Events as described in Lemma 11. Here, e·· denotes events containing HTTP(S) messages, d·· denotes
events containing DNS messages. (15) applies to the resource owner password credentials mode, (16) applies to
the authorization code mode, and (17) applies to the implicit mode.
90
with w ∈ {password, code}.44
Now, as above, we can check where reference′ was created as an entry in pendingDNS. This can only
happen in Line 153 (w ≡ password) and 131 (w ≡ code). In both cases, an incoming HTTPS request
resp
from aauth , i.e., from b, must have been received. This shows the existance and mutual relations of all
events depicted in (16).
req resp
For (15), it is easy to see (as above) that dauth and dauth exist and have the mutual relations as shown.
req
(b) As already shown above, in all cases, eauth was sent by b to r.
resp req
(c) We have that eintr was received from i. Therefore, eintr must have been sent to i. Therefore, r
req
requested the IP address of some domain of i in dintr . This DNS request was created for the domain
of a token endpoint which was looked up in an IdP registration record stored under the key idp. From
Definitions 42 and 41 it follows that idp is a domain of i.
As above, we now have to distinguish where the value reference is created such that the first part is
introspect. This can happen in Lines 23 and 168. We examine these cases separately.
• From (a) above we have that reference′ (which contains idp) was created as an entry in
pendingDNS in Line 153 or 131.
In the case that reference′ was created in Line 153 we have that the HTTPS request ereq auth (which
was sent by b as shown above) must have been received by r and that this request was a POST
request for the path /passwordLogin, with a message body body such that π2 (π1 (body)) ≡ idp,
and that contains an origin header for some domain of r. Such a request can only be caused by
script_rp_index loaded into b from some domain of r. Hence, this script selected the domain idp
in Line 6 of Algorithm 11 and we have that startsOA(Qauth , b, r, i) where Qauth is the processing
req
step that emitted dauth .
In the case that reference′ was created in Line 131 we have that (*) the HTTPS request ereq
auth must
have been received by r and that in this request there is a cookie loginSessionId with a value,
say, l such that in the state of r (when receiving the request) in the subterm loginSessions under
the key l there is a sequence with the first element being idp.
Since we have that ereq auth was sent by b (as shown above) we have that b must have received an
HTTP(S) response from r which contains a Set-Cookie header for the cookie loginSessionId
with the value l.45 We denote the event of this message as eresp strt . This message must have been
created in Line 104 and, in the same processing step, an entry in loginSessions under the key
l as described above is created in Line 100. (There are no other places where login session en-
req
tries are created.) We have that the corresponding request estrt is a POST request with an origin
header for some domain of r, the path /startInteractiveLogin, and that the body must be
idp. As above, such a request can only be caused by script_rp_index loaded into b from some
domain of r. Hence, this script selected the domain idp in Line 6 of Algorithm 11, which output
req
an HREF-command to the browser to send estrt to r. This request is preceded by a pair of corre-
req resp
sponding DNS messages dstrt and dstrt as defined in the browser relation. We therefore have that
req
startsOA(Qstrt , b, r, i) where Qstrt is the processing step that emitted dstrt .
• In the case that reference was created in Line 168 we have the same situation as in (*) and the
proof continues exactly as in (*).
w w
Lemma 12. Let OWS be an OAuth web system with web attackers, then OWS is secure w.r.t. session
integrity for authorization.
44 Note that w cannot be client_credentials because in this case, mode′ in reference would have been
client_credentials, which contradicts that in the processing step Q, an event was emitted.
45 Note that this cookie cannot be set by any party except for r and there are no scripts sent out by r that set cookies.
91
w
P ROOF. We have to show that for all OAuth web system with web attackers OWS , for every run ρ of
OWS w , every processing step Qends in ρ, every browser b that is honest in Qends , every r ∈ RP that is
honest in Qends , every i ∈ IDP, every identity hu, gi, some protected resource t, the following holds true:
If endsOA(Qends , b, r, i,t), then
(a) there is an OAuth Session o ∈ OASessions(ρ, b, r, i), and
or
selectednia (o, b, r, hu, gi) ⇐⇒ t ≡ resourceOf(i, r′ , hu, gi)
for some r′ ∈ {r, ⊥}.
We can see that Lemma 11 applies, since endsOA(Qends , b, r, i,t) where Qends is the processing step in
resp resp
which eintr was received by r from i and eauth was emitted to b. With Lemma 11 (c) and Definition 51 it
immediately follows that there is an OAuth Session o ∈ OASessions(ρ, b, r, i).
For part (b), we now show the connection between Qends and o and show that one of the logical
equivalences in (b) hold true. In the following, we therefore have that i is honest.
In Lemma 11 we have already shown the existence of and the relations between the events of one of
the forms shown in Figure 15. For any two events e1 e2 in Figure 15, the processing steps where these
events where emitted are connected (as i and DNS servers are honest).
Authorization Code Mode. We now show that if the events are structured as shown in (16) in Figure 15
req
then there also exist events as shown in (18) in Figure 16. (The event eauth is the same in both figures.)
req req resp
Since we have that eauth exists and was sent by b, the DNS messages dauth and dauth (as shown) follow
immediately. The request ereqauth contains a session cookie containing a session id, say, l. The request also
contains a URI parameter state with some value, say, z.46
With Lemma 10, we can see that the attacker (or any other party except for i, b, and r) cannot instruct
req
the browser to send eauth . Also, r does not instruct the browser to send such a request, and neither does
46 req
From the proof of Lemma 11 we follow that eauth must be an HTTPS request for the path /redirectionEndpoint
containing the parameters code, state, iss, and client_id.
92
any honest script. The request must therefore have been caused by a redirection contained in an event
eresp
aep2 that was sent from i to b (see Line 41 of Algorithm 13). (The redirection must have included the
state parameter in the URI as above.) This requires that an event eresp aep2 was sent from b to i. (Which, as
req resp
above, was preceded by DNS messages daep2 and daep2 .) This event must contain an HTTP(S) POST
request, with an origin header value of some domain of i, and in the body there must be a dictionary with
an entry for the key client_id containing the client id c = clientIDOfRP(r, i), and an entry for the key
state with the value z. (Note that in this case, c 6= ⊥.)
Because of the origin header value, this request can only be caused by the script script_idp_form.
This script extracted c and z from its initial scriptstate, which was a dictionary with the keys as above.47
resp
The initial scriptstate must have been sent by i in an event eaep1 . Such an event can only be sent out in
Line 13 of Algorithm 13.
resp req resp req
The event eaep1 , as above, must have been preceded by connected events daep1 , daep1 , and eaep1 . In
req
eaep1 the message must be an HTTP(S) request which must have two parameters, first, under the key
state, the value z, and second, under the key client_id, the value l. (These parameters are used as
the initial scriptstate for the script script_idp_form above.)
Similar to above, with Lemma 10, we have that the event ereq req
aep1 (and, with that, daep1 ) must have been
caused by a redirect that was sent from r to b. Such a response is only created by r in Line 104 of
Algorithm 10. Since the state value is always chosen freshly, and we have that in this case it is z, the
event containing this redirect is eresp
strt .
It is now easy to see that the sequence of processing steps emitting the events in (18) and (16) is
a session (as in Definition 49), say, o. We already know that startsOA(Qstarts , b, r, i) where Qstarts is
req
the processing step in which dstrt was emitted. There is no other processing step in o in which the
resp
browser b triggers the script script_rp_index. The processing step Qends (in which eauth is emitted) is the
only processing step in which r receives a protected resource from i and emits an event in Line 48 of
Algorithm 10. Therefore, o is an OAuth session, and Qends is in o.
We now show that
selectedia (o, b, r, hu, gi) ⇐⇒ t ≡ resourceOf(i, r, hu, gi) .
Iff selectedia (o, b, r, hu, gi) then we have that b in Qstart selected interactive ≡ ⊤ in Line 7 and there is
some Qselect in o such that b triggers the script script_idp_form in Qselect and selects hu, gi in Line 4 of
Algorithm 14 and sends a message out to i.
req
We therefore have that Qselect is the processing step where daep2 was emitted. (This is the only pro-
cessing step in which the browser triggers the script script_idp_form.) We have that in this step, the
browser selected hu, gi in Line 4 of Algorithm 14. Then, and only then, the HTTPS POST request in
req
eaep2 contained, in the body, the credentials (username and password) for the identity hu, gi. From the
proof of Lemma 11 we see that in eresp req
strt , in the redirection URI, and hence in the URI in eaep1 , the param-
eter response_type must be code. We therefore have that the initial scriptstate of script_idp_form in
resp req
eaep1 contains the entry hresponse_type, codei. Now, in eaep2 , the body also contains the same entry.
req
Therefore, iff i receives eaep2 , then it creates an entry in the subterm codes of its state (in Line 38 of
Algorithm 13) of the form
hcode, hc, redirecturi, hu, giii
(where redirecturi is some URI and code is a freshly chosen nonce).
resp
Then, and only then, eaep2 contains code in the parameter code of the location redirect URI (which is
the URI for the HTTPS request in ereq auth ). RP sends (as shown in the proof of Lemma 11) code to IdP in
req
etokn . This request contains the body hhgrant_type, authorization_codei, hcode, codeii.
47 This initial scriptstate is never changed if the script runs under the origin of an honest IdP, which it does in this case.
93
Then, and only then, IdP processes ereqtokn (in Line 81 of Algorithm 13) and creates an entry in the
subterm atokens of its state of the form
for a freshly chosen nonce atoken (as there exists an entry in the subterm code of the form
resp
hcode, hc, redirecturi, hu, giii). Then and only then, atoken is contained in etokn . Then and only then,
req
r sends atoken to i in eintr . (In this request, atoken is contained in the URI parameter token.)
Iff there is an entry of the form hatoken, hc, hu, giii in the subterm atokens in the state of i and i
receives ereq req
intr (containing atoken as shown) then i processed eintr in Line 101ff. and emitted an event
resp
(eintr ) containing resourceOf(i, r, hu, gi).
Implicit Mode. This case is very similar to the authorization code mode above. We therefore only
describe the differences between the two modes.
req
In this case, with the proof of Lemma 11, we have that eauth is an HTTPS POST request to the
path /receiveTokenFromImplicitGrant with an origin header being some domain of r. Further, as
req
above, eauth contains the state z. This request must have been created in the browser by script_rp_implicit
running under an origin of r. This script retrieves the state value from the fragment of the URI from
req
which the script was loaded. Therefore, there must have been a request, eimpl containing such a fragment
req resp resp
in the URI. This implies the presence of the events dimpl , dimpl , and eimpl .
We can now that Qends is in o and selectedia (o, b, r, hu, gi) ⇐⇒ t ≡ resourceOf(i, r, hu, gi) by ap-
plying the same reasoning as above, with the following differences:
• We can show that the sequence of processing steps emitting the events in (17) in Figure 15 and
(19) in Figure 16 are the OAuth session o and (as above) that Qends is in o.
• Where the parameter response_type was code above, it now is token. The same applies to the
initial scriptstate of script_idp_form.
• Instead of creating code in the processing step that emits eresp aep2 , this step now creates an access
token token (in the same way as the token was created in the authorization code mode in the
resp req resp req resp
processing step that emits etokn ). The steps dtokn , dtokn , etokn , and etokn are skipped.
resp
• The redirection URI contained in eaep2 contains an access token instead of an authorization code,
and the access token and the state value are contained in the fragment instead of in the parameters.
Resource Owner Password Credentials Mode. It is easy to see that the sequence of processing steps
emitting the events in (15) is a session (as in Definition 49), say, o. In this case, startsOA(Qstarts , b, r, i)
req
holds true if Qstarts is the processing step in which dauth was emitted. As above, o is also an OAuth
session, and Qends is in o.
We now show that
selectednia (o, b, r, hu, gi) ⇐⇒ t ≡ resourceOf(i, r′ , hu, gi)
for some r′ ∈ {r, ⊥}. Iff selectednia (o, b, r, hu, gi) then we have that b in Qstart selected id ≡ hu, gi in
Line 4 of Algorithm 11 and selected interactive ≡ ⊥ in Line 7.
94
Then and only then, ereq
auth is an HTTPS POST request for the path /passwordLogin with an origin
header containing some domain of r and with the identity hu, gi and the corresponding password, say p,
req
in the body. Then and only then, the body in ecred is of the form
for a freshly chosen nonce atoken (as there exists an entry in the subterm code of the form
hcode, hc, redirecturi, hu, giii) and for c′ ∈ {clientIDOfRP(r, i), ⊥}. Then and only then, atoken is con-
resp req
tained in ecred . Then and only then, r sends atoken to i in eintr . (In this request, atoken is contained in the
URI parameter token.)
Iff there is an entry of the form hatoken, hc′ , hu, giii in the subterm atokens in the state of i and i
req req
receives eintr (containing atoken as shown) then i processed eintr in Line 101ff. and emitted an event
resp ′
(eintr ) containing resourceOf(i, r, hu, gi) if c 6= ⊥ and containing resourceOf(i, ⊥, hu, gi) otherwise.
w w
Lemma 13. Let OWS be an OAuth web system with web attackers, then OWS is secure w.r.t. session
integrity for authentication.
P ROOF. We have that r sends a service token to b, and thus, endsOA(Qlogin , b, r, it) for some term t.
w
Since OWS is secure w.r.t. session integrity for authorization, we have that (a) holds true. For (b),
we see from Line 101ff. that honest IdPs, at their introspection endpoint, if they send out an HTTPS
response, the body of that response is of the form
hhprotected_resource, resourceOf(i′′ , r′′ , hu′′ , g′′ i)i, hclient_id, c′′ i, huser, hu′′ , g′′ iii
for any hu′′ , g′′ i and some c′′ , i′′ , r′′ . We therefore have that
t ≡ resourceOf(i, r, hu, gi) ⇐⇒ hu, gi ≡ hu′ , g′ i .
w
Since OWS is secure w.r.t. session integrity for authorization, we have that (b) holds true.
95