rfc9700.original.xml | rfc9700.xml | |||
---|---|---|---|---|
<?xml version='1.0' encoding='utf-8'?> | <?xml version='1.0' encoding='UTF-8'?> | |||
<!DOCTYPE rfc [ | <!DOCTYPE rfc [ | |||
<!ENTITY nbsp " "> | <!ENTITY nbsp " "> | |||
<!ENTITY zwsp "​"> | <!ENTITY zwsp "​"> | |||
<!ENTITY nbhy "‑"> | <!ENTITY nbhy "‑"> | |||
<!ENTITY wj "⁠"> | <!ENTITY wj "⁠"> | |||
]> | ]> | |||
<!-- name="GENERATOR" content="github.com/mmarkdown/mmark Mmark Markdown Process | ||||
or - mmark.miek.nl" --> | ||||
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" version="3" ipr="trust200902" do | ||||
cName="draft-ietf-oauth-security-topics-29" submissionType="IETF" category="bcp" | ||||
xml:lang="en" updates="6749, 6750, 6819" indexInclude="true" tocDepth="4"> | ||||
<front> | <rfc xmlns:xi="http://www.w3.org/2001/XInclude" version="3" ipr="trust200902" do | |||
<title abbrev="OAuth 2.0 Security BCP">OAuth 2.0 Security Best Current Practice< | cName="draft-ietf-oauth-security-topics-29" number="9700" consensus="true" submi | |||
/title><seriesInfo value="draft-ietf-oauth-security-topics-29" stream="IETF" sta | ssionType="IETF" category="bcp" xml:lang="en" updates="6749, 6750, 6819" obsolet | |||
tus="bcp" name="Internet-Draft"/> | es="" tocInclude="true" tocDepth="4" symRefs="true" sortRefs="true"> | |||
<author initials="T." surname="Lodderstedt" fullname="Torsten Lodderstedt"><orga | ||||
nization>SPRIND</organization><address><postal><street/> | <front> | |||
</postal><email>torsten@lodderstedt.net</email> | <title abbrev="OAuth 2.0 Security BCP">Best Current Practice for OAuth 2.0 S | |||
</address></author><author initials="J." surname="Bradley" fullname="John Bradle | ecurity</title> | |||
y"><organization>Yubico</organization><address><postal><street/> | <seriesInfo name="RFC" value="9700"/> | |||
</postal><email>ve7jtb@ve7jtb.com</email> | <seriesInfo name="BCP" value="240"/> | |||
</address></author><author initials="A." surname="Labunets" fullname="Andrey Lab | <author initials="T." surname="Lodderstedt" fullname="Torsten Lodderstedt"> | |||
unets"><organization>Independent Researcher</organization><address><postal><stre | <organization>SPRIND</organization> | |||
et/> | <address> | |||
</postal><email>isciurus@gmail.com</email> | <email>torsten@lodderstedt.net</email> | |||
</address></author><author initials="D." surname="Fett" fullname="Daniel Fett">< | </address> | |||
organization>Authlete</organization><address><postal><street/> | </author> | |||
</postal><email>mail@danielfett.de</email> | <author initials="J." surname="Bradley" fullname="John Bradley"> | |||
</address></author><date/> | <organization>Yubico</organization> | |||
<area>Security</area> | <address> | |||
<workgroup>Web Authorization Protocol</workgroup> | <email>ve7jtb@ve7jtb.com</email> | |||
<keyword>security</keyword> | </address> | |||
<keyword>oauth2</keyword> | </author> | |||
<keyword>best current practice</keyword> | <author initials="A." surname="Labunets" fullname="Andrey Labunets"> | |||
<organization>Independent Researcher</organization> | ||||
<address> | ||||
<email>isciurus@gmail.com</email> | ||||
</address> | ||||
</author> | ||||
<author initials="D." surname="Fett" fullname="Daniel Fett"> | ||||
<organization>Authlete</organization> | ||||
<address> | ||||
<email>mail@danielfett.de</email> | ||||
</address> | ||||
</author> | ||||
<date year="2024" month="November"/> | ||||
<area>SEC</area> | ||||
<workgroup>oauth</workgroup> | ||||
<keyword>threat model</keyword> | ||||
<keyword>attacks</keyword> | ||||
<keyword>mitigations</keyword> | ||||
<abstract> | <abstract> | |||
<t>This document describes best current security practice for OAuth 2.0. It upda tes | <t>This document describes best current security practice for OAuth 2.0. It upda tes | |||
and extends the threat model and security advice given in RFC 6749, | and extends the threat model and security advice given in RFCs 6749, 6750, and 6 | |||
RFC 6750, and RFC 6819 to incorporate practical experiences gathered since | 819 to incorporate practical experiences gathered since | |||
OAuth 2.0 was published and covers new threats relevant due to the broader | OAuth 2.0 was published and covers new threats relevant due to the broader | |||
application of OAuth 2.0. Further, it deprecates some modes of operation that ar e | application of OAuth 2.0. Further, it deprecates some modes of operation that ar e | |||
deemed less secure or even insecure.</t> | deemed less secure or even insecure.</t> | |||
</abstract> | </abstract> | |||
<note title="Discussion Venues" removeInRFC="true"> | ||||
<t>Discussion of this document takes place on the | ||||
Web Authorization Protocol Working Group mailing list (oauth@ietf.org), | ||||
which is archived at <eref target="https://mailarchive.ietf.org/arch/browse/ | ||||
oauth/"/>.</t> | ||||
<t>Source for this draft and an issue tracker can be found at | ||||
<eref target="https://github.com/oauthstuff/draft-ietf-oauth-security-topics | ||||
"/>.</t> | ||||
</note> | ||||
</front> | </front> | |||
<middle> | <middle> | |||
<section anchor="Introduction"><name>Introduction</name> | <section anchor="Introduction"><name>Introduction</name> | |||
<t>Since its publication in <xref target="RFC6749"/> and <xref target="RFC6750"/ >, OAuth 2.0 (referred to as simply "OAuth" in the following) has gained massive traction in the market | <t>Since its publication in <xref target="RFC6749"/> and <xref target="RFC6750"/ >, OAuth 2.0 (referred to as simply "OAuth" in this document) has gained massive traction in the market | |||
and became the standard for API protection and the basis for federated | and became the standard for API protection and the basis for federated | |||
login using OpenID Connect <xref target="OpenID.Core"/>. While OAuth is used in a | login using OpenID Connect <xref target="OpenID.Core"/>. While OAuth is used in a | |||
variety of scenarios and different kinds of deployments, the following | variety of scenarios and different kinds of deployments, the following | |||
challenges can be observed:</t> | challenges can be observed:</t> | |||
<ul> | <ul> | |||
<li><t>OAuth implementations are being attacked through known implementation | <li><t>OAuth implementations are being attacked through known implementation | |||
weaknesses and anti-patterns (i.e., well-known patterns that are considered | weaknesses and anti-patterns (i.e., well-known patterns that are considered | |||
insecure). Although most of these threats are discussed in the OAuth 2.0 | insecure). Although most of these threats are discussed in the OAuth 2.0 | |||
Threat Model and Security Considerations <xref target="RFC6819"/>, continued e xploitation | Threat Model and Security Considerations <xref target="RFC6819"/>, continued e xploitation | |||
demonstrates a need for more specific recommendations, easier to implemen t | demonstrates a need for more specific recommendations, easier to implemen t | |||
mitigations, and more defense in depth.</t> | mitigations, and more defense in depth.</t> | |||
</li> | </li> | |||
<li><t>OAuth is being used in environments with higher security requirements tha n | <li><t>OAuth is being used in environments with higher security requirements tha n | |||
considered initially, such as Open Banking, eHealth, eGovernment, and | considered initially, such as open banking, eHealth, eGovernment, and | |||
Electronic Signatures. Those use cases call for stricter guidelines and | electronic signatures. Those use cases call for stricter guidelines and | |||
additional protection.</t> | additional protection.</t> | |||
</li> | </li> | |||
<li><t>OAuth is being used in much more dynamic setups than originally anticipat ed, | <li><t>OAuth is being used in much more dynamic setups than originally anticipat ed, | |||
creating new challenges with respect to security. Those challenges go beyond | creating new challenges with respect to security. Those challenges go beyond | |||
the original scope of <xref target="RFC6749"/>, <xref target="RFC6750"/>, and <xref target="RFC6819"/>.</t> | the original scope of <xref target="RFC6749"/>, <xref target="RFC6750"/>, and <xref target="RFC6819"/>.</t> | |||
<t>OAuth initially assumed static relationships between clients, | <t>OAuth initially assumed static relationships between clients, | |||
authorization servers, and resource servers. The URLs of the servers were | authorization servers, and resource servers. The URLs of the servers were | |||
known to the client at deployment time and built an anchor for the | known to the client at deployment time and built an anchor for the | |||
trust relationships among those parties. The validation of whether the | trust relationships among those parties. The validation of whether the | |||
client is talking to a legitimate server was based on TLS server | client is talking to a legitimate server was based on TLS server | |||
authentication (see <xref target="RFC6819"/>, Section 4.5.4). With the increasin g | authentication (see <xref target="RFC6819" sectionFormat="of" section="4.5.4"/>) . With the increasing | |||
adoption of OAuth, this simple model dissolved and, in several | adoption of OAuth, this simple model dissolved and, in several | |||
scenarios, was replaced by a dynamic establishment of the relationship | scenarios, was replaced by a dynamic establishment of the relationship | |||
between clients on one side and the authorization and resource servers | between clients on one side and the authorization and resource servers | |||
of a particular deployment on the other side. This way, the same | of a particular deployment on the other side. This way, the same | |||
client could be used to access services of different providers (in | client could be used to access services of different providers (in | |||
case of standard APIs, such as e-mail or OpenID Connect) or serve as a | case of standard APIs, such as email or OpenID Connect) or serve as a | |||
front end to a particular tenant in a multi-tenant environment. | front end to a particular tenant in a multi-tenant environment. | |||
Extensions of OAuth, such as the OAuth 2.0 Dynamic Client Registration | Extensions of OAuth, such as the OAuth 2.0 Dynamic Client Registration | |||
Protocol <xref target="RFC7591"/> and OAuth 2.0 Authorization Server Metadata | Protocol <xref target="RFC7591"/> and OAuth 2.0 Authorization Server Metadata | |||
<xref target="RFC8414"/> were developed to support the use of OAuth in | <xref target="RFC8414"/> were developed to support the use of OAuth in | |||
dynamic scenarios.</t> | dynamic scenarios.</t> | |||
</li> | </li> | |||
<li><t>Technology has changed. For example, the way browsers treat fragments whe n | <li><t>Technology has changed. For example, the way browsers treat fragments whe n | |||
redirecting requests has changed, and with it, the implicit grant's | redirecting requests has changed, and with it, the implicit grant's | |||
underlying security model.</t> | underlying security model.</t> | |||
</li> | </li> | |||
</ul> | </ul> | |||
<t>This document provides updated security recommendations to address these | <t>This document provides updated security recommendations to address these | |||
challenges. It introduces new requirements beyond those defined in existing | challenges. It introduces new requirements beyond those defined in existing | |||
specifications such as OAuth 2.0 <xref target="RFC6749"/> and OpenID Connect <xr ef target="OpenID.Core"/> | specifications such as OAuth 2.0 <xref target="RFC6749"/> and OpenID Connect <xr ef target="OpenID.Core"/> | |||
and deprecates some modes of operation that are deemed less secure or even | and deprecates some modes of operation that are deemed less secure or even | |||
insecure. However, this document does not supplant the security advice given in | insecure. However, this document does not supplant the security advice given in | |||
<xref target="RFC6749"/>, <xref target="RFC6750"/>, and <xref target="RFC6819"/> , but complements those documents.</t> | <xref target="RFC6749"/>, <xref target="RFC6750"/>, and <xref target="RFC6819"/> , but complements those documents.</t> | |||
<t>Naturally, not all existing ecosystems and implementations are | <t>Naturally, not all existing ecosystems and implementations are | |||
compatible with the new requirements and following the best practices described | compatible with the new requirements, and following the best practices described | |||
in | in | |||
this document may break interoperability. Nonetheless, it is RECOMMENDED that | this document may break interoperability. Nonetheless, it is <bcp14>RECOMMENDED< | |||
/bcp14> that | ||||
implementers upgrade their implementations and ecosystems as soon as feasible.</ t> | implementers upgrade their implementations and ecosystems as soon as feasible.</ t> | |||
<t>OAuth 2.1, under developement as <xref target="I-D.ietf-oauth-v2-1"/>, will i ncorporate | <t>OAuth 2.1, under development as <xref target="I-D.ietf-oauth-v2-1"/>, will in corporate | |||
security recommendations from this document.</t> | security recommendations from this document.</t> | |||
<section anchor="structure"><name>Structure</name> | <section anchor="structure"><name>Structure</name> | |||
<t>The remainder of this document is organized as follows: The next section | <t>The remainder of this document is organized as follows: <xref target="recomme | |||
summarizes the most important best practices for every OAuth implementor. | ndations"/> | |||
Afterwards, the updated OAuth attacker model is presented. Subsequently, a | summarizes the most important best practices for every OAuth implementer. | |||
<xref target="secmodel"/> presents the updated OAuth attacker model. <xref targe | ||||
t="attacks_and_mitigations"/> is a | ||||
detailed analysis of the threats and implementation issues that can be found in | detailed analysis of the threats and implementation issues that can be found in | |||
the wild today is given along with a discussion of potential countermeasures.</t > | the wild (at the time of writing) along with a discussion of potential counterme asures.</t> | |||
</section> | </section> | |||
<section anchor="conventions-and-terminology"><name>Conventions and Terminology< /name> | <section anchor="conventions-and-terminology"><name>Conventions and Terminology< /name> | |||
<t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL | <t> | |||
NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", | The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", | |||
"MAY", and "OPTIONAL" in this document are to be interpreted as | "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL NOT</bcp14> | |||
described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and | ", | |||
only when, they | "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", | |||
appear in all capitals, as shown here.</t> | "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>", | |||
"<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to | ||||
be | ||||
interpreted as described in BCP 14 <xref target="RFC2119"/> <xref | ||||
target="RFC8174"/> when, and only when, they appear in all capitals, as | ||||
shown here. | ||||
</t> | ||||
<t>This specification uses the terms "access token", "authorization | <t>This specification uses the terms "access token", "authorization | |||
endpoint", "authorization grant", "authorization server", "client", | endpoint", "authorization grant", "authorization server", "client", | |||
"client identifier" (client ID), "protected resource", "refresh | "client identifier" (client ID), "protected resource", "refresh | |||
token", "resource owner", "resource server", and "token endpoint" | token", "resource owner", "resource server", and "token endpoint" | |||
defined by OAuth 2.0 <xref target="RFC6749"/>.</t> | defined by OAuth 2.0 <xref target="RFC6749"/>.</t> | |||
<t>An "open redirector" is an endpoint on a web server that forwards a user’s | <t>An "open redirector" is an endpoint on a web server that forwards a user's | |||
browser to an arbitrary URI obtained from a query parameter.</t> | browser to an arbitrary URI obtained from a query parameter.</t> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="recommendations"><name>Best Practices</name> | <section anchor="recommendations"><name>Best Practices</name> | |||
<t>This section describes the core set of security mechanisms and measures that | <t>This section describes the core set of security mechanisms and measures that | |||
are considered to be best practices at the time of writing. Details | are considered to be best practices at the time of writing. Details | |||
about these security mechanisms and measures (including detailed attack | about these security mechanisms and measures (including detailed attack | |||
descriptions) and requirements for less commonly used options are provided in | descriptions) and requirements for less commonly used options are provided in | |||
<xref target="attacks_and_mitigations"/>.</t> | <xref target="attacks_and_mitigations"/>.</t> | |||
<section anchor="rec_redirect"><name>Protecting Redirect-Based Flows</name> | <section anchor="rec_redirect"><name>Protecting Redirect-Based Flows</name> | |||
<t>When comparing client redirect URIs against pre-registered URIs, authorizatio | ||||
n | <t>When comparing client redirection URIs against pre-registered URIs, authoriza | |||
servers MUST utilize exact string matching except for port numbers in | tion | |||
servers <bcp14>MUST</bcp14> utilize exact string matching except for port number | ||||
s in | ||||
<tt>localhost</tt> redirection URIs of native apps (see <xref target="iuv_counte rmeasures"/>). This | <tt>localhost</tt> redirection URIs of native apps (see <xref target="iuv_counte rmeasures"/>). This | |||
measure contributes to the prevention of leakage of authorization codes and | measure contributes to the prevention of leakage of authorization codes and | |||
access tokens (see <xref target="insufficient_uri_validation"/>). It can also he lp to detect | access tokens (see <xref target="insufficient_uri_validation"/>). It can also he lp to detect | |||
mix-up attacks (see <xref target="mix_up"/>).</t> | mix-up attacks (see <xref target="mix_up"/>).</t> | |||
<t>Clients and authorization servers MUST NOT expose URLs that forward the user' s browser to | <t>Clients and authorization servers <bcp14>MUST NOT</bcp14> expose URLs that fo rward the user's browser to | |||
arbitrary URIs obtained from a query parameter (open redirectors) as | arbitrary URIs obtained from a query parameter (open redirectors) as | |||
described in <xref target="open_redirection"/>. Open redirectors can enable | described in <xref target="open_redirection"/>. Open redirectors can enable | |||
exfiltration of authorization codes and access tokens.</t> | exfiltration of authorization codes and access tokens.</t> | |||
<t>Clients MUST prevent Cross-Site Request Forgery (CSRF). In this | <t>Clients <bcp14>MUST</bcp14> prevent Cross-Site Request Forgery (CSRF). In thi s | |||
context, CSRF refers to requests to the redirection endpoint that do | context, CSRF refers to requests to the redirection endpoint that do | |||
not originate at the authorization server, but a malicious third party | not originate at the authorization server, but at a malicious third party | |||
(see Section 4.4.1.8. of <xref target="RFC6819"/> for details). Clients that hav | (see <xref target="RFC6819" sectionFormat="of" section="4.4.1.8"/> for details). | |||
e | Clients that have | |||
ensured that the authorization server supports Proof Key for Code Exchange (PKCE | ensured that the authorization server supports Proof Key for Code Exchange (PKCE | |||
, <xref target="RFC7636"/>) MAY | ) <xref target="RFC7636"/> <bcp14>MAY</bcp14> | |||
rely on the CSRF protection provided by PKCE. In OpenID Connect flows, | rely on the CSRF protection provided by PKCE. In OpenID Connect flows, | |||
the <tt>nonce</tt> parameter provides CSRF protection. Otherwise, one-time | the <tt>nonce</tt> parameter provides CSRF protection. Otherwise, one-time | |||
use CSRF tokens carried in the <tt>state</tt> parameter that are securely | use CSRF tokens carried in the <tt>state</tt> parameter that are securely | |||
bound to the user agent MUST be used for CSRF protection (see | bound to the user agent <bcp14>MUST</bcp14> be used for CSRF protection (see | |||
<xref target="csrf_countermeasures"/>).</t> | <xref target="csrf_countermeasures"/>).</t> | |||
<t>When an OAuth client can interact with more than one authorization server, a | <t>When an OAuth client can interact with more than one authorization server, a | |||
defense against mix-up attacks (see <xref target="mix_up"/>) is REQUIRED. To thi | defense against mix-up attacks (see <xref target="mix_up"/>) is <bcp14>REQUIRED< | |||
s end, clients | /bcp14>. To this end, clients | |||
SHOULD</t> | <bcp14>SHOULD</bcp14></t> | |||
<ul spacing="compact"> | <ul spacing="compact"> | |||
<li>use the <tt>iss</tt> parameter as a countermeasure according to | <li>use the <tt>iss</tt> parameter as a countermeasure according to | |||
<xref target="RFC9207"/>, or</li> | <xref target="RFC9207"/>, or</li> | |||
<li>use an alternative countermeasure based on an <tt>iss</tt> value in the | <li>use an alternative countermeasure based on an <tt>iss</tt> value in the | |||
authorization response (such as the <tt>iss</tt> Claim in the ID Token in | authorization response (such as the <tt>iss</tt> claim in the ID Token in | |||
<xref target="OpenID.Core"/> or in <xref target="OpenID.JARM"/> responses), proc | <xref target="OpenID.Core"/> or in <xref target="OpenID.JARM"/> responses), proc | |||
essing it as described in | essing that value as described in | |||
<xref target="RFC9207"/>.</li> | <xref target="RFC9207"/>.</li> | |||
</ul> | </ul> | |||
<t>In the absence of these options, clients MAY instead use distinct redirect UR Is | <t>In the absence of these options, clients <bcp14>MAY</bcp14> instead use disti nct redirection URIs | |||
to identify authorization endpoints and token endpoints, as described in | to identify authorization endpoints and token endpoints, as described in | |||
<xref target="mixupcountermeasures"/>.</t> | <xref target="mixupcountermeasures"/>.</t> | |||
<t>An authorization server that redirects a request potentially containing user credentials | <t>An authorization server that redirects a request potentially containing user credentials | |||
MUST avoid forwarding these user credentials accidentally (see | <bcp14>MUST</bcp14> avoid forwarding these user credentials accidentally (see | |||
<xref target="redirect_307"/> for details).</t> | <xref target="redirect_307"/> for details).</t> | |||
<section anchor="ac"><name>Authorization Code Grant</name> | <section anchor="ac"><name>Authorization Code Grant</name> | |||
<t>Clients MUST prevent authorization code | <t>Clients <bcp14>MUST</bcp14> prevent authorization code | |||
injection attacks (see <xref target="code_injection"/>) and misuse of authorizat ion codes using one of the following options:</t> | injection attacks (see <xref target="code_injection"/>) and misuse of authorizat ion codes using one of the following options:</t> | |||
<ul spacing="compact"> | <ul spacing="compact"> | |||
<li>Public clients MUST use PKCE <xref target="RFC7636"/> to this end, as motiva ted in | <li>Public clients <bcp14>MUST</bcp14> use PKCE <xref target="RFC7636"/> to this end, as motivated in | |||
<xref target="pkce_as_injection_protection"/>.</li> | <xref target="pkce_as_injection_protection"/>.</li> | |||
<li>For confidential clients, the use of PKCE <xref target="RFC7636"/> is RECOMM ENDED, as it | <li>For confidential clients, the use of PKCE <xref target="RFC7636"/> is <bcp14 >RECOMMENDED</bcp14>, as it | |||
provides strong protection against misuse and injection of authorization | provides strong protection against misuse and injection of authorization | |||
codes as described in <xref target="pkce_as_injection_protection"/> and, as a si | codes as described in <xref target="pkce_as_injection_protection"/>. Also, as a | |||
de-effect, | side effect, | |||
prevents CSRF even in the presence of strong attackers as described in | it prevents CSRF even in the presence of strong attackers as described in | |||
<xref target="csrf_countermeasures"/>.</li> | <xref target="csrf_countermeasures"/>.</li> | |||
<li>With additional precautions, described in <xref target="nonce_as_injection_p rotection"/>, | <li>With additional precautions, described in <xref target="nonce_as_injection_p rotection"/>, | |||
confidential OpenID Connect <xref target="OpenID.Core"/> clients MAY use the <tt >nonce</tt> parameter and the | confidential OpenID Connect <xref target="OpenID.Core"/> clients <bcp14>MAY</bcp 14> use the <tt>nonce</tt> parameter and the | |||
respective Claim in the ID Token instead.</li> | respective Claim in the ID Token instead.</li> | |||
</ul> | </ul> | |||
<t>In any case, the PKCE challenge or OpenID Connect <tt>nonce</tt> MUST be | <t>In any case, the PKCE challenge or OpenID Connect <tt>nonce</tt> <bcp14>MUST< /bcp14> be | |||
transaction-specific and securely bound to the client and the user agent in | transaction-specific and securely bound to the client and the user agent in | |||
which the transaction was started. | which the transaction was started. | |||
Authorization servers are encouraged to make a reasonable effort at detecting an d | Authorization servers are encouraged to make a reasonable effort at detecting an d | |||
preventing the use of constant PKCE challenge or OpenID Connect <tt>nonce</tt> v alues.</t> | preventing the use of constant values for the PKCE challenge or OpenID Connect < tt>nonce</tt>.</t> | |||
<t>Note: Although PKCE was designed as a mechanism to protect native | <t>Note: Although PKCE was designed as a mechanism to protect native | |||
apps, this advice applies to all kinds of OAuth clients, including web | apps, this advice applies to all kinds of OAuth clients, including web | |||
applications.</t> | applications.</t> | |||
<t>When using PKCE, clients SHOULD use PKCE code challenge methods that | <t>When using PKCE, clients <bcp14>SHOULD</bcp14> use PKCE code challenge method s that | |||
do not expose the PKCE verifier in the authorization request. | do not expose the PKCE verifier in the authorization request. | |||
Otherwise, attackers that can read the authorization request (cf. | Otherwise, attackers that can read the authorization request (cf. Attacker <xref | |||
Attacker A4 in <xref target="secmodel"/>) can break the security provided | target="read_request" format="none">(A4)</xref> in <xref target="secmodel"/>) c | |||
an break the security provided | ||||
by PKCE. Currently, <tt>S256</tt> is the only such method.</t> | by PKCE. Currently, <tt>S256</tt> is the only such method.</t> | |||
<t>Authorization servers MUST support PKCE <xref target="RFC7636"/>.</t> | <t>Authorization servers <bcp14>MUST</bcp14> support PKCE <xref target="RFC7636" | |||
<t>If a client sends a valid PKCE <xref target="RFC7636"/> <tt>code_challenge</t | />.</t> | |||
t> parameter in the | <t>If a client sends a valid PKCE <tt>code_challenge</tt> parameter in the | |||
authorization request, the authorization server MUST enforce the correct usage | authorization request, the authorization server <bcp14>MUST</bcp14> enforce the | |||
correct usage | ||||
of <tt>code_verifier</tt> at the token endpoint.</t> | of <tt>code_verifier</tt> at the token endpoint.</t> | |||
<t>Authorization servers MUST mitigate PKCE Downgrade Attacks by ensuring that a | <t>Authorization servers <bcp14>MUST</bcp14> mitigate PKCE downgrade attacks by ensuring that a | |||
token request containing a <tt>code_verifier</tt> parameter is accepted only if a | token request containing a <tt>code_verifier</tt> parameter is accepted only if a | |||
<tt>code_challenge</tt> parameter was present in the authorization request, see | <tt>code_challenge</tt> parameter was present in the authorization request; see | |||
<xref target="pkce_downgrade_countermeasures"/> for details.</t> | <xref target="pkce_downgrade_countermeasures"/> for details.</t> | |||
<t>Authorization servers MUST provide a way to detect their support for | <t>Authorization servers <bcp14>MUST</bcp14> provide a way to detect their suppo | |||
PKCE. It is RECOMMENDED for authorization servers to publish the element | rt for | |||
<tt>code_challenge_methods_supported</tt> in their Authorization Server Metadata | PKCE. It is <bcp14>RECOMMENDED</bcp14> for authorization servers to publish the | |||
(<xref target="RFC8414"/>) | element | |||
<tt>code_challenge_methods_supported</tt> in their Authorization Server Metadata | ||||
<xref target="RFC8414"/> | ||||
containing the supported PKCE challenge methods (which can be used by | containing the supported PKCE challenge methods (which can be used by | |||
the client to detect PKCE support). Authorization servers MAY instead provide a | the client to detect PKCE support). Authorization servers <bcp14>MAY</bcp14> ins tead provide a | |||
deployment-specific way to ensure or determine PKCE support by the authorization server.</t> | deployment-specific way to ensure or determine PKCE support by the authorization server.</t> | |||
</section> | </section> | |||
<section anchor="implicit_grant_recommendation"><name>Implicit Grant</name> | <section anchor="implicit_grant_recommendation"><name>Implicit Grant</name> | |||
<t>The implicit grant (response type "token") and other response types | <t>The implicit grant (response type <tt>token</tt>) and other response types | |||
causing the authorization server to issue access tokens in the | causing the authorization server to issue access tokens in the | |||
authorization response are vulnerable to access token leakage and | authorization response are vulnerable to access token leakage and | |||
access token replay as described in <xref target="insufficient_uri_validation"/> | access token replay as described in Sections <xref target="insufficient_uri_vali | |||
, | dation" format="counter"/>, | |||
<xref target="credential_leakage_referrer"/>, <xref target="browser_history"/>, | <xref target="credential_leakage_referrer" format="counter"/>, <xref target="bro | |||
and | wser_history" format="counter"/>, and | |||
<xref target="access_token_injection"/>.</t> | <xref target="access_token_injection" format="counter"/>.</t> | |||
<t>Moreover, no standardized method for sender-constraining exists to | <t>Moreover, no standardized method for sender-constraining exists to | |||
bind access tokens to a specific client (as recommended in | bind access tokens to a specific client (as recommended in | |||
<xref target="token_replay_prevention"/>) when the access tokens are issued in t he | <xref target="token_replay_prevention"/>) when the access tokens are issued in t he | |||
authorization response. This means that an attacker can use the leaked or stolen | authorization response. This means that an attacker can use the leaked or stolen | |||
access token at a resource endpoint.</t> | access token at a resource endpoint.</t> | |||
<t>In order to avoid these issues, clients SHOULD NOT use the implicit | <t>In order to avoid these issues, clients <bcp14>SHOULD NOT</bcp14> use the imp | |||
grant (response type "token") or other response types issuing | licit | |||
grant (response type <tt>token</tt>) or other response types issuing | ||||
access tokens in the authorization response, unless access token injection | access tokens in the authorization response, unless access token injection | |||
in the authorization response is prevented and the aforementioned token leakage | in the authorization response is prevented and the aforementioned token leakage | |||
vectors are mitigated.</t> | vectors are mitigated.</t> | |||
<t>Clients SHOULD instead use the response type <tt>code</tt> (i.e., authorizati on | <t>Clients <bcp14>SHOULD</bcp14> instead use the response type <tt>code</tt> (i. e., authorization | |||
code grant type) as specified in <xref target="ac"/> or any other response type that | code grant type) as specified in <xref target="ac"/> or any other response type that | |||
causes the authorization server to issue access tokens in the token | causes the authorization server to issue access tokens in the token | |||
response, such as the <tt>code id_token</tt> response type. This allows the | response, such as the <tt>code id_token</tt> response type. This allows the | |||
authorization server to detect replay attempts by attackers and | authorization server to detect replay attempts by attackers and | |||
generally reduces the attack surface since access tokens are not | generally reduces the attack surface since access tokens are not | |||
exposed in URLs. It also allows the authorization server to | exposed in URLs. It also allows the authorization server to | |||
sender-constrain the issued tokens (see next section).</t> | sender-constrain the issued tokens (see <xref target="token_replay_prevention"/> .</t> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="token_replay_prevention"><name>Token Replay Prevention</name> | <section anchor="token_replay_prevention"><name>Token Replay Prevention</name> | |||
<section anchor="access-tokens"><name>Access Tokens</name> | <section anchor="access-tokens"><name>Access Tokens</name> | |||
<t>A sender-constrained access token scopes the applicability of an access | <t>A sender-constrained access token scopes the applicability of an access | |||
token to a certain sender. This sender is obliged to demonstrate knowledge | token to a certain sender. This sender is obliged to demonstrate knowledge | |||
of a certain secret as a prerequisite for the acceptance of that token at | of a certain secret as a prerequisite for the acceptance of that token at | |||
the recipient (e.g., a resource server).</t> | the recipient (e.g., a resource server).</t> | |||
<t>Authorization and resource servers SHOULD use mechanisms for sender-constrain | <t>Authorization and resource servers <bcp14>SHOULD</bcp14> use mechanisms for s | |||
ing | ender-constraining | |||
access tokens, such as Mutual TLS for OAuth 2.0 <xref target="RFC8705"/> or OAut | access tokens, such as mutual TLS for OAuth 2.0 <xref target="RFC8705"/> or OAut | |||
h 2.0 | h 2.0 | |||
Demonstrating Proof of Possession (DPoP) <xref target="RFC9449"/> (see | Demonstrating Proof of Possession (DPoP) <xref target="RFC9449"/> (see | |||
<xref target="pop_tokens"/>), to prevent misuse of stolen and leaked access toke ns.</t> | <xref target="pop_tokens"/>), to prevent misuse of stolen and leaked access toke ns.</t> | |||
</section> | </section> | |||
<section anchor="refresh-tokens"><name>Refresh Tokens</name> | <section anchor="refresh-tokens"><name>Refresh Tokens</name> | |||
<t>Refresh tokens for public clients MUST be sender-constrained or use refresh | <t>Refresh tokens for public clients <bcp14>MUST</bcp14> be sender-constrained o r use refresh | |||
token rotation as described in <xref target="refresh_token_protection"/>. <xref target="RFC6749"/> already | token rotation as described in <xref target="refresh_token_protection"/>. <xref target="RFC6749"/> already | |||
mandates that refresh tokens for confidential clients can only be used by the | mandates that refresh tokens for confidential clients can only be used by the | |||
client for which they were issued.</t> | client for which they were issued.</t> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="access-token-privilege-restriction"><name>Access Token Privileg e Restriction</name> | <section anchor="access-token-privilege-restriction"><name>Access Token Privileg e Restriction</name> | |||
<t>The privileges associated with an access token SHOULD be restricted to | <t>The privileges associated with an access token <bcp14>SHOULD</bcp14> be restr icted to | |||
the minimum required for the particular application or use case. This | the minimum required for the particular application or use case. This | |||
prevents clients from exceeding the privileges authorized by the | prevents clients from exceeding the privileges authorized by the | |||
resource owner. It also prevents users from exceeding their privileges | resource owner. It also prevents users from exceeding their privileges | |||
authorized by the respective security policy. Privilege restrictions | authorized by the respective security policy. Privilege restrictions | |||
also help to reduce the impact of access token leakage.</t> | also help to reduce the impact of access token leakage.</t> | |||
<t>In particular, access tokens SHOULD be audience-restricted to a specific reso | ||||
urce | <t>In particular, access tokens <bcp14>SHOULD</bcp14> be audience-restricted to | |||
server, or, if that is not feasible, to a small set of resource servers. To put | a specific resource | |||
this into effect, the authorization server associates | server or, if that is not feasible, to a small set of resource servers. To put t | |||
the access token with certain resource servers and every resource | his into effect, the authorization server associates | |||
the access token with certain resource servers, and every resource | ||||
server is obliged to verify, for every request, whether the access | server is obliged to verify, for every request, whether the access | |||
token sent with that request was meant to be used for that particular | token sent with that request was meant to be used for that particular | |||
resource server. If it was not, the resource server MUST refuse to serve the | resource server. If it was not, the resource server <bcp14>MUST</bcp14> refuse t | |||
respective request. The <tt>aud</tt> claim as defined in <xref target="RFC9068"/ | o serve the | |||
> MAY be | respective request. The <tt>aud</tt> claim as defined in <xref target="RFC9068"/ | |||
used to audience-restrict access tokens. Clients and authorization servers MAY u | > <bcp14>MAY</bcp14> be | |||
tilize the | used to audience-restrict access tokens. Clients and authorization servers <bcp1 | |||
4>MAY</bcp14> utilize the | ||||
parameters <tt>scope</tt> or <tt>resource</tt> as specified in <xref target="RFC 6749"/> and | parameters <tt>scope</tt> or <tt>resource</tt> as specified in <xref target="RFC 6749"/> and | |||
<xref target="RFC8707"/>, respectively, to determine the | <xref target="RFC8707"/>, respectively, to determine the | |||
resource server they want to access.</t> | resource server they want to access.</t> | |||
<t>Additionally, access tokens SHOULD be restricted to certain resources | <t>Additionally, access tokens <bcp14>SHOULD</bcp14> be restricted to certain re sources | |||
and actions on resource servers or resources. To put this into effect, | and actions on resource servers or resources. To put this into effect, | |||
the authorization server associates the access token with the | the authorization server associates the access token with the | |||
respective resource and actions and every resource server is obliged | respective resource and actions and every resource server is obliged | |||
to verify, for every request, whether the access token sent with that | to verify, for every request, whether the access token sent with that | |||
request was meant to be used for that particular action on the | request was meant to be used for that particular action on the | |||
particular resource. If not, the resource server must refuse to serve | particular resource. If not, the resource server must refuse to serve | |||
the respective request. Clients and authorization servers MAY utilize | the respective request. Clients and authorization servers <bcp14>MAY</bcp14> uti lize | |||
the parameter <tt>scope</tt> as specified in <xref target="RFC6749"/> and <tt>au thorization_details</tt> as specified in <xref target="RFC9396"/> to determine t hose | the parameter <tt>scope</tt> as specified in <xref target="RFC6749"/> and <tt>au thorization_details</tt> as specified in <xref target="RFC9396"/> to determine t hose | |||
resources and/or actions.</t> | resources and/or actions.</t> | |||
</section> | </section> | |||
<section anchor="resource-owner-password-credentials-grant"><name>Resource Owner Password Credentials Grant</name> | <section anchor="resource-owner-password-credentials-grant"><name>Resource Owner Password Credentials Grant</name> | |||
<t>The resource owner password credentials grant <xref target="RFC6749"/> MUST N | ||||
OT | <t>The resource owner password credentials grant <xref target="RFC6749"/> <bcp14 | |||
>MUST NOT</bcp14> | ||||
be used. This grant type insecurely exposes the credentials of the resource | be used. This grant type insecurely exposes the credentials of the resource | |||
owner to the client. Even if the client is benign, this results in an increased | owner to the client. Even if the client is benign, usage of this grant results i | |||
attack surface (credentials can leak in more places than just the authorization | n an increased | |||
server) and users | attack surface (i.e., credentials can leak in more places than just the authoriz | |||
are trained to enter their credentials in places other than the authorization se | ation server) and in training users to enter their credentials in places other t | |||
rver.</t> | han the authorization server.</t> | |||
<t>Furthermore, the resource owner password credentials grant is not designed to | <t>Furthermore, the resource owner password credentials grant is not designed to | |||
work with two-factor authentication and authentication processes that require | work with two-factor authentication and authentication processes that require | |||
multiple user interaction steps. Authentication with cryptographic credentials | multiple user interaction steps. Authentication with cryptographic credentials | |||
(cf. WebCrypto <xref target="W3C.WebCrypto"/>, WebAuthn <xref target="W3C.WebAut hn"/>) may be impossible | (cf. WebCrypto <xref target="W3C.WebCrypto"/>, WebAuthn <xref target="W3C.WebAut hn"/>) may be impossible | |||
to implement with this grant type, as it is usually bound to a specific web orig in.</t> | to implement with this grant type, as it is usually bound to a specific web orig in.</t> | |||
</section> | </section> | |||
<section anchor="client-authentication"><name>Client Authentication</name> | <section anchor="client-authentication"><name>Client Authentication</name> | |||
<t>Authorization servers SHOULD enforce client authentication if it is feasible, in | <t>Authorization servers <bcp14>SHOULD</bcp14> enforce client authentication if it is feasible, in | |||
the particular deployment, to establish a process for issuance/registration of | the particular deployment, to establish a process for issuance/registration of | |||
credentials for clients and ensuring the confidentiality of those credentials.</ t> | credentials for clients and ensuring the confidentiality of those credentials.</ t> | |||
<t>It is RECOMMENDED to use asymmetric cryptography for | ||||
client authentication, such as mTLS <xref target="RFC8705"/> or signed JWTs | <t> | |||
("Private Key JWT") in accordance with <xref target="RFC7521"/> and <xref target | It is <bcp14>RECOMMENDED</bcp14> to use asymmetric cryptography for | |||
="RFC7523"/> | client authentication, such as mutual TLS for OAuth 2.0 <xref target="RFC8705"/> | |||
(in <xref target="OpenID.Core"/> defined as the client authentication method <tt | or signed JWTs | |||
>private_key_jwt</tt>). | ("Private Key JWT") in accordance with <xref target="RFC7521"/> and <xref target | |||
="RFC7523"/>. The latter is defined in <xref target="OpenID.Core"/> as the clien | ||||
t authentication method <tt>private_key_jwt</tt>). | ||||
When asymmetric cryptography for client authentication is used, authorization | When asymmetric cryptography for client authentication is used, authorization | |||
servers do not need to store sensitive symmetric keys, making these | servers do not need to store sensitive symmetric keys, making these | |||
methods more robust against leakage of keys.</t> | methods more robust against leakage of keys.</t> | |||
</section> | </section> | |||
<section anchor="other_recommendations"><name>Other Recommendations</name> | <section anchor="other_recommendations"><name>Other Recommendations</name> | |||
<t>The use of OAuth Authorization Server Metadata <xref target="RFC8414"/> can h elp to improve the security of OAuth | <t>The use of OAuth Authorization Server Metadata <xref target="RFC8414"/> can h elp to improve the security of OAuth | |||
deployments:</t> | deployments:</t> | |||
<ul spacing="compact"> | <ul spacing="compact"> | |||
<li>It ensures that security features and other new OAuth features can be enable d | <li>It ensures that security features and other new OAuth features can be enable d | |||
automatically by compliant software libraries.</li> | automatically by compliant software libraries.</li> | |||
<li>It reduces chances for misconfigurations, for example misconfigured endpoint | <li>It reduces chances for misconfigurations -- for example, misconfigured endpo int | |||
URLs (that might belong to an attacker) or misconfigured security features.</li> | URLs (that might belong to an attacker) or misconfigured security features.</li> | |||
<li>It can help to facilitate rotation of cryptographic keys and to ensure | <li>It can help to facilitate rotation of cryptographic keys and to ensure | |||
cryptographic agility.</li> | cryptographic agility.</li> | |||
</ul> | </ul> | |||
<t>It is therefore RECOMMENDED that authorization servers publish OAuth Authoriz | <t>It is therefore <bcp14>RECOMMENDED</bcp14> that authorization servers publish | |||
ation Server Metadata according to | OAuth Authorization Server Metadata according to | |||
<xref target="RFC8414"/> and that clients make use of this Authorization Server | <xref target="RFC8414"/> and that clients make use of this Authorization Server | |||
Metadata to configure themselves | Metadata (when available) to configure themselves.</t> | |||
when available.</t> | ||||
<t>Under the conditions described in <xref target="client_impersonating_counterm easures"/>, | <t>Under the conditions described in <xref target="client_impersonating_counterm easures"/>, | |||
authorization servers SHOULD NOT allow clients to influence their <tt>client_id< | authorization servers <bcp14>SHOULD NOT</bcp14> allow clients to influence their | |||
/tt> or | <tt>client_id</tt> or | |||
any claim that could cause confusion with a genuine resource owner.</t> | any other claim that could cause confusion with a genuine resource owner.</t> | |||
<t>It is RECOMMENDED to use end-to-end TLS according to <xref target="BCP195"/> | <t>It is <bcp14>RECOMMENDED</bcp14> to use end-to-end TLS according to <xref tar | |||
between the client and the resource server. If TLS | get="BCP195"/> between the client and the resource server. If TLS | |||
traffic needs to be terminated at an intermediary, refer to | traffic needs to be terminated at an intermediary, refer to | |||
<xref target="tls_terminating"/> for further security advice.</t> | <xref target="tls_terminating"/> for further security advice.</t> | |||
<t>Authorization responses MUST NOT be transmitted over unencrypted network | <t>Authorization responses <bcp14>MUST NOT</bcp14> be transmitted over unencrypt | |||
connections. To this end, authorization servers MUST NOT allow redirect URIs tha | ed network | |||
t use the <tt>http</tt> | connections. To this end, authorization servers <bcp14>MUST NOT</bcp14> allow re | |||
scheme except for native clients that use Loopback Interface Redirection as | direction URIs that use the <tt>http</tt> | |||
described in <xref target="RFC8252"/>, Section 7.3.</t> | scheme except for native clients that use loopback interface redirection as | |||
described in <xref target="RFC8252" sectionFormat="of" section="7.3"/>.</t> | ||||
<t>If the authorization response is sent with in-browser communication technique s | <t>If the authorization response is sent with in-browser communication technique s | |||
like postMessage <xref target="WHATWG.postmessage_api"/> instead of HTTP redirec ts, both the | like postMessage <xref target="WHATWG.postmessage_api"/> instead of HTTP redirec ts, both the | |||
initiator and receiver of the in-browser message MUST be strictly verified as de scribed | initiator and receiver of the in-browser message <bcp14>MUST</bcp14> be strictly verified as described | |||
in <xref target="rec_ibc"/>.</t> | in <xref target="rec_ibc"/>.</t> | |||
<t>To support browser-based clients, endpoints directly accessed by such clients | <t>To support browser-based clients, endpoints directly accessed by such clients | |||
including the Token Endpoint, Authorization Server Metadata Endpoint, <tt>jwks_u ri</tt> | including the Token Endpoint, Authorization Server Metadata Endpoint, <tt>jwks_u ri</tt> | |||
Endpoint, and the Dynamic Client Registration Endpoint MAY support the use of | Endpoint, and Dynamic Client Registration Endpoint <bcp14>MAY</bcp14> support th | |||
Cross-Origin Resource Sharing (CORS, <xref target="WHATWG.CORS"/>). However, COR | e use of | |||
S MUST NOT be | Cross-Origin Resource Sharing (CORS) <xref target="WHATWG.CORS"/>. | |||
supported at the Authorization Endpoint, as the client does not access this | However, CORS <bcp14>MUST NOT</bcp14> be | |||
supported at the authorization endpoint, as the client does not access this | ||||
endpoint directly; instead, the client redirects the user agent to it.</t> | endpoint directly; instead, the client redirects the user agent to it.</t> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="secmodel"><name>The Updated OAuth 2.0 Attacker Model</name> | <section anchor="secmodel"><name>The Updated OAuth 2.0 Attacker Model</name> | |||
<t>In <xref target="RFC6819"/>, a threat model is laid out that describes the th reats against | <t>In <xref target="RFC6819"/>, a threat model is laid out that describes the th reats against | |||
which OAuth deployments must be protected. While doing so, <xref target="RFC6819 "/> makes | which OAuth deployments must be protected. While doing so, <xref target="RFC6819 "/> makes | |||
certain assumptions about attackers and their capabilities, i.e., implicitly | certain assumptions about attackers and their capabilities, i.e., it implicitly | |||
establishes an attacker model. In the following, this attacker model is made | establishes an attacker model. In the following, this attacker model is made | |||
explicit and is updated and expanded to account for the potentially dynamic | explicit and is updated and expanded to account for the potentially dynamic | |||
relationships involving multiple parties (as described in <xref target="Introduc tion"/>), to | relationships involving multiple parties (as described in <xref target="Introduc tion"/>), to | |||
include new types of attackers and to define the attacker model more clearly.</t > | include new types of attackers, and to define the attacker model more clearly.</ t> | |||
<t>The goal of this document is to ensure that the authorization of a resource | <t>The goal of this document is to ensure that the authorization of a resource | |||
owner (with a user agent) at an authorization server and the subsequent usage of | owner (with a user agent) at an authorization server and the subsequent usage of | |||
the access token at a resource server is protected, as well as practically | the access token at a resource server is protected, as well as practically | |||
possible, at least against the following attackers:</t> | possible, at least against the following attackers.</t> | |||
<ul> | <ol type="(A%d)"> | |||
<li><t>(A1) Web Attackers that can set up and operate an arbitrary number of | <li anchor="web_attackers"><t>Web attackers that can set up and operate an arbit | |||
rary number of | ||||
network endpoints (besides the "honest" ones) including browsers and | network endpoints (besides the "honest" ones) including browsers and | |||
servers. Web attackers may set up web sites that are visited by the resource | servers. Web attackers may set up websites that are visited by the resource | |||
owner, operate their own user agents, and participate in the protocol.</t> | owner, operate their own user agents, and participate in the protocol.</t> | |||
<t>Web attackers may, in particular, operate OAuth clients that are registered | <t>In particular, web attackers may operate OAuth clients that are registered | |||
at the authorization server, and operate their own authorization and | at the authorization server, and they may operate their own authorization and | |||
resource servers that can be used (in parallel to the "honest" ones) by the | resource servers that can be used (in parallel to the "honest" ones) by the | |||
resource owner and other resource owners.</t> | resource owner and other resource owners.</t> | |||
<t>It must also be assumed that web attackers can lure the user to | <t>It must also be assumed that web attackers can lure the user to | |||
navigate their browser to arbitrary attacker-chosen URIs at any time. In practic e, this | navigate their browser to arbitrary attacker-chosen URIs at any time. In practic e, this | |||
can be achieved in many ways, for example, by injecting malicious | can be achieved in many ways, for example, by injecting malicious | |||
advertisements into advertisement networks, or by sending | advertisements into advertisement networks or by sending | |||
legitimate-looking emails.</t> | legitimate-looking emails.</t> | |||
<t>Web attackers can use their own user credentials to create new | <t>Web attackers can use their own user credentials to create new | |||
messages as well as any secrets they learned previously. For | messages as well as any secrets they learned previously. For | |||
example, if a web attacker learns an authorization code of a user | example, if a web attacker learns an authorization code of a user | |||
through a misconfigured redirect URI, the web attacker can then | through a misconfigured redirection URI, the web attacker can then | |||
try to redeem that code for an access token.</t> | try to redeem that code for an access token.</t> | |||
<t>They cannot, however, read or manipulate messages that are not | <t>They cannot, however, read or manipulate messages that are not | |||
targeted towards them (e.g., sent to a URL controlled by a | targeted towards them (e.g., sent to a URL of an authorization server not under | |||
non-attacker controlled authorization server).</t> | control of an attacker).</t> | |||
</li> | </li> | |||
<li><t>(A2) Network Attackers that additionally have full control over | <li anchor="network_attackers"><t>Network attackers that additionally have full control over | |||
the network over which protocol participants communicate. They can | the network over which protocol participants communicate. They can | |||
eavesdrop on, manipulate, and spoof messages, except when these | eavesdrop on, manipulate, and spoof messages, except when these | |||
are properly protected by cryptographic methods (e.g., TLS). | are properly protected by cryptographic methods (e.g., TLS). | |||
Network attackers can also block arbitrary messages.</t> | Network attackers can also block arbitrary messages.</t> | |||
</li> | </li> | |||
</ul> | </ol> | |||
<t>While an example for a web attacker would be a customer of an internet | <t>While an example for a web attacker would be a customer of an internet | |||
service provider, network attackers could be the internet service | service provider, network attackers could be the internet service | |||
provider itself, an attacker in a public (Wi-Fi) network using ARP | provider itself, an attacker in a public (Wi-Fi) network using ARP | |||
spoofing, or a state-sponsored attacker with access to internet | spoofing, or a state-sponsored attacker with access to internet | |||
exchange points, for instance.</t> | exchange points, for instance.</t> | |||
<t>The aforementioned attackers (A1) and (A2) conform to the attacker model that was used in formal analysis | <t>The aforementioned attackers <xref target="web_attackers" format="none">(A1)< /xref> and <xref target="network_attackers" format="none">(A2)</xref> conform to the attacker model that was used in formal analysis | |||
efforts for OAuth <xref target="arXiv.1601.01229"/>. This is a minimal attacker model. | efforts for OAuth <xref target="arXiv.1601.01229"/>. This is a minimal attacker model. | |||
Implementers MUST take into account all possible types of attackers in the | Implementers <bcp14>MUST</bcp14> take into account all possible types of attacke rs in the | |||
environment of their OAuth implementations. For example, in <xref target="arXiv. 1901.11520"/>, | environment of their OAuth implementations. For example, in <xref target="arXiv. 1901.11520"/>, | |||
a very strong attacker model is used that includes attackers that have | a very strong attacker model is used that includes attackers that have | |||
full control over the token endpoint. This models effects of a | full control over the token endpoint. This models effects of a | |||
possible misconfiguration of endpoints in the ecosystem, which can be avoided | possible misconfiguration of endpoints in the ecosystem, which can be avoided | |||
by using authorization server metadata as described in <xref target="other_recom mendations"/>. Such an attacker is therefore not listed here.</t> | by using authorization server metadata as described in <xref target="other_recom mendations"/>. Such an attacker is therefore not listed here.</t> | |||
<t>However, previous attacks on OAuth have shown that the following types of | <t>However, previous attacks on OAuth have shown that the following types of | |||
attackers are relevant in particular:</t> | attackers are relevant in particular:</t> | |||
<ul> | <ol type="(A%d)" start="3"> | |||
<li><t>(A3) Attackers that can read, but not modify, the contents of the | <li anchor="read_response"> | |||
authorization response (i.e., the authorization response can leak | <t> | |||
to an attacker).</t> | Attackers that can read, but not modify, the contents of the | |||
<t>Examples for such attacks include open redirector attacks, insufficient | authorization response (i.e., the authorization response can leak | |||
checking of redirect URIs (see <xref target="insufficient_uri_validation"/>), pr | to an attacker). | |||
oblems | </t> | |||
existing on mobile operating systems (where different apps can register | <t> | |||
themselves on the same URI), mix-up attacks (see <xref target="mix_up"/>), where | Examples of such attacks include open redirector attacks and | |||
the | mix-up attacks (see <xref target="mix_up"/>), where the client is tricked | |||
client is tricked into sending credentials to an attacker-controlled authorizati | into sending credentials to an attacker-controlled authorization | |||
on server, and | server. | |||
the fact that URLs are often stored/logged by browsers (history), proxy | </t> | |||
servers, and operating systems.</t> | <t> | |||
Also, this includes attacks that take advantage of: | ||||
</t> | ||||
<ul spacing="compact"> | ||||
<li> insufficient checking of redirect URIs (see <xref target="insufficient_ | ||||
uri_validation"/>);</li> | ||||
<li> problems existing on mobile operating systems, where different | ||||
apps can register themselves on the same URI; and</li> | ||||
<li> URLs stored/logged by browsers (history), proxy servers, and operating | ||||
systems.</li> | ||||
</ul> | ||||
</li> | </li> | |||
<li><t>(A4) Attackers that can read, but not modify, the contents of the | <li anchor="read_request"><t>Attackers that can read, but not modify, the conten ts of the | |||
authorization request (i.e., the authorization request can leak, | authorization request (i.e., the authorization request can leak, | |||
in the same manner as above, to an attacker).</t> | in the same manner as above, to an attacker).</t> | |||
</li> | </li> | |||
<li><t>(A5) Attackers that can acquire an access token issued by an authorizatio | <li anchor="acquire_token"><t>Attackers that can acquire an access token issued | |||
n server. For | by an authorization server. | |||
example, a resource server can be compromised by an attacker, an | For | |||
example, a resource server may be compromised by an attacker, an | ||||
access token may be sent to an attacker-controlled resource server | access token may be sent to an attacker-controlled resource server | |||
due to a misconfiguration, or a resource owner is social-engineered into | due to a misconfiguration, or social engineering may be used to get a resource o | |||
using an attacker-controlled resource server. Also see <xref target="comp_res_se | wner to | |||
rver"/>.</t> | use an attacker-controlled resource server. Also see <xref target="comp_res_serv | |||
er"/>.</t> | ||||
</li> | </li> | |||
</ul> | </ol> | |||
<t>(A3), (A4) and (A5) typically occur together with either (A1) or (A2). | <t><xref target="read_response" format="none">(A3)</xref>, <xref target="read_re | |||
quest" format="none">(A4)</xref>, and <xref target="acquire_token" format="none" | ||||
>(A5)</xref> typically occur together with either <xref target="web_attackers" f | ||||
ormat="none">(A1)</xref> or <xref target="network_attackers" format="none">(A2)< | ||||
/xref>. | ||||
Attackers can collaborate to reach a common goal.</t> | Attackers can collaborate to reach a common goal.</t> | |||
<t>Note that an attacker (A1) or (A2) can be a resource owner or | <t>Note that an Attacker <xref target="web_attackers" format="none">(A1)</xref> or <xref target="network_attackers" format="none">(A2)</xref> can be a resource owner or | |||
act as one. For example, such an attacker can use their own browser to replay | act as one. For example, such an attacker can use their own browser to replay | |||
tokens or authorization codes obtained by any of the attacks described | tokens or authorization codes obtained by any of the attacks described | |||
above at the client or resource server.</t> | above at the client or resource server.</t> | |||
<t>This document focuses on threats resulting from attackers (A1) to (A5).</t> | <t>This document focuses on threats resulting from Attackers <xref target="web_a ttackers" format="none">(A1)</xref> to <xref target="acquire_token" format="none ">(A5)</xref>.</t> | |||
</section> | </section> | |||
<section anchor="attacks_and_mitigations"><name>Attacks and Mitigations</name> | <section anchor="attacks_and_mitigations"><name>Attacks and Mitigations</name> | |||
<t>This section gives a detailed description of attacks on OAuth implementations , | <t>This section gives a detailed description of attacks on OAuth implementations , | |||
along with potential countermeasures. Attacks and mitigations already covered in | along with potential countermeasures. Attacks and mitigations already covered in | |||
<xref target="RFC6819"/> are not listed here, except where new recommendations a re made.</t> | <xref target="RFC6819"/> are not listed here, except where new recommendations a re made.</t> | |||
<t>This section further defines additional requirements beyond those defined in | <t>This section further defines additional requirements (beyond those defined in | |||
<xref target="recommendations"/> for certain cases and protocol options.</t> | <xref target="recommendations"/>) for certain cases and protocol options.</t> | |||
<section anchor="insufficient_uri_validation"><name>Insufficient Redirect URI Va | <section anchor="insufficient_uri_validation"><name>Insufficient Redirection URI | |||
lidation</name> | Validation</name> | |||
<t>Some authorization servers allow clients to register redirect URI | <t>Some authorization servers allow clients to register redirection URI | |||
patterns instead of complete redirect URIs. The authorization servers | patterns instead of complete redirection URIs. The authorization servers | |||
then match the redirect URI parameter value at the authorization | then match the redirection URI parameter value at the authorization | |||
endpoint against the registered patterns at runtime. This approach | endpoint against the registered patterns at runtime. This approach | |||
allows clients to encode transaction state into additional redirect | allows clients to encode transaction state into additional redirect | |||
URI parameters or to register a single pattern for multiple | URI parameters or to register a single pattern for multiple | |||
redirect URIs.</t> | redirection URIs.</t> | |||
<t>This approach turned out to be more complex to implement and more | <t>This approach turned out to be more complex to implement and more | |||
error-prone to manage than exact redirect URI matching. Several | error-prone to manage than exact redirection URI matching. Several | |||
successful attacks exploiting flaws in the pattern-matching | successful attacks exploiting flaws in the pattern-matching | |||
implementation or concrete configurations have been observed in the | implementation or concrete configurations have been observed in the | |||
wild (see, e.g., <xref target="research.rub2"/>). Insufficient validation of the redirect URI effectively breaks | wild (see, e.g., <xref target="research.rub2"/>). Insufficient validation of the redirection URI effectively breaks | |||
client identification or authentication (depending on grant and client | client identification or authentication (depending on grant and client | |||
type) and allows the attacker to obtain an authorization code or | type) and allows the attacker to obtain an authorization code or | |||
access token, either</t> | access token, either</t> | |||
<ul spacing="compact"> | <ul spacing="compact"> | |||
<li>by directly sending the user agent to a URI under the attacker's | <li>by directly sending the user agent to a URI under the attacker's | |||
control, or</li> | control, or</li> | |||
<li>by exposing the OAuth credentials to an attacker by utilizing an | <li>by exposing the OAuth credentials to an attacker by utilizing an | |||
open redirector at the client in conjunction with the way user | open redirector at the client in conjunction with the way user | |||
agents handle URL fragments.</li> | agents handle URL fragments.</li> | |||
</ul> | </ul> | |||
<t>These attacks are shown in detail in the following subsections.</t> | <t>These attacks are shown in detail in the following subsections.</t> | |||
<section anchor="insufficient_uri_validation_acg"><name>Redirect URI Validation Attacks on Authorization Code Grant</name> | <section anchor="insufficient_uri_validation_acg"><name>Redirect URI Validation Attacks on Authorization Code Grant</name> | |||
<t>For a client using the grant type <tt>code</tt>, an attack may work as | <t>For a client using the grant type <tt>code</tt>, an attack may work as | |||
follows:</t> | follows:</t> | |||
<t>Assume the redirect URL pattern <tt>https://*.somesite.example/*</tt> is | <t>Assume the redirection URL pattern <tt>https://*.somesite.example/*</tt> is | |||
registered for the client with the client ID <tt>s6BhdRkqt3</tt>. The | registered for the client with the client ID <tt>s6BhdRkqt3</tt>. The | |||
intention is to allow any subdomain of <tt>somesite.example</tt> to be a | intention is to allow any subdomain of <tt>somesite.example</tt> to be a | |||
valid redirect URI for the client, for example | valid redirection URI for the client, for example, | |||
<tt>https://app1.somesite.example/redirect</tt>. A naive implementation on | <tt>https://app1.somesite.example/redirect</tt>. However, a naive implementation | |||
the authorization server, however, might interpret the wildcard <tt>*</tt> as | on | |||
the authorization server might interpret the wildcard <tt>*</tt> as | ||||
"any character" and not "any character valid for a domain name". The | "any character" and not "any character valid for a domain name". The | |||
authorization server, therefore, might permit | authorization server, therefore, might permit | |||
<tt>https://attacker.example/.somesite.example</tt> as a redirect URI, | <tt>https://attacker.example/.somesite.example</tt> as a redirection URI, | |||
although <tt>attacker.example</tt> is a different domain potentially | although <tt>attacker.example</tt> is a different domain potentially | |||
controlled by a malicious party.</t> | controlled by a malicious party.</t> | |||
<t>The attack can then be conducted as follows:</t> | <t>The attack can then be conducted as follows:</t> | |||
<t>To begin, the attacker needs to trick the user into opening a tampered | <t>To begin, the attacker needs to trick the user into opening a tampered | |||
URL in their browser that launches a page under the attacker's | URL in their browser that launches a page under the attacker's | |||
control, say <tt>https://www.evil.example</tt> (see Attacker A1 in <xref target= "secmodel"/>).</t> | control, say, <tt>https://www.evil.example</tt> (see attacker <xref target="web_ attackers" format="none">A1</xref> in <xref target="secmodel"/>).</t> | |||
<t>This URL initiates the following authorization request with the client | <t>This URL initiates the following authorization request with the client | |||
ID of a legitimate client to the authorization endpoint (line breaks | ID of a legitimate client to the authorization endpoint (line breaks | |||
for display only):</t> | for display only):</t> | |||
<artwork><![CDATA[GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=9 | <sourcecode type="http-message"><![CDATA[ | |||
ad67f13 | GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=9ad67f13 | |||
&redirect_uri=https%3A%2F%2Fattacker.example%2F.somesite.example | &redirect_uri=https%3A%2F%2Fattacker.example%2F.somesite.example | |||
HTTP/1.1 | HTTP/1.1 | |||
Host: server.somesite.example | Host: server.somesite.example | |||
]]> | ]]></sourcecode> | |||
</artwork> | ||||
<t>The authorization server validates the redirect URI and compares it to | <t>The authorization server validates the redirection URI and compares it to | |||
the registered redirect URL patterns for the client <tt>s6BhdRkqt3</tt>. | the registered redirection URL patterns for the client <tt>s6BhdRkqt3</tt>. | |||
The authorization request is processed and presented to the user.</t> | The authorization request is processed and presented to the user.</t> | |||
<t>If the user does not see the redirect URI or does not recognize the | <t>If the user does not see the redirection URI or does not recognize the | |||
attack, the code is issued and immediately sent to the attacker's | attack, the code is issued and immediately sent to the attacker's | |||
domain. If an automatic approval of the authorization is enabled | domain. If an automatic approval of the authorization is enabled | |||
(which is not recommended for public clients according to | (which is not recommended for public clients according to | |||
<xref target="RFC6749"/>), the attack can be performed even without user | <xref target="RFC6749"/>), the attack can be performed even without user | |||
interaction.</t> | interaction.</t> | |||
<t>If the attacker impersonates a public client, the attacker can | <t>If the attacker impersonates a public client, the attacker can | |||
exchange the code for tokens at the respective token endpoint.</t> | exchange the code for tokens at the respective token endpoint.</t> | |||
<t>This attack will not work as easily for confidential clients, since | <t>This attack will not work as easily for confidential clients, since | |||
the code exchange requires authentication with the legitimate client's | the code exchange requires authentication with the legitimate client's | |||
secret. The attacker can, however, use the legitimate confidential | secret. However, the attacker can use the legitimate confidential | |||
client to redeem the code by performing an authorization code | client to redeem the code by performing an authorization code | |||
injection attack, see <xref target="code_injection"/>.</t> | injection attack; see <xref target="code_injection"/>.</t> | |||
<t>It is important to note that redirect URI validation vulnerabilities can also | <t>It is important to note that redirection URI validation vulnerabilities can a | |||
exist if the authorization | lso exist if the authorization | |||
server handles wildcards properly. For example, assume that the client | server handles wildcards properly. For example, assume that the client | |||
registers the redirect URL pattern <tt>https://*.somesite.example/*</tt> and | registers the redirection URL pattern <tt>https://*.somesite.example/*</tt> and | |||
the authorization server interprets this as "allow redirect URIs | the authorization server interprets this as "allow redirection URIs | |||
pointing to any host residing in the domain <tt>somesite.example</tt>". If an | pointing to any host residing in the domain <tt>somesite.example</tt>". If an | |||
attacker manages to establish a host or subdomain in | attacker manages to establish a host or subdomain in | |||
<tt>somesite.example</tt>, the attacker can impersonate the legitimate client. T | <tt>somesite.example</tt>, the attacker can impersonate the legitimate client. F | |||
his | or example, this | |||
could be caused, for example, by a subdomain takeover attack <xref target="resea | could be caused by a subdomain takeover attack <xref target="research.udel"/>, w | |||
rch.udel"/>, where an | here an | |||
outdated CNAME record (say, <tt>external-service.somesite.example</tt>) | outdated CNAME record (say, <tt>external-service.somesite.example</tt>) | |||
points to an external DNS name that does no longer exist (say, | points to an external DNS name that no longer exists (say, | |||
<tt>customer-abc.service.example</tt>) and can be taken over by an attacker | <tt>customer-abc.service.example</tt>) and can be taken over by an attacker | |||
(e.g., by registering as <tt>customer-abc</tt> with the external service).</t> | (e.g., by registering as <tt>customer-abc</tt> with the external service).</t> | |||
</section> | </section> | |||
<section anchor="redir_uri_open_redir"><name>Redirect URI Validation Attacks on Implicit Grant</name> | <section anchor="redir_uri_open_redir"><name>Redirect URI Validation Attacks on Implicit Grant</name> | |||
<t>The attack described above works for the implicit grant as well. If | <t>The attack described above works for the implicit grant as well. If | |||
the attacker is able to send the authorization response to an attacker-controlle d URI, the attacker will directly get access to the fragment carrying the | the attacker is able to send the authorization response to an attacker-controlle d URI, the attacker will directly get access to the fragment carrying the | |||
access token.</t> | access token.</t> | |||
<t>Additionally, implicit grants (and also other grants when using <tt>response_ mode=fragment</tt> as defined in <xref target="OAuth.Responses"/>) can be subjec t to a further kind of | <t>Additionally, implicit grants (and also other grants when using <tt>response_ mode=fragment</tt> as defined in <xref target="OAuth.Responses"/>) can be subjec t to a further kind of | |||
attack. It utilizes the fact that user agents re-attach fragments to | attack. The attack utilizes the fact that user agents reattach fragments to | |||
the destination URL of a redirect if the location header does not | the destination URL of a redirect if the location header does not | |||
contain a fragment (see <xref target="RFC9110"/>, Section 17.11). The attack | contain a fragment (see <xref target="RFC9110" sectionFormat="of" section="17.11 "/>). The attack | |||
described here combines this behavior with the client as an open | described here combines this behavior with the client as an open | |||
redirector (see <xref target="open_redirector_on_client"/>) in order to obtain a ccess tokens. This allows | redirector (see <xref target="open_redirector_on_client"/>) in order to obtain a ccess tokens. This allows | |||
circumvention even of very narrow redirect URI patterns, but not strict URL | circumvention even of very narrow redirection URI patterns, but not of strict UR L | |||
matching.</t> | matching.</t> | |||
<t>Assume the registered URL pattern for client <tt>s6BhdRkqt3</tt> is | <t>Assume the registered URL pattern for client <tt>s6BhdRkqt3</tt> is | |||
<tt>https://client.somesite.example/cb?*</tt>, i.e., any parameter is allowed | <tt>https://client.somesite.example/cb?*</tt>, i.e., any parameter is allowed | |||
for redirects to <tt>https://client.somesite.example/cb</tt>. Unfortunately, | for redirects to <tt>https://client.somesite.example/cb</tt>. Unfortunately, | |||
the client exposes an open redirector. This endpoint supports a | the client exposes an open redirector. This endpoint supports a | |||
parameter <tt>redirect_to</tt> which takes a target URL and will send the | parameter <tt>redirect_to</tt> which takes a target URL and will send the | |||
browser to this URL using an HTTP Location header redirect 303.</t> | browser to this URL using an HTTP Location header redirect 303.</t> | |||
<t>The attack can now be conducted as follows:</t> | <t>The attack can now be conducted as follows:</t> | |||
<t>To begin, as above, the attacker needs to trick the user into opening | <t>To begin, as above, the attacker needs to trick the user into opening | |||
a tampered URL in their browser that launches a page under the | a tampered URL in their browser that launches a page under the | |||
attacker's control, say <tt>https://www.evil.example</tt>.</t> | attacker's control, say, <tt>https://www.evil.example</tt>.</t> | |||
<t>Afterwards, the website initiates an authorization request that is | <t>Afterwards, the website initiates an authorization request that is | |||
very similar to the one in the attack on the code flow. Different to | very similar to the one in the attack on the code flow. Different to | |||
above, it utilizes the open redirector by encoding | above, it utilizes the open redirector by encoding | |||
<tt>redirect_to=https://attacker.example</tt> into the parameters of the | <tt>redirect_to=https://attacker.example</tt> into the parameters of the | |||
redirect URI and it uses the response type "token" (line breaks for display only ):</t> | redirection URI, and it uses the response type <tt>token</tt> (line breaks for d isplay only):</t> | |||
<artwork><![CDATA[GET /authorize?response_type=token&state=9ad67f13 | <sourcecode type="http-message"><![CDATA[ | |||
GET /authorize?response_type=token&state=9ad67f13 | ||||
&client_id=s6BhdRkqt3 | &client_id=s6BhdRkqt3 | |||
&redirect_uri=https%3A%2F%2Fclient.somesite.example | &redirect_uri=https%3A%2F%2Fclient.somesite.example | |||
%2Fcb%26redirect_to%253Dhttps%253A%252F | %2Fcb%26redirect_to%253Dhttps%253A%252F | |||
%252Fattacker.example%252F HTTP/1.1 | %252Fattacker.example%252F HTTP/1.1 | |||
Host: server.somesite.example | Host: server.somesite.example | |||
]]> | ]]></sourcecode> | |||
</artwork> | ||||
<t>Now, since the redirect URI matches the registered pattern, the | <t>Then, since the redirection URI matches the registered pattern, the | |||
authorization server permits the request and sends the resulting access | authorization server permits the request and sends the resulting access | |||
token in a 303 redirect (some response parameters omitted for | token in a 303 redirect (some response parameters omitted for | |||
readability):</t> | readability):</t> | |||
<artwork><![CDATA[HTTP/1.1 303 See Other | <sourcecode type="http-message"><![CDATA[ | |||
HTTP/1.1 303 See Other | ||||
Location: https://client.somesite.example/cb? | Location: https://client.somesite.example/cb? | |||
redirect_to%3Dhttps%3A%2F%2Fattacker.example%2Fcb | redirect_to%3Dhttps%3A%2F%2Fattacker.example%2Fcb | |||
#access_token=2YotnFZFEjr1zCsicMWpAA&... | #access_token=2YotnFZFEjr1zCsicMWpAA&... | |||
]]> | ]]></sourcecode> | |||
</artwork> | ||||
<t>At client.somesite.example, the request arrives at the open redirector. The e ndpoint will | <t>At client.somesite.example, the request arrives at the open redirector. The e ndpoint will | |||
read the redirect parameter and will issue an HTTP 303 Location header | read the redirect parameter and will issue an HTTP 303 Location header | |||
redirect to the URL <tt>https://attacker.example/</tt>.</t> | redirect to the URL <tt>https://attacker.example/</tt>.</t> | |||
<artwork><![CDATA[HTTP/1.1 303 See Other | <sourcecode type="http-message"><![CDATA[ | |||
HTTP/1.1 303 See Other | ||||
Location: https://attacker.example/ | Location: https://attacker.example/ | |||
]]> | ]]></sourcecode> | |||
</artwork> | ||||
<t>Since the redirector at client.somesite.example does not include a | <t>Since the redirector at client.somesite.example does not include a | |||
fragment in the Location header, the user agent will re-attach the | fragment in the Location header, the user agent will reattach the | |||
original fragment <tt>#access_token=2YotnFZFEjr1zCsicMWpAA&amp;...</tt> to | original fragment <tt>#access_token=2YotnFZFEjr1zCsicMWpAA&amp;...</tt> to | |||
the URL and will navigate to the following URL:</t> | the URL and will navigate to the following URL:</t> | |||
<artwork><![CDATA[https://attacker.example/#access_token=2YotnFZFEjr1z... | <artwork><![CDATA[ | |||
]]> | https://attacker.example/#access_token=2YotnFZFEjr1z... | |||
</artwork> | ]]></artwork> | |||
<t>The attacker's page at <tt>attacker.example</tt> can now access the | ||||
<t>The attacker's page at <tt>attacker.example</tt> can then access the | ||||
fragment and obtain the access token.</t> | fragment and obtain the access token.</t> | |||
</section> | </section> | |||
<section anchor="iuv_countermeasures"><name>Countermeasures</name> | <section anchor="iuv_countermeasures"><name>Countermeasures</name> | |||
<t>The complexity of implementing and managing pattern matching correctly obviou sly | <t>The complexity of implementing and managing pattern matching correctly obviou sly | |||
causes security issues. This document therefore advises simplifying the required | causes security issues. This document therefore advises simplifying the required | |||
logic and configuration by using exact redirect URI matching. This means the | logic and configuration by using exact redirection URI matching. This means the | |||
authorization server MUST ensure that the two URIs are equal, see <xref target=" | authorization server <bcp14>MUST</bcp14> ensure that the two URIs are equal; see | |||
RFC3986"/>, | <xref target="RFC3986" sectionFormat="of" section="6.2.1"/>, Simple String Comp | |||
Section 6.2.1, Simple String Comparison, for details. The only exception is | arison, for details. The only exception is | |||
native apps using a <tt>localhost</tt> URI: In this case, the authorization serv | native apps using a <tt>localhost</tt> URI: In this case, the authorization serv | |||
er MUST allow variable | er <bcp14>MUST</bcp14> allow variable | |||
port numbers as described in <xref target="RFC8252"/>, Section 7.3.</t> | port numbers as described in <xref target="RFC8252" sectionFormat="of" section=" | |||
7.3"/>.</t> | ||||
<t>Additional recommendations:</t> | <t>Additional recommendations:</t> | |||
<ul spacing="compact"> | <ul spacing="compact"> | |||
<li>Web servers on which redirect URIs are hosted MUST NOT expose open | <li>Web servers on which redirection URIs are hosted <bcp14>MUST NOT</bcp14> exp ose open | |||
redirectors (see <xref target="open_redirection"/>).</li> | redirectors (see <xref target="open_redirection"/>).</li> | |||
<li>Browsers reattach URL fragments to Location redirection URLs only | <li>Browsers reattach URL fragments to Location redirection URLs only | |||
if the URL in the Location header does not already contain a fragment. | if the URL in the Location header does not already contain a fragment. | |||
Therefore, servers MAY prevent browsers from reattaching fragments | Therefore, servers <bcp14>MAY</bcp14> prevent browsers from reattaching fragment s | |||
to redirection URLs by attaching an arbitrary fragment identifier, | to redirection URLs by attaching an arbitrary fragment identifier, | |||
for example <tt>#_</tt>, to URLs in Location headers.</li> | for example <tt>#_</tt>, to URLs in Location headers.</li> | |||
<li>Clients SHOULD use the authorization code response type instead of | <li>Clients <bcp14>SHOULD</bcp14> use the authorization code response type inste | |||
response types causing access token issuance at the authorization | ad of | |||
response types that cause access token issuance at the authorization | ||||
endpoint. This offers countermeasures against the reuse of leaked | endpoint. This offers countermeasures against the reuse of leaked | |||
credentials through the exchange process with the authorization | credentials through the exchange process with the authorization | |||
server and token replay through sender-constraining of the access | server and against token replay through sender-constraining of the access | |||
tokens.</li> | tokens.</li> | |||
</ul> | </ul> | |||
<t>If the origin and integrity of the authorization request containing | <t>If the origin and integrity of the authorization request containing | |||
the redirect URI can be verified, for example when using | the redirection URI can be verified, for example, when using | |||
<xref target="RFC9101"/> or <xref target="RFC9126"/> with client | <xref target="RFC9101"/> or <xref target="RFC9126"/> with client | |||
authentication, the authorization server MAY trust the redirect URI | authentication, the authorization server <bcp14>MAY</bcp14> trust the redirectio n URI | |||
without further checks.</t> | without further checks.</t> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="credential_leakage_referrer"><name>Credential Leakage via Refer er Headers</name> | <section anchor="credential_leakage_referrer"><name>Credential Leakage via Refer er Headers</name> | |||
<t>The contents of the authorization request URI or the authorization | <t>The contents of the authorization request URI or the authorization | |||
response URI can unintentionally be disclosed to attackers through the | response URI can unintentionally be disclosed to attackers through the | |||
Referer HTTP header (see <xref target="RFC9110"/>, Section 10.1.3), by leaking e | Referer HTTP header (see <xref target="RFC9110" sectionFormat="of" section="10.1 | |||
ither | .3"/>), by leaking from either the authorization server's or the client's websit | |||
from the authorization server's or the client's website, respectively. Most | e, respectively. Most | |||
importantly, authorization codes or <tt>state</tt> values can be disclosed in | importantly, authorization codes or <tt>state</tt> values can be disclosed in | |||
this way. Although specified otherwise in <xref target="RFC9110"/>, Section 10.1 .3, | this way. Although specified otherwise in <xref target="RFC9110" sectionFormat=" of" section="10.1.3"/>, | |||
the same may happen to access tokens conveyed in URI fragments due to | the same may happen to access tokens conveyed in URI fragments due to | |||
browser implementation issues, as illustrated by a (now fixed) issue in the Chro mium project <xref target="bug.chromium"/>.</t> | browser implementation issues, as illustrated by a (now fixed) issue in the Chro mium project <xref target="bug.chromium"/>.</t> | |||
<section anchor="leakage-from-the-oauth-client"><name>Leakage from the OAuth Cli ent</name> | <section anchor="leakage-from-the-oauth-client"><name>Leakage from the OAuth Cli ent</name> | |||
<t>Leakage from the OAuth client requires that the client, as a result of | <t>Leakage from the OAuth client requires that the client, as a result of | |||
a successful authorization request, renders a page that</t> | a successful authorization request, renders a page that</t> | |||
<ul spacing="compact"> | <ul spacing="compact"> | |||
<li>contains links to other pages under the attacker's control and a | <li>contains links to other pages under the attacker's control and a | |||
user clicks on such a link, or</li> | user clicks on such a link, or</li> | |||
skipping to change at line 682 ¶ | skipping to change at line 718 ¶ | |||
</section> | </section> | |||
<section anchor="leakage-from-the-authorization-server"><name>Leakage from the A uthorization Server</name> | <section anchor="leakage-from-the-authorization-server"><name>Leakage from the A uthorization Server</name> | |||
<t>In a similar way, an attacker can learn <tt>state</tt> from the authorization | <t>In a similar way, an attacker can learn <tt>state</tt> from the authorization | |||
request if the authorization endpoint at the authorization server | request if the authorization endpoint at the authorization server | |||
contains links or third-party content as above.</t> | contains links or third-party content as above.</t> | |||
</section> | </section> | |||
<section anchor="consequences"><name>Consequences</name> | <section anchor="consequences"><name>Consequences</name> | |||
<t>An attacker that learns a valid code or access token through a | <t>An attacker that learns a valid code or access token through a | |||
Referer header can perform the attacks as described in | Referer header can perform the attacks as described in Sections | |||
<xref target="insufficient_uri_validation_acg"/>, <xref target="code_injection"/ | <xref target="insufficient_uri_validation_acg" format="counter"/>, <xref target= | |||
>, and | "code_injection" format="counter"/> and | |||
<xref target="access_token_injection"/>. If the attacker learns <tt>state</tt>, | <xref target="access_token_injection" format="counter"/>. If the attacker learns | |||
the CSRF | <tt>state</tt>, the CSRF | |||
protection achieved by using <tt>state</tt> is lost, resulting in CSRF | protection achieved by using <tt>state</tt> is lost, resulting in CSRF | |||
attacks as described in <xref target="RFC6819"/>, Section 4.4.1.8.</t> | attacks as described in <xref target="RFC6819" sectionFormat="of" section="4.4.1 .8"/>.</t> | |||
</section> | </section> | |||
<section anchor="countermeasures"><name>Countermeasures</name> | <section anchor="countermeasures"><name>Countermeasures</name> | |||
<t>The page rendered as a result of the OAuth authorization response and | <t>The page rendered as a result of the OAuth authorization response and | |||
the authorization endpoint SHOULD NOT include third-party resources or | the authorization endpoint <bcp14>SHOULD NOT</bcp14> include third-party resourc es or | |||
links to external sites.</t> | links to external sites.</t> | |||
<t>The following measures further reduce the chances of a successful attack:</t> | <t>The following measures further reduce the chances of a successful attack:</t> | |||
<ul> | <ul> | |||
<li>Suppress the Referer header by applying an appropriate Referrer | <li>Suppress the Referer header by applying an appropriate Referrer | |||
Policy <xref target="W3C.webappsec-referrer-policy"/> to the document (either as | Policy <xref target="W3C.webappsec-referrer-policy"/> to the document (either as | |||
part of the "referrer" meta attribute or by setting a | part of the "referrer" meta attribute or by setting a | |||
Referrer-Policy header). For example, the header <tt>Referrer-Policy: | Referrer-Policy header). For example, the header <tt>Referrer-Policy: | |||
no-referrer</tt> in the response completely suppresses the Referer | no-referrer</tt> in the response completely suppresses the Referer | |||
header in all requests originating from the resulting document.</li> | header in all requests originating from the resulting document.</li> | |||
<li>Use authorization code instead of response types causing access | <li>Use authorization code instead of response types causing access | |||
token issuance from the authorization endpoint.</li> | token issuance from the authorization endpoint.</li> | |||
<li>Bind the authorization code to a confidential client or PKCE | <li>Bind the authorization code to a confidential client or PKCE | |||
challenge. In this case, the attacker lacks the secret to request | challenge. In this case, the attacker lacks the secret to request | |||
the code exchange.</li> | the code exchange.</li> | |||
<li><t>As described in <xref target="RFC6749"/>, Section 4.1.2, authorization co | <li><t>As described in <xref target="RFC6749" sectionFormat="of" section="4.1.2" | |||
des | />, authorization codes | |||
MUST be invalidated by the authorization server after their first use at the tok | <bcp14>MUST</bcp14> be invalidated by the authorization server after their first | |||
en | use at the token | |||
endpoint. For example, if an authorization server invalidated the code after the | endpoint. For example, if an authorization server invalidated the code after the | |||
legitimate client redeemed it, the attacker would fail to exchange | legitimate client redeemed it, the attacker would fail to exchange | |||
this code later.</t> | this code later.</t> | |||
<t>This does not mitigate the attack if the attacker manages to | <t>This does not mitigate the attack if the attacker manages to | |||
exchange the code for a token before the legitimate client does | exchange the code for a token before the legitimate client does | |||
so. Therefore, <xref target="RFC6749"/> further recommends that, when an | so. Therefore, <xref target="RFC6749"/> further recommends that, when an | |||
attempt is made to redeem a code twice, the authorization server SHOULD revoke a ll | attempt is made to redeem a code twice, the authorization server <bcp14>SHOULD</ bcp14> revoke all | |||
tokens issued previously based on that code.</t> | tokens issued previously based on that code.</t> | |||
</li> | </li> | |||
<li><t>The <tt>state</tt> value SHOULD be invalidated by the client after its | <li><t>The <tt>state</tt> value <bcp14>SHOULD</bcp14> be invalidated by the clie nt after its | |||
first use at the redirection endpoint. If this is implemented, and | first use at the redirection endpoint. If this is implemented, and | |||
an attacker receives a token through the Referer header from the | an attacker receives a token through the Referer header from the | |||
client's website, the <tt>state</tt> was already used, invalidated by | client's website, the <tt>state</tt> was already used, invalidated by | |||
the client and cannot be used again by the attacker. (This does | the client and cannot be used again by the attacker. (This does | |||
not help if the <tt>state</tt> leaks from the | not help if the <tt>state</tt> leaks from the | |||
authorization server's website, since then the <tt>state</tt> | authorization server's website, since then the <tt>state</tt> | |||
has not been used at the redirection endpoint at the client yet.)</t> | has not been used at the redirection endpoint at the client yet.)</t> | |||
</li> | </li> | |||
<li><t>Use the form post response mode instead of a redirect for the | <li><t>Use the form post response mode instead of a redirect for the | |||
authorization response (see <xref target="OAuth.Post"/>).</t> | authorization response (see <xref target="OAuth.Post"/>).</t> | |||
skipping to change at line 749 ¶ | skipping to change at line 785 ¶ | |||
<section anchor="authorization-code-in-browser-history"><name>Authorization Code in Browser History</name> | <section anchor="authorization-code-in-browser-history"><name>Authorization Code in Browser History</name> | |||
<t>When a browser navigates to | <t>When a browser navigates to | |||
<tt>client.example/redirection_endpoint?code=abcd</tt> as a result of a | <tt>client.example/redirection_endpoint?code=abcd</tt> as a result of a | |||
redirect from a provider's authorization endpoint, the URL including | redirect from a provider's authorization endpoint, the URL including | |||
the authorization code may end up in the browser's history. An | the authorization code may end up in the browser's history. An | |||
attacker with access to the device could obtain the code and try to | attacker with access to the device could obtain the code and try to | |||
replay it.</t> | replay it.</t> | |||
<t>Countermeasures:</t> | <t>Countermeasures:</t> | |||
<ul spacing="compact"> | <ul spacing="compact"> | |||
<li>Authorization code replay prevention as described in <xref target="RFC6819"/ | <li>Authorization code replay prevention as described in <xref target="RFC6819" | |||
>, | sectionFormat="of" section="4.4.1.1"/>, and <xref target="code_injection"/>.</li | |||
Section 4.4.1.1, and <xref target="code_injection"/>.</li> | > | |||
<li>Use form post response mode instead of redirect for the authorization | <li>Use the form post response mode instead of redirect for the authorization | |||
response (see <xref target="OAuth.Post"/>).</li> | response (see <xref target="OAuth.Post"/>).</li> | |||
</ul> | </ul> | |||
</section> | </section> | |||
<section anchor="access-token-in-browser-history"><name>Access Token in Browser History</name> | <section anchor="access-token-in-browser-history"><name>Access Token in Browser History</name> | |||
<t>An access token may end up in the browser history if a client or a web | <t>An access token may end up in the browser history if a client or a website th | |||
site that already has a token deliberately navigates to a page like | at already has a token deliberately navigates to a page like | |||
<tt>provider.com/get_user_profile?access_token=abcdef</tt>. <xref target="RFC675 0"/> | <tt>provider.com/get_user_profile?access_token=abcdef</tt>. <xref target="RFC675 0"/> | |||
discourages this practice and advises transferring tokens via a header, | discourages this practice and advises transferring tokens via a header, | |||
but in practice web sites often pass access tokens in query | but in practice websites often pass access tokens in query | |||
parameters.</t> | parameters.</t> | |||
<t>In the case of implicit grant, a URL like | <t>In the case of implicit grant, a URL like | |||
<tt>client.example/redirection_endpoint#access_token=abcdef</tt> may also end | <tt>client.example/redirection_endpoint#access_token=abcdef</tt> may also end | |||
up in the browser history as a result of a redirect from a provider's | up in the browser history as a result of a redirect from a provider's | |||
authorization endpoint.</t> | authorization endpoint.</t> | |||
<t>Countermeasures:</t> | <t>Countermeasures:</t> | |||
<ul spacing="compact"> | <ul spacing="compact"> | |||
<li>Clients MUST NOT pass access tokens in a URI query parameter in | <li>Clients <bcp14>MUST NOT</bcp14> pass access tokens in a URI query parameter | |||
the way described in Section 2.3 of <xref target="RFC6750"/>. The authorization | in | |||
the way described in <xref target="RFC6750" sectionFormat="of" section="2.3"/>. | ||||
The authorization | ||||
code grant or alternative OAuth response modes like the form post | code grant or alternative OAuth response modes like the form post | |||
response mode <xref target="OAuth.Post"/> can be used to | response mode <xref target="OAuth.Post"/> can be used to | |||
this end.</li> | this end.</li> | |||
</ul> | </ul> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="mix_up"><name>Mix-Up Attacks</name> | <section anchor="mix_up"><name>Mix-Up Attacks</name> | |||
<t>Mix-up is an attack on scenarios where an OAuth client interacts with | <t>Mix-up attacks can occur in scenarios where an OAuth client interacts with | |||
two or more authorization servers and at least one authorization | two or more authorization servers and at least one authorization | |||
server is under the control of the attacker. This can be the case, | server is under the control of the attacker. This can be the case, | |||
for example, if the attacker uses dynamic registration to register the | for example, if the attacker uses dynamic registration to register the | |||
client at their own authorization server or if an authorization server | client at their own authorization server or if an authorization server | |||
becomes compromised.</t> | becomes compromised.</t> | |||
<t>The goal of the attack is to obtain an authorization code or an access | <t>The goal of the attack is to obtain an authorization code or an access | |||
token for an uncompromised authorization server. This is achieved by | token for an uncompromised authorization server. This is achieved by | |||
tricking the client into sending those credentials to the compromised | tricking the client into sending those credentials to the compromised | |||
authorization server (the attacker) instead of using them at the | authorization server (the attacker) instead of using them at the | |||
respective endpoint of the uncompromised authorization/resource | respective endpoint of the uncompromised authorization/resource | |||
skipping to change at line 809 ¶ | skipping to change at line 843 ¶ | |||
<li>the implicit or authorization code grant is used with multiple authorization servers | <li>the implicit or authorization code grant is used with multiple authorization servers | |||
of which one is considered "honest" (H-AS) and one is operated by | of which one is considered "honest" (H-AS) and one is operated by | |||
the attacker (A-AS), and</li> | the attacker (A-AS), and</li> | |||
<li>the client stores the authorization server chosen by the user in a session b ound to | <li>the client stores the authorization server chosen by the user in a session b ound to | |||
the user's browser and uses the same redirection endpoint URI for | the user's browser and uses the same redirection endpoint URI for | |||
each authorization server.</li> | each authorization server.</li> | |||
</ul> | </ul> | |||
<t>In the following, it is further assumed that the client is registered with H- AS (URI: | <t>In the following, it is further assumed that the client is registered with H- AS (URI: | |||
<tt>https://honest.as.example</tt>, client ID: <tt>7ZGZldHQ</tt>) and with A-AS (URI: | <tt>https://honest.as.example</tt>, client ID: <tt>7ZGZldHQ</tt>) and with A-AS (URI: | |||
<tt>https://attacker.example</tt>, client ID: <tt>666RVZJTA</tt>). URLs shown in the following | <tt>https://attacker.example</tt>, client ID: <tt>666RVZJTA</tt>). URLs shown in the following | |||
example are shortened for presentation to only include parameters relevant to th e | example are shortened for presentation to include only parameters relevant to th e | |||
attack.</t> | attack.</t> | |||
<t>Attack on the authorization code grant:</t> | <t>Attack on the authorization code grant:</t> | |||
<ol> | <ol spacing="normal" type="1"> | |||
<li>The user selects to start the grant using A-AS (e.g., by clicking on a butto n on the | <li>The user selects to start the grant using A-AS (e.g., by clicking on a butto n on the | |||
client's website).</li> | client's website).</li> | |||
<li>The client stores in the user's session that the user selected | <li anchor="step_2_mixup">The client stores in the user's session that the user selected | |||
"A-AS" and redirects the user to A-AS's authorization endpoint | "A-AS" and redirects the user to A-AS's authorization endpoint | |||
with a Location header containing the URL | with a Location header containing the URL | |||
<tt>https://attacker.example/authorize?response_type=code&client_id=666RVZJT A</tt>.</li> | <tt>https://attacker.example/authorize?response_type=code&client_id=666RVZJT A</tt>.</li> | |||
<li>When the user's browser navigates to the attacker's authorization endpoint, | <li>When the user's browser navigates to the attacker's authorization endpoint, | |||
the attacker immediately redirects the browser to the authorization endpoint | the attacker immediately redirects the browser to the authorization endpoint | |||
of H-AS. In the authorization request, the attacker replaces the client ID | of H-AS. In the authorization request, the attacker replaces the client ID | |||
of the client at A-AS with the client's ID at H-AS. Therefore, the browser | of the client at A-AS with the client's ID at H-AS. Therefore, the browser | |||
receives a redirection (<tt>303 See Other</tt>) with a Location header pointing to | receives a redirection (303 See Other) with a Location header pointing to | |||
<tt>https://honest.as.example/authorize?response_type=code&client_id=7ZGZldH Q</tt></li> | <tt>https://honest.as.example/authorize?response_type=code&client_id=7ZGZldH Q</tt></li> | |||
<li><t>The user authorizes the client to access their resources at H-AS. (Note t | ||||
hat a | <li anchor="step_4_mixup"><t>The user authorizes the client to access their reso | |||
urces at H-AS. (Note that a | ||||
vigilant user might at this point detect that they intended to use A-AS | vigilant user might at this point detect that they intended to use A-AS | |||
instead of H-AS. The first attack variant listed below avoids this.) H-AS | instead of H-AS. The first attack variant listed does not have this limitation.) H-AS | |||
issues a code and sends it (via the browser) back to the client.</t> | issues a code and sends it (via the browser) back to the client.</t> | |||
</li> | </li> | |||
<li><t>Since the client still assumes that the code was issued by A-AS, | <li><t>Since the client still assumes that the code was issued by A-AS, | |||
it will try to redeem the code at A-AS's token endpoint.</t> | it will try to redeem the code at A-AS's token endpoint.</t> | |||
</li> | </li> | |||
<li><t>The attacker therefore obtains code and can either exchange the | <li><t>The attacker therefore obtains code and can either exchange the | |||
code for an access token (for public clients) or perform an | code for an access token (for public clients) or perform an | |||
authorization code injection attack as described in | authorization code injection attack as described in | |||
<xref target="code_injection"/>.</t> | <xref target="code_injection"/>.</t> | |||
</li> | </li> | |||
</ol> | </ol> | |||
<t>Variants:</t> | <t>Variants:</t> | |||
<ul spacing="compact"> | <ul spacing="compact"> | |||
<li>Mix-Up With Interception: This variant works only if the attacker can | <li>Mix-Up with Interception: This variant works only if the attacker can | |||
intercept and manipulate the first request/response pair from a user's | intercept and manipulate the first request/response pair from a user's | |||
browser to the client (in which the user selects a certain authorization server and is then | browser to the client (in which the user selects a certain authorization server and is then | |||
redirected by the client to that authorization server), as in Attacker A2 (see < | redirected by the client to that authorization server), as in <xref target="netw | |||
xref target="secmodel"/>). This capability | ork_attackers" | |||
format="none">Attacker (A2)</xref> (see <xref target="secmodel"/>). This capabil | ||||
ity | ||||
can, for example, be the result of a attacker-in-the-middle attack on the user's | can, for example, be the result of a attacker-in-the-middle attack on the user's | |||
connection to the client. In the attack, the user starts the flow with H-AS. | connection to the client. In the attack, the user starts the flow with H-AS. | |||
The attacker intercepts this request and changes the user's selection to | The attacker intercepts this request and changes the user's selection to | |||
A-AS. The rest of the attack proceeds as in Steps 2 and following above.</li> | A-AS. The rest of the attack proceeds as in <xref target="step_2_mixup" format=" none">Step 2</xref> and following above.</li> | |||
<li>Implicit Grant: In the implicit grant, the attacker receives an access | <li>Implicit Grant: In the implicit grant, the attacker receives an access | |||
token instead of the code in Step 4. The attacker's authorization server receive | token instead of the code in <xref target="step_4_mixup" format="none">Step 4</x | |||
s the access token | ref>. The attacker's authorization server receives the access token | |||
when the client makes a request to the A-AS userinfo endpoint, or since the | when the client makes either a request to the A-AS userinfo endpoint or a reques | |||
client believes it has completed the flow with A-AS, a request to the | t to the attacker's resource server (since the client believes it has completed | |||
attacker's resource server.</li> | the flow with A-AS).</li> | |||
<li>Per-AS Redirect URIs: If clients use different redirect URIs for | <li>Per-AS Redirect URIs: If clients use different redirection URIs for | |||
different authorization servers, do not store the selected authorization server | different authorization servers, clients do not store the selected authorization | |||
in the user's session, and authorization servers | server in the user's session, and authorization servers | |||
do not check the redirect URIs properly, attackers can mount an attack | do not check the redirection URIs properly, attackers can mount an attack | |||
called "Cross-Social Network Request Forgery". These attacks have been | called "Cross-Social Network Request Forgery". These attacks have been | |||
observed in practice. Refer to <xref target="research.jcs_14"/> for details.</li > | observed in practice. Refer to <xref target="research.jcs_14"/> for details.</li > | |||
<li>OpenID Connect: Some variants can be used to attack OpenID | <li>OpenID Connect: Some variants can be used to attack OpenID | |||
Connect. In these attacks, the attacker misuses features of the OpenID | Connect. In these attacks, the attacker misuses features of the OpenID | |||
Connect Discovery <xref target="OpenID.Discovery"/> mechanism or replays access tokens or ID | Connect Discovery <xref target="OpenID.Discovery"/> mechanism or replays access tokens or ID | |||
Tokens to conduct a mix-up attack. The attacks are described in detail in | Tokens to conduct a mix-up attack. The attacks are described in detail in Append | |||
<xref target="arXiv.1704.08539"/>, Appendix A, and <xref target="arXiv.1508.0432 | ix A of | |||
4v2"/>, Section 6 | <xref target="arXiv.1704.08539"/> and Section 6 of <xref target="arXiv.1508.0432 | |||
("Malicious Endpoints Attacks").</li> | 4v2"/> ("Malicious Endpoints Attacks").</li> | |||
</ul> | </ul> | |||
</section> | </section> | |||
<section anchor="mixupcountermeasures"><name>Countermeasures</name> | <section anchor="mixupcountermeasures"><name>Countermeasures</name> | |||
<t>When an OAuth client can only interact with one authorization server, a mix-u p | <t>When an OAuth client can only interact with one authorization server, a mix-u p | |||
defense is not required. In scenarios where an OAuth client interacts with two | defense is not required. In scenarios where an OAuth client interacts with two | |||
or more authorization servers, however, clients MUST prevent mix-up attacks. Two | or more authorization servers, however, clients <bcp14>MUST</bcp14> prevent mix- | |||
different methods are discussed in the following.</t> | up attacks. Two | |||
<t>For both defenses, clients MUST store, for each authorization request, the | different methods are discussed below.</t> | |||
<t>For both defenses, clients <bcp14>MUST</bcp14> store, for each authorization | ||||
request, the | ||||
issuer they sent the authorization request to and bind this information to the | issuer they sent the authorization request to and bind this information to the | |||
user agent. The issuer serves, via the associated metadata, as an abstract | user agent. The issuer serves, via the associated metadata, as an abstract | |||
identifier for the combination of the authorization endpoint and token endpoint | identifier for the combination of the authorization endpoint and token endpoint | |||
that are to be used in the flow. If an issuer identifier is not available, for | that are to be used in the flow. If an issuer identifier is not available (for | |||
example, if neither OAuth Authorization Server Metadata <xref target="RFC8414"/> nor OpenID Connect Discovery <xref target="OpenID.Discovery"/> is | example, if neither OAuth Authorization Server Metadata <xref target="RFC8414"/> nor OpenID Connect Discovery <xref target="OpenID.Discovery"/> is | |||
used, a different unique identifier for this tuple or the tuple itself can be | used), a different unique identifier for this tuple or the tuple itself can be | |||
used instead. For brevity of presentation, such a deployment-specific identifier | used instead. For brevity of presentation, such a deployment-specific identifier | |||
will be subsumed under the issuer (or issuer identifier) in the following.</t> | will be subsumed under the issuer (or issuer identifier) in the following.</t> | |||
<t>It is important to note that just storing the authorization server URL is not sufficient to identify | <t>It is important to note that just storing the authorization server URL is not sufficient to identify | |||
mix-up attacks. An attacker might declare an uncompromised authorization server' s authorization endpoint URL as | mix-up attacks. An attacker might declare an uncompromised authorization server' s authorization endpoint URL as | |||
"their" authorization server URL, but declare a token endpoint under their own c ontrol.</t> | "their" authorization server URL, but declare a token endpoint under their own c ontrol.</t> | |||
<section anchor="mix-up-defense-via-issuer-identification"><name>Mix-Up Defense via Issuer Identification</name> | <section anchor="mix-up-defense-via-issuer-identification"><name>Mix-Up Defense via Issuer Identification</name> | |||
<t>This defense requires that the authorization server sends its issuer identifi er | <t>This defense requires that the authorization server sends its issuer identifi er | |||
in the authorization response to the client. When receiving the authorization | in the authorization response to the client. When receiving the authorization | |||
response, the client MUST compare the received issuer identifier to the stored | response, the client <bcp14>MUST</bcp14> compare the received issuer identifier | |||
issuer identifier. If there is a mismatch, the client MUST abort the | to the stored | |||
issuer identifier. If there is a mismatch, the client <bcp14>MUST</bcp14> abort | ||||
the | ||||
interaction.</t> | interaction.</t> | |||
<t>There are different ways this issuer identifier can be transported to the cli ent:</t> | <t>There are different ways this issuer identifier can be transported to the cli ent:</t> | |||
<ul spacing="compact"> | <ul spacing="compact"> | |||
<li>The issuer information can be transported, for | <li>The issuer information can be transported, for | |||
example, via a separate response parameter <tt>iss</tt>, defined in | example, via a separate response parameter <tt>iss</tt>, defined in | |||
<xref target="RFC9207"/>.</li> | <xref target="RFC9207"/>.</li> | |||
<li>When OpenID Connect is used and an ID Token is returned in the authorization | <li>When OpenID Connect is used and an ID Token is returned in the authorization | |||
response, the client can evaluate the <tt>iss</tt> claim in the ID Token.</li> | response, the client can evaluate the <tt>iss</tt> claim in the ID Token.</li> | |||
</ul> | </ul> | |||
<t>In both cases, the <tt>iss</tt> value MUST be evaluated according to <xref ta rget="RFC9207"/>.</t> | <t>In both cases, the <tt>iss</tt> value <bcp14>MUST</bcp14> be evaluated accord ing to <xref target="RFC9207"/>.</t> | |||
<t>While this defense may require deploying new OAuth features to transport the | <t>While this defense may require deploying new OAuth features to transport the | |||
issuer information, it is a robust and relatively simple defense against mix-up. </t> | issuer information, it is a robust and relatively simple defense against mix-up. </t> | |||
</section> | </section> | |||
<section anchor="mix-up-defense-via-distinct-redirect-uris"><name>Mix-Up Defense via Distinct Redirect URIs</name> | <section anchor="mix-up-defense-via-distinct-redirect-uris"><name>Mix-Up Defense via Distinct Redirect URIs</name> | |||
<t>For this defense, clients MUST use a distinct redirect URI for each issuer | <t>For this defense, clients <bcp14>MUST</bcp14> use a distinct redirection URI for each issuer | |||
they interact with.</t> | they interact with.</t> | |||
<t>Clients MUST check that the authorization response was received from the corr | <t>Clients <bcp14>MUST</bcp14> check that the authorization response was receive | |||
ect | d from the correct | |||
issuer by comparing the distinct redirect URI for the issuer to the URI where | issuer by comparing the distinct redirection URI for the issuer to the URI where | |||
the authorization response was received on. If there is a mismatch, the client | the authorization response was received on. If there is a mismatch, the client | |||
MUST abort the flow.</t> | <bcp14>MUST</bcp14> abort the flow.</t> | |||
<t>While this defense builds upon existing OAuth functionality, it cannot be use d | <t>While this defense builds upon existing OAuth functionality, it cannot be use d | |||
in scenarios where clients only register once for the use of many different | in scenarios where clients only register once for the use of many different | |||
issuers (as in some open banking schemes) and due to the tight integration with | issuers (as in some open banking schemes) and due to the tight integration with | |||
the client registration, it is harder to deploy automatically.</t> | the client registration, it is harder to deploy automatically.</t> | |||
<t>Furthermore, an attacker might be able to circumvent the protection offered b y | <t>Furthermore, an attacker might be able to circumvent the protection offered b y | |||
this defense by registering a new client with the "honest" authorization server using the redirect | this defense by registering a new client with the "honest" authorization server using the redirect | |||
URI that the client assigned to the attacker's authorization server. The attacke r could then run | URI that the client assigned to the attacker's authorization server. The attacke r could then run | |||
the attack as described above, replacing the | the attack as described above, replacing the | |||
client ID with the client ID of their newly created client.</t> | client ID with the client ID of their newly created client.</t> | |||
<t>This defense SHOULD therefore only be used if other options are not available .</t> | <t>This defense <bcp14>SHOULD</bcp14> therefore only be used if other options ar e not available.</t> | |||
</section> | </section> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="code_injection"><name>Authorization Code Injection</name> | <section anchor="code_injection"><name>Authorization Code Injection</name> | |||
<t>An attacker who has gained access to an authorization code contained in an | <t>An attacker who has gained access to an authorization code contained in an | |||
authorization response (see Attacker A3 in <xref target="secmodel"/>) can try to | authorization response (see <xref target="read_response" | |||
redeem the | format="none">Attacker (A3)</xref> in <xref target="secmodel"/>) can try to rede | |||
em the | ||||
authorization code for an access token or otherwise make use of the | authorization code for an access token or otherwise make use of the | |||
authorization code.</t> | authorization code.</t> | |||
<t>In the case that the authorization code was created for a public client, the | <t>In the case that the authorization code was created for a public client, the | |||
attacker can send the authorization code to the token endpoint of the | attacker can send the authorization code to the token endpoint of the | |||
authorization server and thereby get an access token. This attack was described | authorization server and thereby get an access token. This attack was described | |||
in Section 4.4.1.1 of <xref target="RFC6819"/>.</t> | in <xref target="RFC6819" sectionFormat="of" section="4.4.1.1"/>.</t> | |||
<t>For confidential clients, or in some special situations, the attacker can | <t>For confidential clients, or in some special situations, the attacker can | |||
execute an authorization code injection attack, as described in the following.</ t> | execute an authorization code injection attack, as described in the following.</ t> | |||
<t>In an authorization code injection attack, the attacker attempts to inject a | <t>In an authorization code injection attack, the attacker attempts to inject a | |||
stolen authorization code into the attacker's own session with the client. The | stolen authorization code into the attacker's own session with the client. The | |||
aim is to associate the attacker's session at the client with the victim's | aim is to associate the attacker's session at the client with the victim's | |||
resources or identity, thereby giving the attacker at least limited access to | resources or identity, thereby giving the attacker at least limited access to | |||
the victim's resources.</t> | the victim's resources.</t> | |||
<t>Besides circumventing the client authentication of confidential clients, othe r | <t>Besides circumventing the client authentication of confidential clients, othe r | |||
use cases for this attack include:</t> | use cases for this attack include:</t> | |||
skipping to change at line 962 ¶ | skipping to change at line 996 ¶ | |||
<li>The authorization or resource servers are limited to certain | <li>The authorization or resource servers are limited to certain | |||
networks that the attacker is unable to access directly.</li> | networks that the attacker is unable to access directly.</li> | |||
</ul> | </ul> | |||
<t>Except in these special cases, authorization code injection is usually not | <t>Except in these special cases, authorization code injection is usually not | |||
interesting when the code is created for a public client, as sending the code | interesting when the code is created for a public client, as sending the code | |||
to the token endpoint is a simpler and more powerful attack, as described above. </t> | to the token endpoint is a simpler and more powerful attack, as described above. </t> | |||
<section anchor="attack-description-1"><name>Attack Description</name> | <section anchor="attack-description-1"><name>Attack Description</name> | |||
<t>The authorization code injection attack works as follows:</t> | <t>The authorization code injection attack works as follows:</t> | |||
<ol spacing="compact"> | <ol spacing="compact" type="1"> | |||
<li>The attacker obtains an authorization code (see attacker A3 in <xref target= | <li>The attacker obtains an authorization code (see <xref target="read_response" | |||
"secmodel"/>). For the rest | format="none">Attacker (A3)</xref> in <xref target="secmodel"/>). For the rest | |||
of the attack, only the capabilities of a web attacker (A1) are required.</li> | of the attack, only the capabilities of a web attacker <xref target="web_attacke | |||
<li>From the attacker's device, the attacker starts a regular OAuth authorizatio | rs" format="none">(A1)</xref> are required.</li> | |||
n | <li anchor="step_2_code_injection">From the attacker's device, the attacker star | |||
ts a regular OAuth authorization | ||||
process with the legitimate client.</li> | process with the legitimate client.</li> | |||
<li>In the response of the authorization server to the legitimate client, the | <li anchor="step_3_code_injection">In the response of the authorization server t o the legitimate client, the | |||
attacker replaces the newly created authorization code with the stolen | attacker replaces the newly created authorization code with the stolen | |||
authorization code. Since this response is passing through the attacker's | authorization code. Since this response is passing through the attacker's | |||
device, the attacker can use any tool that can intercept and manipulate the | device, the attacker can use any tool that can intercept and manipulate the | |||
authorization response to this end. The attacker does not need to control | authorization response to this end. The attacker does not need to control | |||
the network.</li> | the network.</li> | |||
<li>The legitimate client sends the code to the authorization server's token | <li>The legitimate client sends the code to the authorization server's token | |||
endpoint, along with the <tt>redirect_uri</tt> and the client's client ID and | endpoint, along with the <tt>redirect_uri</tt> and the client's client ID and | |||
client secret (or other means of client authentication).</li> | client secret (or other means of client authentication).</li> | |||
<li>The authorization server checks the client secret, whether the | <li anchor="checkin">The authorization server checks the client secret, whether the | |||
code was issued to the particular client, and whether the actual | code was issued to the particular client, and whether the actual | |||
redirect URI matches the <tt>redirect_uri</tt> parameter (see | redirection URI matches the <tt>redirect_uri</tt> parameter (see | |||
<xref target="RFC6749"/>).</li> | <xref target="RFC6749"/>).</li> | |||
<li>All checks succeed and the authorization server issues access and | <li>All checks succeed and the authorization server issues access and | |||
other tokens to the client. The attacker has now associated their | other tokens to the client. The attacker has now associated their | |||
session with the legitimate client with the victim's resources | session with the legitimate client with the victim's resources | |||
and/or identity.</li> | and/or identity.</li> | |||
</ol> | </ol> | |||
</section> | </section> | |||
<section anchor="discussion"><name>Discussion</name> | <section anchor="discussion"><name>Discussion</name> | |||
<t>Obviously, the check-in step (5.) will fail if the code was issued to | <t>Obviously, the check-in step (<xref target="checkin" format="none">Step 5</xr ef>) will fail if the code was issued to | |||
another client ID, e.g., a client set up by the attacker. The check | another client ID, e.g., a client set up by the attacker. The check | |||
will also fail if the authorization code was already redeemed by the | will also fail if the authorization code was already redeemed by the | |||
legitimate user and was one-time use only.</t> | legitimate user and was one-time use only.</t> | |||
<t>An attempt to inject a code obtained via a manipulated redirect URI | <t>An attempt to inject a code obtained via a manipulated redirection URI | |||
should also be detected if the authorization server stored the | should also be detected if the authorization server stored the | |||
complete redirect URI used in the authorization request and compares | complete redirection URI used in the authorization request and compares | |||
it with the <tt>redirect_uri</tt> parameter.</t> | it with the <tt>redirect_uri</tt> parameter.</t> | |||
<t><xref target="RFC6749"/>, Section 4.1.3, requires the authorization server to | ||||
"... ensure that the | <t><xref target="RFC6749" sectionFormat="of" section="4.1.3"/> requires the auth | |||
<tt>redirect_uri</tt> parameter is present if the <tt>redirect_uri</tt> paramete | orization server to </t> | |||
r | <blockquote> | |||
was included in the initial authorization request as described in | ensure that the "redirect_uri" parameter is present if the | |||
Section 4.1.1, and if included ensure that their values are | "redirect_uri" parameter was included in the initial authorization | |||
identical.". In the attack scenario described above, the legitimate | request as described in Section <xref target="RFC6749" section="4.1.1" sec | |||
client would use the correct redirect URI it always uses for | tionFormat="bare" />, and if included ensure that | |||
their values are identical. | ||||
</blockquote> | ||||
<t>In the attack scenario described in <xref target="attack-description-1"/>, th | ||||
e legitimate | ||||
client would use the correct redirection URI it always uses for | ||||
authorization requests. But this URI would not match the tampered | authorization requests. But this URI would not match the tampered | |||
redirect URI used by the attacker (otherwise, the redirect would not | redirection URI used by the attacker (otherwise, the redirect would not | |||
land at the attacker's page). So the authorization server would detect | land at the attacker's page). So, the authorization server would detect | |||
the attack and refuse to exchange the code.</t> | the attack and refuse to exchange the code.</t> | |||
<t>This check could also detect attempts to inject an authorization | <t>This check could also detect attempts to inject an authorization | |||
code that had been obtained from another instance of the same client | code that had been obtained from another instance of the same client | |||
on another device if certain conditions are fulfilled:</t> | on another device if certain conditions are fulfilled:</t> | |||
<ul spacing="compact"> | <ul spacing="compact"> | |||
<li>the redirect URI itself needs to contain a nonce or another kind | <li>the redirection URI itself contains a nonce or another kind | |||
of one-time use, secret data and</li> | of one-time use, secret data and</li> | |||
<li>the client has bound this data to this particular instance of the | <li>the client has bound this data to this particular instance of the | |||
client.</li> | client.</li> | |||
</ul> | </ul> | |||
<t>But this approach conflicts with the idea of enforcing exact redirect | <t>But, this approach conflicts with the idea of enforcing exact redirect | |||
URI matching at the authorization endpoint. Moreover, it has been | URI matching at the authorization endpoint. Moreover, it has been | |||
observed that providers very often ignore the <tt>redirect_uri</tt> check | observed that providers very often ignore the <tt>redirect_uri</tt> check | |||
requirement at this stage, maybe because it doesn't seem to be | requirement at this stage, maybe because it doesn't seem to be | |||
security-critical from reading the specification.</t> | security-critical from reading the specification.</t> | |||
<!-- START --> | ||||
<t>Other providers just pattern match the <tt>redirect_uri</tt> parameter | <t>Other providers just pattern match the <tt>redirect_uri</tt> parameter | |||
against the registered redirect URI pattern. This saves the | against the registered redirection URI pattern. This saves the | |||
authorization server from storing the link between the actual redirect | authorization server from storing the link between the actual redirect | |||
URI and the respective authorization code for every transaction. But | URI and the respective authorization code for every transaction. However, | |||
this kind of check obviously does not fulfill the intent of the | this kind of check obviously does not fulfill the intent of the | |||
specification, since the tampered redirect URI is not considered. So | specification, since the tampered redirection URI is not considered. So, | |||
any attempt to inject an authorization code obtained using the | any attempt to inject an authorization code obtained using the | |||
<tt>client_id</tt> of a legitimate client or by utilizing the legitimate | <tt>client_id</tt> of a legitimate client or by utilizing the legitimate | |||
client on another device will not be detected in the respective | client on another device will not be detected in the respective | |||
deployments.</t> | deployments.</t> | |||
<t>It is also assumed that the requirements defined in <xref target="RFC6749"/>, | <t>It is also assumed that the requirements defined in <xref target="RFC6749" se | |||
Section 4.1.3, increase client implementation complexity as clients | ctionFormat="of" section="4.1.3"/> increase client implementation complexity as | |||
need to store or re-construct the correct redirect URI for the call | clients | |||
need to store or reconstruct the correct redirection URI for the call | ||||
to the token endpoint.</t> | to the token endpoint.</t> | |||
<t>Asymmetric methods for client authentication do not stop this attack, as the | <t>Asymmetric methods for client authentication do not stop this attack, as the | |||
legitimate client authenticates at the token endpoint.</t> | legitimate client authenticates at the token endpoint.</t> | |||
<t>This document therefore recommends instead binding every authorization | <t>This document therefore recommends instead binding every authorization | |||
code to a certain client instance on a certain device (or in a certain | code to a certain client instance on a certain device (or in a certain | |||
user agent) in the context of a certain transaction using one of the | user agent) in the context of a certain transaction using one of the | |||
mechanisms described next.</t> | mechanisms described next.</t> | |||
</section> | </section> | |||
<section anchor="countermeasures-1"><name>Countermeasures</name> | <section anchor="countermeasures-1"><name>Countermeasures</name> | |||
<t>There are two good technical solutions to binding authorization codes to clie nt | <t>There are two good technical solutions to binding authorization codes to clie nt | |||
instances, outlined in the following.</t> | instances, as follows.</t> | |||
<section anchor="pkce_as_injection_protection"><name>PKCE</name> | <section anchor="pkce_as_injection_protection"><name>PKCE</name> | |||
<t>The PKCE mechanism specified in <xref target="RFC7636"/> can be used as a cou ntermeasure | <t>The PKCE mechanism specified in <xref target="RFC7636"/> can be used as a cou ntermeasure | |||
(even though it was originally designed to secure native apps). When the | (even though it was originally designed to secure native apps). When the | |||
attacker attempts to inject an authorization code, the check of the | attacker attempts to inject an authorization code, the check of the | |||
<tt>code_verifier</tt> fails: the client uses its correct verifier, but the code is | <tt>code_verifier</tt> fails: the client uses its correct verifier, but the code is | |||
associated with a <tt>code_challenge</tt> that does not match this verifier.</t> | associated with a <tt>code_challenge</tt> that does not match this verifier.</t> | |||
<t>PKCE does not only protect against the authorization code injection attack bu t | <t>PKCE not only protects against the authorization code injection attack but | |||
also protects authorization codes created for public clients: PKCE ensures that | also protects authorization codes created for public clients: PKCE ensures that | |||
an attacker cannot redeem a stolen authorization code at the token endpoint of | an attacker cannot redeem a stolen authorization code at the token endpoint of | |||
the authorization server without knowledge of the <tt>code_verifier</tt>.</t> | the authorization server without knowledge of the <tt>code_verifier</tt>.</t> | |||
</section> | </section> | |||
<section anchor="nonce_as_injection_protection"><name>Nonce</name> | <section anchor="nonce_as_injection_protection"><name>Nonce</name> | |||
<t>OpenID Connect's existing <tt>nonce</tt> parameter can protect against author ization | <t>OpenID Connect's existing <tt>nonce</tt> parameter can protect against author ization | |||
code injection attacks. The <tt>nonce</tt> value is one-time use and is created by the | code injection attacks. The <tt>nonce</tt> value is one-time use and is created by the | |||
client. The client is supposed to bind it to the user agent session and send it | client. The client is supposed to bind it to the user agent session and send it | |||
with the initial request to the OpenID Provider (OP). The OP puts the received < tt>nonce</tt> value into the ID Token that is issued | with the initial request to the OpenID Provider (OP). The OP puts the received < tt>nonce</tt> value into the ID Token that is issued | |||
as part of the code exchange at the token endpoint. If an attacker injects an | as part of the code exchange at the token endpoint. | |||
If an attacker injects an | ||||
authorization code in the authorization response, the nonce value in the client | authorization code in the authorization response, the nonce value in the client | |||
session and the nonce value in the ID token received from the token endpoint wil l not match and the attack is | session and the <tt>nonce</tt> value in the ID Token received from the token end point will not match, and the attack is | |||
detected. The assumption is that an attacker cannot get hold of the user agent | detected. The assumption is that an attacker cannot get hold of the user agent | |||
state on the victim's device (from which the attacker has stolen the respective authorization | state on the victim's device (from which the attacker has stolen the respective authorization | |||
code).</t> | code).</t> | |||
<t>It is important to note that this countermeasure only works if the client | <t>It is important to note that this countermeasure only works if the client | |||
properly checks the <tt>nonce</tt> parameter in the ID Token obtained from the t oken endpoint and does not use any | properly checks the <tt>nonce</tt> parameter in the ID Token obtained from the t oken endpoint and does not use any | |||
issued token until this check has succeeded. More precisely, a client protecting | issued token until this check has succeeded. More precisely, a client protecting | |||
itself against code injection using the <tt>nonce</tt> parameter</t> | itself against code injection using the <tt>nonce</tt> parameter</t> | |||
<ol spacing="compact"> | <ol spacing="compact" type="1"> | |||
<li>MUST validate the <tt>nonce</tt> in the ID Token obtained from the token end | <li><bcp14>MUST</bcp14> validate the <tt>nonce</tt> in the ID Token obtained fro | |||
point, | m the token endpoint, | |||
even if another ID Token was obtained from the authorization response | even if another ID Token was obtained from the authorization response | |||
(e.g., <tt>response_type=code+id_token</tt>), and</li> | (e.g., <tt>response_type=code+id_token</tt>), and</li> | |||
<li>MUST ensure that, unless and until that check succeeds, all tokens (ID | <li><bcp14>MUST</bcp14> ensure that, unless and until that check succeeds, all t okens (ID | |||
Tokens and the access token) are disregarded and not used for any other | Tokens and the access token) are disregarded and not used for any other | |||
purpose.</li> | purpose.</li> | |||
</ol> | </ol> | |||
<t>It is important to note that <tt>nonce</tt> does not protect authorization co des of | <t>It is important to note that <tt>nonce</tt> does not protect authorization co des of | |||
public clients, as an attacker does not need to execute an authorization code | public clients, as an attacker does not need to execute an authorization code | |||
injection attack. Instead, an attacker can directly call the token endpoint with | injection attack. Instead, an attacker can directly call the token endpoint with | |||
the stolen authorization code.</t> | the stolen authorization code.</t> | |||
</section> | </section> | |||
<section anchor="other-solutions"><name>Other Solutions</name> | <section anchor="other-solutions"><name>Other Solutions</name> | |||
<t>Other solutions, like binding <tt>state</tt> to the code, sender-constraining the code | <t>Other solutions like binding <tt>state</tt> to the code, sender-constraining the code | |||
using cryptographic means, or per-instance client credentials are | using cryptographic means, or per-instance client credentials are | |||
conceivable, but lack support and bring new security requirements.</t> | conceivable, but lack support and bring new security requirements.</t> | |||
<t>PKCE is the most obvious solution for OAuth clients as it is available | <t>PKCE is the most obvious solution for OAuth clients, as it is available | |||
today, while <tt>nonce</tt> is | at the time of writing, while <tt>nonce</tt> is | |||
appropriate for OpenID Connect clients.</t> | appropriate for OpenID Connect clients.</t> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="limitations"><name>Limitations</name> | <section anchor="limitations"><name>Limitations</name> | |||
<t>An attacker can circumvent the countermeasures described above if he | <t>An attacker can circumvent the countermeasures described above if they | |||
can modify the <tt>nonce</tt> or <tt>code_challenge</tt> values that are used in the | can modify the <tt>nonce</tt> or <tt>code_challenge</tt> values that are used in the | |||
victim's authorization request. The attacker can modify these values | victim's authorization request. The attacker can modify these values | |||
to be the same ones as those chosen by the client in their own session | to be the same ones as those chosen by the client in their own session | |||
in Step 2 of the attack above. (This requires that the victim's | in <xref target="step_2_code_injection" format="none">Step 2</xref> of the attac k above. (This requires that the victim's | |||
session with the client begins after the attacker started their session | session with the client begins after the attacker started their session | |||
with the client.) If the attacker is then able to capture the | with the client.) If the attacker is then able to capture the | |||
authorization code from the victim, the attacker will be able to | authorization code from the victim, the attacker will be able to | |||
inject the stolen code in Step 3 even if PKCE or <tt>nonce</tt> are used.</t> | inject the stolen code in <xref target="step_3_code_injection" format="none">Ste p 3</xref> even if PKCE or <tt>nonce</tt> are used.</t> | |||
<t>This attack is complex and requires a close interaction between the | <t>This attack is complex and requires a close interaction between the | |||
attacker and the victim's session. Nonetheless, measures to prevent | attacker and the victim's session. Nonetheless, measures to prevent | |||
attackers from reading the contents of the authorization response | attackers from reading the contents of the authorization response | |||
still need to be taken, as described in | still need to be taken, as described in Sections | |||
<xref target="insufficient_uri_validation"/>, <xref target="credential_leakage_r | <xref target="insufficient_uri_validation" format="counter"/>, <xref target="cre | |||
eferrer"/>, | dential_leakage_referrer" format="counter"/>, | |||
<xref target="browser_history"/>, <xref target="mix_up"/>, and <xref target="ope | <xref target="browser_history" format="counter"/>, <xref target="mix_up" format= | |||
n_redirection"/>.</t> | "counter"/>, and <xref target="open_redirection" format="counter"/>.</t> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="access_token_injection"><name>Access Token Injection</name> | <section anchor="access_token_injection"><name>Access Token Injection</name> | |||
<t>In an access token injection attack, the attacker attempts to inject a | <t>In an access token injection attack, the attacker attempts to inject a | |||
stolen access token into a legitimate client (that is not under the | stolen access token into a legitimate client (that is not under the | |||
attacker's control). This will typically happen if the attacker wants | attacker's control). This will typically happen if the attacker wants | |||
to utilize a leaked access token to impersonate a user in a certain | to utilize a leaked access token to impersonate a user in a certain | |||
client.</t> | client.</t> | |||
<t>To conduct the attack, the attacker starts an OAuth flow with the | <t>To conduct the attack, the attacker starts an OAuth flow with the | |||
skipping to change at line 1143 ¶ | skipping to change at line 1185 ¶ | |||
<section anchor="countermeasures-2"><name>Countermeasures</name> | <section anchor="countermeasures-2"><name>Countermeasures</name> | |||
<t>There is no way to detect such an injection attack in pure-OAuth | <t>There is no way to detect such an injection attack in pure-OAuth | |||
flows since the token is issued without any binding to the | flows since the token is issued without any binding to the | |||
transaction or the particular user agent.</t> | transaction or the particular user agent.</t> | |||
<t>In OpenID Connect, the attack can be mitigated, as the authorization response | <t>In OpenID Connect, the attack can be mitigated, as the authorization response | |||
additionally contains an ID Token containing the <tt>at_hash</tt> claim. The att acker | additionally contains an ID Token containing the <tt>at_hash</tt> claim. The att acker | |||
therefore needs to replace both the access token as well as the ID Token in the | therefore needs to replace both the access token as well as the ID Token in the | |||
response. The attacker cannot forge the ID Token, as it is signed or encrypted | response. The attacker cannot forge the ID Token, as it is signed or encrypted | |||
with authentication. The attacker also cannot inject a leaked ID Token matching | with authentication. The attacker also cannot inject a leaked ID Token matching | |||
the stolen access token, as the <tt>nonce</tt> claim in the leaked ID Token will | the stolen access token, as the <tt>nonce</tt> claim in the leaked ID Token will | |||
(with a very high probability) contain a different value than the one expected | contain (with a very high probability) a different value than the one expected | |||
in the authorization response.</t> | in the authorization response.</t> | |||
<t>Note that further protection, like sender-constrained access tokens, is still | <t>Note that further protection, like sender-constrained access tokens, is still | |||
required to prevent attackers from using the access token at the resource | required to prevent attackers from using the access token at the resource | |||
endpoint directly.</t> | endpoint directly.</t> | |||
<t>The recommendations in <xref target="implicit_grant_recommendation"/> follow from this.</t> | <t>The recommendations in <xref target="implicit_grant_recommendation"/> follow from this.</t> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="csrf"><name>Cross-Site Request Forgery</name> | <section anchor="csrf"><name>Cross-Site Request Forgery</name> | |||
<t>An attacker might attempt to inject a request to the redirect URI of | <t>An attacker might attempt to inject a request to the redirection URI of | |||
the legitimate client on the victim's device, e.g., to cause the | the legitimate client on the victim's device, e.g., to cause the | |||
client to access resources under the attacker's control. This is a | client to access resources under the attacker's control. This is a | |||
variant of an attack known as Cross-Site Request Forgery (CSRF).</t> | variant of an attack known as Cross-Site Request Forgery (CSRF).</t> | |||
<section anchor="csrf_countermeasures"><name>Countermeasures</name> | <section anchor="csrf_countermeasures"><name>Countermeasures</name> | |||
<t>The long-established countermeasure is that clients pass a random value, also | <t>The long-established countermeasure is that clients pass a random value, also | |||
known as a CSRF Token, in the <tt>state</tt> parameter that links the request to | known as a CSRF Token, in the <tt>state</tt> parameter that links the request to | |||
the redirect URI to the user agent session as described. This | the redirection URI to the user agent session as described. This | |||
countermeasure is described in detail in <xref target="RFC6819"/>, Section 5.3.5 | countermeasure is described in detail in <xref target="RFC6819" sectionFormat="o | |||
. The | f" section="5.3.5"/>. The | |||
same protection is provided by PKCE or the OpenID Connect <tt>nonce</tt> value.< /t> | same protection is provided by PKCE or the OpenID Connect <tt>nonce</tt> value.< /t> | |||
<t>When using PKCE instead of <tt>state</tt> or <tt>nonce</tt> for CSRF protecti on, it is | <t>When using PKCE instead of <tt>state</tt> or <tt>nonce</tt> for CSRF protecti on, it is | |||
important to note that:</t> | important to note that:</t> | |||
<ul> | <ul> | |||
<li><t>Clients MUST ensure that the authorization server supports PKCE before us ing PKCE for | <li><t>Clients <bcp14>MUST</bcp14> ensure that the authorization server supports PKCE before using PKCE for | |||
CSRF protection. If an authorization server does not support PKCE, | CSRF protection. If an authorization server does not support PKCE, | |||
<tt>state</tt> or <tt>nonce</tt> MUST be used for CSRF protection.</t> | <tt>state</tt> or <tt>nonce</tt> <bcp14>MUST</bcp14> be used for CSRF protection .</t> | |||
</li> | </li> | |||
<li><t>If <tt>state</tt> is used for carrying application state, and the integri ty of | <li><t>If <tt>state</tt> is used for carrying application state, and the integri ty of | |||
its contents is a concern, clients MUST protect <tt>state</tt> against | its contents is a concern, clients <bcp14>MUST</bcp14> protect <tt>state</tt> ag ainst | |||
tampering and swapping. This can be achieved by binding the | tampering and swapping. This can be achieved by binding the | |||
contents of state to the browser session and/or signed/encrypted | contents of state to the browser session and/or by signing/encrypting | |||
state values. One example of this is discussed in the now-expired draft <xref ta | state values. One example of this is discussed in the expired Internet-Draft <xr | |||
rget="I-D.bradley-oauth-jwt-encoded-state"/>.</t> | ef target="I-D.bradley-oauth-jwt-encoded-state"/>.</t> | |||
</li> | </li> | |||
</ul> | </ul> | |||
<t>The authorization server therefore MUST provide a way to detect their support for PKCE. Using Authorization Server Metadata according to <xref target="RFC841 4"/> is RECOMMENDED, but authorization servers MAY instead provide a | <t>The authorization server therefore <bcp14>MUST</bcp14> provide a way to detec t their support for PKCE. Using Authorization Server Metadata according to <xref target="RFC8414"/> is <bcp14>RECOMMENDED</bcp14>, but authorization servers <bc p14>MAY</bcp14> instead provide a | |||
deployment-specific way to ensure or determine PKCE support.</t> | deployment-specific way to ensure or determine PKCE support.</t> | |||
<t>PKCE provides robust protection against CSRF attacks even in presence of an a | <t>PKCE provides robust protection against CSRF attacks even in the presence of | |||
ttacker that | an attacker that | |||
can read the authorization response (see Attacker A3 in <xref target="secmodel"/ | can read the authorization response (see <xref target="read_response" | |||
>). When | format="none">Attacker (A3)</xref> in <xref target="secmodel"/>). When | |||
<tt>state</tt> is used or an ID Token is returned in the authorization response (e.g., | <tt>state</tt> is used or an ID Token is returned in the authorization response (e.g., | |||
<tt>response_type=code+id_token</tt>), the attacker either learns the <tt>state< /tt> value and | <tt>response_type=code+id_token</tt>), the attacker either learns the <tt>state< /tt> value and | |||
can replay it into the forged authorization response, or can extract the <tt>non ce</tt> | can replay it into the forged authorization response, or can extract the <tt>non ce</tt> | |||
from the ID Token and use it in a new request to the authorization server to | from the ID Token and use it in a new request to the authorization server to | |||
mint an ID Token with the same <tt>nonce</tt>. The new ID Token can then be used for | mint an ID Token with the same <tt>nonce</tt>. The new ID Token can then be used for | |||
the CSRF attack.</t> | the CSRF attack.</t> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="pkce-downgrade-attack"><name>PKCE Downgrade Attack</name> | <section anchor="pkce-downgrade-attack"><name>PKCE Downgrade Attack</name> | |||
<t>An authorization server that supports PKCE but does not make its use mandator y for | <t>An authorization server that supports PKCE but does not make its use mandator y for | |||
all flows can be susceptible to a PKCE downgrade attack.</t> | all flows can be susceptible to a PKCE downgrade attack.</t> | |||
<t>The first prerequisite for this attack is that there is an attacker-controlla ble | <t>The first prerequisite for this attack is that there is an attacker-controlla ble | |||
flag in the authorization request that enables or disables PKCE for the | flag in the authorization request that enables or disables PKCE for the | |||
particular flow. The presence or absence of the <tt>code_challenge</tt> paramete r lends | particular flow. The presence or absence of the <tt>code_challenge</tt> paramete r lends | |||
itself for this purpose, i.e., the authorization server enables and enforces PKC E if this | itself for this purpose, i.e., the authorization server enables and enforces PKC E if this | |||
parameter is present in the authorization request, but does not enforce PKCE if | parameter is present in the authorization request, but it does not enforce PKCE if | |||
the parameter is missing.</t> | the parameter is missing.</t> | |||
<t>The second prerequisite for this attack is that the client is not using <tt>s tate</tt> | <t>The second prerequisite for this attack is that the client is not using <tt>s tate</tt> | |||
at all (e.g., because the client relies on PKCE for CSRF prevention) or that the | at all (e.g., because the client relies on PKCE for CSRF prevention) or that the | |||
client is not checking <tt>state</tt> correctly.</t> | client is not checking <tt>state</tt> correctly.</t> | |||
<t>Roughly speaking, this attack is a variant of a CSRF attack. The attacker | <t>Roughly speaking, this attack is a variant of a CSRF attack. The attacker | |||
achieves the same goal as in the attack described in <xref target="csrf"/>: The attacker injects an | achieves the same goal as in the attack described in <xref target="csrf"/>: The attacker injects an | |||
authorization code (and with that, an access token) that is bound to the attacke r's | authorization code (and with that, an access token) that is bound to the attacke r's | |||
resources into a session between their victim and the client.</t> | resources into a session between their victim and the client.</t> | |||
<section anchor="attack-description-2"><name>Attack Description</name> | <section anchor="attack-description-2"><name>Attack Description</name> | |||
<ol spacing="compact"> | <ol spacing="compact" type="1"> | |||
<li>The user has started an OAuth session using some client at an authorization server. In the | <li>The user has started an OAuth session using some client at an authorization server. In the | |||
authorization request, the client has set the parameter | authorization request, the client has set the parameter | |||
<tt>code_challenge=hash(abc)</tt> as the PKCE code challenge (with the hash func tion and parameter encoding as defined in <xref target="RFC7636"/>). The client is now | <tt>code_challenge=hash(abc)</tt> as the PKCE code challenge (with the hash func tion and parameter encoding as defined in <xref target="RFC7636"/>). The client is now | |||
waiting to receive the authorization response from the user's browser.</li> | waiting to receive the authorization response from the user's browser.</li> | |||
<li>To conduct the attack, the attacker uses their own device to start an | <li>To conduct the attack, the attacker uses their own device to start an | |||
authorization flow with the targeted client. The client now uses another | authorization flow with the targeted client. The client now uses another | |||
PKCE code challenge, say <tt>code_challenge=hash(xyz)</tt>, in the authorization | PKCE code challenge, say, <tt>code_challenge=hash(xyz)</tt>, in the authorizatio n | |||
request. The attacker intercepts the request and removes the entire | request. The attacker intercepts the request and removes the entire | |||
<tt>code_challenge</tt> parameter from the request. Since this step is performed on | <tt>code_challenge</tt> parameter from the request. Since this step is performed on | |||
the attacker's device, the attacker has full access to the request contents, | the attacker's device, the attacker has full access to the request contents, | |||
for example using browser debug tools.</li> | for example, using browser debug tools.</li> | |||
<li>If the authorization server allows for flows without PKCE, it will create a | <li>If the authorization server allows for flows without PKCE, it will create a | |||
code that is not bound to any PKCE code challenge.</li> | code that is not bound to any PKCE code challenge.</li> | |||
<li>The attacker now redirects the user's browser to an authorization response | <li>The attacker now redirects the user's browser to an authorization response | |||
URL that contains the code for the attacker's session with the authorization ser ver.</li> | URL that contains the code for the attacker's session with the authorization ser ver.</li> | |||
<li>The user's browser sends the authorization code to the client, which will | <li>The user's browser sends the authorization code to the client, which will | |||
now try to redeem the code for an access token at the authorization server. The client will | now try to redeem the code for an access token at the authorization server. The client will | |||
send <tt>code_verifier=abc</tt> as the PKCE code verifier in the token request.< /li> | send <tt>code_verifier=abc</tt> as the PKCE code verifier in the token request.< /li> | |||
<li>Since the authorization server sees that this code is not bound to any PKCE | <li>Since the authorization server sees that this code is not bound to any PKCE | |||
code challenge, it will not check the presence or contents of the | code challenge, it will not check the presence or contents of the | |||
<tt>code_verifier</tt> parameter. It will issue an access token that belongs to | <tt>code_verifier</tt> parameter. It will issue an access token (which belongs t | |||
the | o the | |||
attacker's resource to the client under the user's control.</li> | attacker's resource) to the client under the user's control.</li> | |||
</ol> | </ol> | |||
</section> | </section> | |||
<section anchor="pkce_downgrade_countermeasures"><name>Countermeasures</name> | <section anchor="pkce_downgrade_countermeasures"><name>Countermeasures</name> | |||
<t>Using <tt>state</tt> properly would prevent this attack. However, practice ha s shown | <t>Using <tt>state</tt> properly would prevent this attack. However, practice ha s shown | |||
that many OAuth clients do not use or check <tt>state</tt> properly.</t> | that many OAuth clients do not use or check <tt>state</tt> properly.</t> | |||
<t>Therefore, authorization servers MUST mitigate this attack.</t> | <t>Therefore, authorization servers <bcp14>MUST</bcp14> mitigate this attack.</t > | |||
<t>Note that from the view of the authorization server, in the attack described above, a | <t>Note that from the view of the authorization server, in the attack described above, a | |||
<tt>code_verifier</tt> parameter is received at the token endpoint although no | <tt>code_verifier</tt> parameter is received at the token endpoint although no | |||
<tt>code_challenge</tt> parameter was present in the authorization request for t he | <tt>code_challenge</tt> parameter was present in the authorization request for t he | |||
OAuth flow in which the authorization code was issued.</t> | OAuth flow in which the authorization code was issued.</t> | |||
<t>This fact can be used to mitigate this attack. <xref target="RFC7636"/> alrea dy mandates that</t> | <t>This fact can be used to mitigate this attack. <xref target="RFC7636"/> alrea dy mandates that</t> | |||
<ul spacing="compact"> | <ul spacing="compact"> | |||
<li>an authorization server that supports PKCE MUST check whether a code challen ge is contained in | <li>an authorization server that supports PKCE <bcp14>MUST</bcp14> check whether a code challenge is contained in | |||
the authorization request and bind this information to the code that is | the authorization request and bind this information to the code that is | |||
issued; and</li> | issued; and</li> | |||
<li>when a code arrives at the token endpoint, and there was a <tt>code_challeng e</tt> | <li>when a code arrives at the token endpoint, and there was a <tt>code_challeng e</tt> | |||
in the authorization request for which this code was issued, there must be a | in the authorization request for which this code was issued, there must be a | |||
valid <tt>code_verifier</tt> in the token request.</li> | valid <tt>code_verifier</tt> in the token request.</li> | |||
</ul> | </ul> | |||
<t>Beyond this, to prevent PKCE downgrade attacks, the authorization server MUST ensure that | <t>Beyond this, to prevent PKCE downgrade attacks, the authorization server <bcp 14>MUST</bcp14> ensure that | |||
if there was no <tt>code_challenge</tt> in the authorization request, a request to | if there was no <tt>code_challenge</tt> in the authorization request, a request to | |||
the token endpoint containing a <tt>code_verifier</tt> is rejected.</t> | the token endpoint containing a <tt>code_verifier</tt> is rejected.</t> | |||
<t>Authorization servers that mandate the use of PKCE in general or for particul ar clients | <t>Authorization servers that mandate the use of PKCE (in general or for particu lar clients) | |||
implicitly implement this security measure.</t> | implicitly implement this security measure.</t> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="access_token_leakage"><name>Access Token Leakage at the Resourc e Server</name> | <section anchor="access_token_leakage"><name>Access Token Leakage at the Resourc e Server</name> | |||
<t>Access tokens can leak from a resource server under certain | <t>Access tokens can leak from a resource server under certain | |||
circumstances.</t> | circumstances.</t> | |||
<section anchor="counterfeit_res_server"><name>Access Token Phishing by Counterf eit Resource Server</name> | <section anchor="counterfeit_res_server"><name>Access Token Phishing by Counterf eit Resource Server</name> | |||
<t>An attacker may set up their own resource server and trick a client into | <t>An attacker may set up their own resource server and trick a client into | |||
sending access tokens to it that are valid for other resource servers | sending access tokens to it that are valid for other resource servers | |||
(see Attackers A1 and A5 in <xref target="secmodel"/>). If the client sends a va lid access token to | (see Attackers <xref target="web_attackers" format="none">(A1)</xref> and <xref target="acquire_token" format="none">(A5)</xref> in <xref target="secmodel"/>). If the client sends a valid access token to | |||
this counterfeit resource server, the attacker in turn may use that | this counterfeit resource server, the attacker in turn may use that | |||
token to access other services on behalf of the resource owner.</t> | token to access other services on behalf of the resource owner.</t> | |||
<t>This attack assumes the client is not bound to one specific resource | <t>This attack assumes the client is not bound to one specific resource | |||
server (and its URL) at development time, but client instances are | server (and its URL) at development time, but client instances are | |||
provided with the resource server URL at runtime. This kind of late | provided with the resource server URL at runtime. | |||
This kind of late | ||||
binding is typical in situations where the client uses a service | binding is typical in situations where the client uses a service | |||
implementing a standardized API (e.g., for e-mail, calendar, health, | implementing a standardized API (e.g., for email, calendaring, eHealth, | |||
or banking) and where the client is configured by a user or | or open banking) and where the client is configured by a user or | |||
administrator for a service that this user or company uses.</t> | administrator.</t> | |||
</section> | </section> | |||
<section anchor="comp_res_server"><name>Compromised Resource Server</name> | <section anchor="comp_res_server"><name>Compromised Resource Server</name> | |||
<t>An attacker may compromise a resource server to gain access to the | <t>An attacker may compromise a resource server to gain access to the | |||
resources of the respective deployment. Such a compromise may range | resources of the respective deployment. Such a compromise may range | |||
from partial access to the system, e.g., its log files, to full | from partial access to the system, e.g., its log files, to full | |||
control over the respective server, in which case all controls can be | control over the respective server, in which case all controls can be | |||
circumvented and all resources can be | circumvented and all resources can be | |||
accessed. The attacker would also be able to obtain other access | accessed. The attacker would also be able to obtain other access | |||
tokens held on the compromised system that would potentially be valid | tokens held on the compromised system that would potentially be valid | |||
to access other resource servers.</t> | to access other resource servers.</t> | |||
<t>Preventing server breaches by hardening and monitoring server systems | <t>Preventing server breaches by hardening and monitoring server systems | |||
is considered a standard operational procedure and, therefore, out of | is considered a standard operational procedure and, therefore, out of | |||
the scope of this document. This section focuses on the impact of | the scope of this document. | |||
<xref target="access_token_leakage"/> focuses on the impact of | ||||
OAuth-related breaches and the replaying of captured access tokens.</t> | OAuth-related breaches and the replaying of captured access tokens.</t> | |||
</section> | </section> | |||
<section anchor="countermeasures-3"><name>Countermeasures</name> | <section anchor="countermeasures-3"><name>Countermeasures</name> | |||
<t>The following measures should be taken into account by implementers in | <t>The following measures should be taken into account by implementers in | |||
order to cope with access token replay by malicious actors:</t> | order to cope with access token replay by malicious actors:</t> | |||
<ul spacing="compact"> | <ul spacing="compact"> | |||
<li>Sender-constrained access tokens, as described in <xref target="pop_tokens"/ >, | <li>Sender-constrained access tokens, as described in <xref target="pop_tokens"/ >, | |||
SHOULD be used to prevent the attacker from replaying the access | <bcp14>SHOULD</bcp14> be used to prevent the attacker from replaying the access | |||
tokens on other resource servers. If an attacker has only partial | tokens on other resource servers. If an attacker has only partial | |||
access to the compromised system, like a read-only access to web | access to the compromised system, like a read-only access to web | |||
server logs, sender-constrained access tokens may also prevent | server logs, sender-constrained access tokens may also prevent | |||
replay on the compromised system.</li> | replay on the compromised system.</li> | |||
<li>Audience restriction as described in <xref target="aud_restriction"/> SHOULD be | <li>Audience restriction as described in <xref target="aud_restriction"/> <bcp14 >SHOULD</bcp14> be | |||
used to prevent replay of captured access tokens on other resource | used to prevent replay of captured access tokens on other resource | |||
servers.</li> | servers.</li> | |||
<li>The resource server MUST treat access tokens like other sensitive secrets | ||||
and not store or transfer them in plain text.</li> | <li>The resource server <bcp14>MUST</bcp14> treat access tokens like other sensi | |||
tive secrets | ||||
and not store or transfer them in plaintext.</li> | ||||
</ul> | </ul> | |||
<t>The first and second recommendations also apply to other scenarios | <t>The first and second recommendations also apply to other scenarios | |||
where access tokens leak (see Attacker A5 in <xref target="secmodel"/>).</t> | where access tokens leak (see <xref target="acquire_token" format="none">Attacke r (A5)</xref> in <xref target="secmodel"/>).</t> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="misuse-of-stolen-access-tokens"><name>Misuse of Stolen Access T okens</name> | <section anchor="misuse-of-stolen-access-tokens"><name>Misuse of Stolen Access T okens</name> | |||
<t>Access tokens can be stolen by an attacker in various ways, for example, | <t>Access tokens can be stolen by an attacker in various ways, for example, | |||
via the attacks described in <xref target="insufficient_uri_validation"/>, | via the attacks described in Sections <xref target="insufficient_uri_validation" | |||
<xref target="credential_leakage_referrer"/>, <xref target="browser_history"/>, | format="counter"/>, | |||
<xref target="mix_up"/> and | <xref target="credential_leakage_referrer" format="counter"/>, <xref target="bro | |||
<xref target="access_token_leakage"/>. Some of these attacks can be mitigated by | wser_history" format="counter"/>, <xref target="mix_up" format="counter"/>, and | |||
<xref target="access_token_leakage" format="counter"/>. Some of these attacks ca | ||||
n be mitigated by | ||||
specific security measures, as described in the respective sections. | specific security measures, as described in the respective sections. | |||
However, in some cases, these measures are not sufficient or are not | However, in some cases, these measures are not sufficient or are not | |||
implemented correctly. Authorization servers therefore SHOULD ensure that | implemented correctly. Authorization servers therefore <bcp14>SHOULD</bcp14> ens ure that | |||
access tokens are sender-constrained and audience-restricted as described | access tokens are sender-constrained and audience-restricted as described | |||
in the following. Architecture and performance reasons may | in the following. Architecture and performance reasons may | |||
prevent the use of these measures in some deployments.</t> | prevent the use of these measures in some deployments.</t> | |||
<section anchor="pop_tokens"><name>Sender-Constrained Access Tokens</name> | <section anchor="pop_tokens"><name>Sender-Constrained Access Tokens</name> | |||
<t>As the name suggests, sender-constrained access tokens scope the | <t>As the name suggests, sender-constrained access tokens scope the | |||
applicability of an access token to a certain sender. This sender is | applicability of an access token to a certain sender. This sender is | |||
obliged to demonstrate knowledge of a certain secret as a prerequisite | obliged to demonstrate knowledge of a certain secret as a prerequisite | |||
for the acceptance of that token at a resource server.</t> | for the acceptance of that token at a resource server.</t> | |||
<t>A typical flow looks like this:</t> | <t>A typical flow looks like this:</t> | |||
<ol spacing="compact"> | <ol spacing="compact"> | |||
<li>The authorization server associates data with the access token | <li>The authorization server associates data with the access token | |||
that binds this particular token to a certain client. The binding | that binds this particular token to a certain client. The binding | |||
can utilize the client's identity, but in most cases, the authorization server u tilizes | can utilize the client's identity, but in most cases, the authorization server u tilizes | |||
key material (or data derived from the key material) known to the | key material (or data derived from the key material) known to the | |||
client.</li> | client.</li> | |||
<li>This key material must be distributed somehow. Either the key | <li>This key material must be distributed somehow. Either the key | |||
material already exists before the authorization server creates the binding or t he | material already exists before the authorization server creates the binding or t he | |||
authorization server creates ephemeral keys. The way pre-existing key material i s | authorization server creates ephemeral keys. The way preexisting key material is | |||
distributed varies among the different approaches. For example, | distributed varies among the different approaches. For example, | |||
X.509 Certificates can be used, in which case the distribution | X.509 certificates can be used, in which case the distribution | |||
happens explicitly during the enrollment process. Or the key | happens explicitly during the enrollment process. Or, the key | |||
material is created and distributed at the TLS layer, in which | material is created and distributed at the TLS layer, in which | |||
case it might automatically happen during the setup of a TLS | case it might automatically happen during the setup of a TLS | |||
connection.</li> | connection.</li> | |||
<li>The resource server must implement the actual proof of possession check. Thi s | <li>The resource server must implement the actual proof-of-possession check. Thi s | |||
is typically done on the application level, often tied to specific | is typically done on the application level, often tied to specific | |||
material provided by transport layer (e.g., TLS). The resource server must also | material provided by the transport layer (e.g., TLS). The resource server must a lso | |||
ensure that a replay of the proof of possession is not possible.</li> | ensure that a replay of the proof of possession is not possible.</li> | |||
</ol> | </ol> | |||
<t>Two methods for sender-constrained access tokens using proof-of-possession ha ve | <t>Two methods for sender-constrained access tokens using proof of possession ha ve | |||
been defined by the OAuth working group and are in use in practice:</t> | been defined by the OAuth working group and are in use in practice:</t> | |||
<ul spacing="compact"> | <ul spacing="compact"> | |||
<li>OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound | <li>"OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound | |||
Access Tokens (<xref target="RFC8705"/>): The approach specified in this | Access Tokens" <xref target="RFC8705"/>: The approach specified in this) | |||
document allows the use of mutual TLS (mTLS) for both client | document allows the use of mutual TLS for both client | |||
authentication and sender-constrained access tokens. For the | authentication and sender-constrained access tokens. For the | |||
purpose of sender-constrained access tokens, the client is | purpose of sender-constrained access tokens, the client is | |||
identified towards the resource server by the fingerprint of its | identified towards the resource server by the fingerprint of its | |||
public key. During the processing of an access token request, the | public key. During the processing of an access token request, the | |||
authorization server obtains the client's public key from the TLS | authorization server obtains the client's public key from the TLS | |||
stack and associates its fingerprint with the respective access | stack and associates its fingerprint with the respective access | |||
tokens. The resource server in the same way obtains the public key | tokens. The resource server in the same way obtains the public key | |||
from the TLS stack and compares its fingerprint with the | from the TLS stack and compares its fingerprint with the | |||
fingerprint associated with the access token.</li> | fingerprint associated with the access token.</li> | |||
<li>OAuth 2.0 Demonstrating Proof of Possession (DPoP) (<xref target="RFC9449"/> | <li>"OAuth 2.0 Demonstrating Proof of Possession (DPoP)" <xref target="RFC9449"/ | |||
): | >: | |||
DPoP outlines an | DPoP outlines an | |||
application-level sender-constraining for access and refresh | application-level mechanism for sender-constraining access and refresh | |||
tokens. It uses | tokens. It uses | |||
proof-of-possession based on a public/private key pair and | proof-of-possession based on a public/private key pair and | |||
application-level signing. DPoP can be used with public clients | application-level signing. DPoP can be used with public clients | |||
and, in the case of confidential clients, can be combined with any | and, in the case of confidential clients, can be combined with any | |||
client authentication method.</li> | client authentication method.</li> | |||
</ul> | </ul> | |||
<t>Note that the security of sender-constrained tokens is undermined when | <t>Note that the security of sender-constrained tokens is undermined when | |||
an attacker gets access to the token and the key material. This is, in | an attacker gets access to the token and the key material. This is, in | |||
particular, the case for corrupted client software and cross-site | particular, the case for corrupted client software and cross-site | |||
scripting attacks (when the client is running in the browser). If the | scripting attacks (when the client is running in the browser). If the | |||
skipping to change at line 1398 ¶ | skipping to change at line 1447 ¶ | |||
only indirectly accessible (like in a TLS stack), sender-constrained | only indirectly accessible (like in a TLS stack), sender-constrained | |||
tokens at least protect against the use of the token when the client is | tokens at least protect against the use of the token when the client is | |||
offline, i.e., when the security module or interface is not available | offline, i.e., when the security module or interface is not available | |||
to the attacker. This applies to access tokens as well as to refresh | to the attacker. This applies to access tokens as well as to refresh | |||
tokens (see <xref target="refresh_token_protection"/>).</t> | tokens (see <xref target="refresh_token_protection"/>).</t> | |||
</section> | </section> | |||
<section anchor="aud_restriction"><name>Audience-Restricted Access Tokens</name> | <section anchor="aud_restriction"><name>Audience-Restricted Access Tokens</name> | |||
<t>Audience restriction essentially restricts access tokens to a | <t>Audience restriction essentially restricts access tokens to a | |||
particular resource server. The authorization server associates the | particular resource server. The authorization server associates the | |||
access token with the particular resource server and the resource | access token with the particular resource server, and the resource | |||
server is then supposed to verify the intended audience. If the access token fai ls | server is then supposed to verify the intended audience. If the access token fai ls | |||
the intended audience validation, the resource server refuses to | the intended audience validation, the resource server refuses to | |||
serve the respective request.</t> | serve the respective request.</t> | |||
<t>In general, audience restriction limits the impact of token leakage. | <t>In general, audience restriction limits the impact of token leakage. | |||
In the case of a counterfeit resource server, it may (as described | In the case of a counterfeit resource server, it may (as described | |||
below) also prevent abuse of the phished access token at the | below) also prevent abuse of the phished access token at the | |||
legitimate resource server.</t> | legitimate resource server.</t> | |||
<t>The audience can be expressed using logical names or | <t>The audience can be expressed using logical names or | |||
physical addresses (like URLs). To prevent phishing, it is | physical addresses (like URLs). To prevent phishing, it is | |||
necessary to use the actual URL the client will send requests to. In | necessary to use the actual URL the client will send requests to. In | |||
the phishing case, this URL will point to the counterfeit resource | the phishing case, this URL will point to the counterfeit resource | |||
server. If the attacker tries to use the access token at the | server. If the attacker tries to use the access token at the | |||
legitimate resource server (which has a different URL), the resource | legitimate resource server (which has a different URL), the resource | |||
server will detect the mismatch (wrong audience) and refuse to serve | server will detect the mismatch (wrong audience) and refuse to serve | |||
the request.</t> | the request.</t> | |||
<t>In deployments where the authorization server knows the URLs of all | <t>In deployments where the authorization server knows the URLs of all | |||
resource servers, the authorization server may just refuse to issue | resource servers, the authorization server may just refuse to issue | |||
access tokens for unknown resource server URLs.</t> | access tokens for unknown resource server URLs.</t> | |||
<t>For this to work, the client needs to tell the authorization server the inten ded | <t>For this to work, the client needs to tell the authorization server the inten ded | |||
resource server. The mechanism in <xref target="RFC8707"/> can be used for this or the | resource server. The mechanism in <xref target="RFC8707"/> can be used for this or the | |||
information can be encoded in the scope value (Section 3.3 of <xref target="RFC6 749"/>).</t> | information can be encoded in the scope value (<xref target="RFC6749" sectionFor mat="of" section="3.3"/>).</t> | |||
<t>Instead of the URL, it is also possible to utilize the fingerprint of | <t>Instead of the URL, it is also possible to utilize the fingerprint of | |||
the resource server's X.509 certificate as the audience value. This | the resource server's X.509 certificate as the audience value. This | |||
variant would also allow detection of an attempt to spoof the legitimate | variant would also allow detection of an attempt to spoof the legitimate | |||
resource server's URL by using a valid TLS certificate obtained from a | resource server's URL by using a valid TLS certificate obtained from a | |||
different CA. It might also be considered a privacy benefit to hide | different CA. It might also be considered a privacy benefit to hide | |||
the resource server URL from the authorization server.</t> | the resource server URL from the authorization server.</t> | |||
<t>Audience restriction may seem easier to use since it does not require | <t>Audience restriction may seem easier to use since it does not require | |||
any cryptography on the client side. Still, since every access token is | any cryptography on the client side. Still, since every access token is | |||
bound to a specific resource server, the client also needs to obtain a | bound to a specific resource server, the client also needs to obtain a | |||
single resource server-specific access token when accessing several resource | single resource server-specific access token when accessing several resource | |||
servers. (Resource indicators, as specified in | servers. (Resource indicators, as specified in | |||
<xref target="RFC8707"/>, can help to achieve this.) | <xref target="RFC8707"/>, can help to achieve this.) | |||
<xref target="I-D.ietf-oauth-token-binding"/> had the same property since differ ent | <xref target="I-D.ietf-oauth-token-binding"/> had the same property since differ ent | |||
token-binding IDs must be associated with the access token. Using | token-binding IDs must be associated with the access token. Using | |||
<xref target="RFC8705"/>, on the other hand, allows a client to use the | mutual TLS for OAuth 2.0 <xref target="RFC8705"/>, on the other hand, allows a c lient to use the | |||
access token at multiple resource servers.</t> | access token at multiple resource servers.</t> | |||
<t>It should be noted that audience restrictions, or generally speaking an | <t>It should be noted that audience restrictions -- or, generally speaking, an | |||
indication by the client to the authorization server where it wants to | indication by the client to the authorization server where it wants to | |||
use the access token, have additional benefits beyond the scope of | use the access token -- have additional benefits beyond the scope of | |||
token leakage prevention. It allows the authorization server to create | token leakage prevention. They allow the authorization server to create | |||
a different access token whose format and content are specifically minted | a different access token whose format and content are specifically minted | |||
for the respective server. This has huge functional and privacy | for the respective server. This has huge functional and privacy | |||
advantages in deployments using structured access tokens.</t> | advantages in deployments using structured access tokens.</t> | |||
</section> | </section> | |||
<section anchor="discussion-preventing-leakage-via-metadata"><name>Discussion: P reventing Leakage via Metadata</name> | <section anchor="discussion-preventing-leakage-via-metadata"><name>Discussion: P reventing Leakage via Metadata</name> | |||
<t>An authorization server could provide the client with additional | <t>An authorization server could provide the client with additional | |||
information about the locations where it is safe to use its access | information about the locations where it is safe to use its access | |||
tokens. This approach, and why it is not recommended, is discussed in | tokens. This approach, and why it is not recommended, is discussed in | |||
the following.</t> | the following.</t> | |||
<t>In the simplest form, this would require the authorization server to publish a list of | <t>In the simplest form, this would require the authorization server to publish a list of | |||
its known resource servers, illustrated in the following example using | its known resource servers, illustrated in the following example using | |||
a non-standard Authorization Server Metadata parameter <tt>resource_servers</tt> :</t> | a non-standard Authorization Server Metadata parameter <tt>resource_servers</tt> :</t> | |||
<artwork><![CDATA[HTTP/1.1 200 OK | <sourcecode type="http-message"><![CDATA[ | |||
HTTP/1.1 200 OK | ||||
Content-Type: application/json | Content-Type: application/json | |||
{ | { | |||
"issuer":"https://server.somesite.example", | "issuer":"https://server.somesite.example", | |||
"authorization_endpoint": | "authorization_endpoint": | |||
"https://server.somesite.example/authorize", | "https://server.somesite.example/authorize", | |||
"resource_servers":[ | "resource_servers":[ | |||
"email.somesite.example", | "email.somesite.example", | |||
"storage.somesite.example", | "storage.somesite.example", | |||
"video.somesite.example" | "video.somesite.example" | |||
] | ] | |||
... | ... | |||
} | } | |||
]]> | ]]></sourcecode> | |||
</artwork> | ||||
<t>The authorization server could also return the URL(s) an access token is good for in the | <t>The authorization server could also return the URL(s) an access token is good for in the | |||
token response, illustrated by the example and non-standard return | token response, illustrated by the example and non-standard return | |||
parameter <tt>access_token_resource_server</tt>:</t> | parameter <tt>access_token_resource_server</tt>:</t> | |||
<artwork><![CDATA[HTTP/1.1 200 OK | <sourcecode type="http-message"><![CDATA[ | |||
HTTP/1.1 200 OK | ||||
Content-Type: application/json;charset=UTF-8 | Content-Type: application/json;charset=UTF-8 | |||
Cache-Control: no-store | Cache-Control: no-store | |||
Pragma: no-cache | Pragma: no-cache | |||
{ | { | |||
"access_token":"2YotnFZFEjr1zCsicMWpAA", | "access_token":"2YotnFZFEjr1zCsicMWpAA", | |||
"access_token_resource_server": | "access_token_resource_server": | |||
"https://hostedresource.somesite.example/path1", | "https://hostedresource.somesite.example/path1", | |||
... | ... | |||
} | } | |||
]]> | ]]></sourcecode> | |||
</artwork> | ||||
<t>This mitigation strategy would rely on the client to enforce the | <t>This mitigation strategy would rely on the client to enforce the | |||
security policy and to only send access tokens to legitimate | security policy and to only send access tokens to legitimate | |||
destinations. Results of OAuth-related security research (see for | destinations. Results of OAuth-related security research (see, for | |||
example <xref target="research.ubc"/> and <xref target="research.cmu"/>) indicat | example, <xref target="research.ubc"/> and <xref target="research.cmu"/>) indica | |||
e a | te a | |||
large portion of client implementations do not or fail to properly | large portion of client implementations do not or fail to properly | |||
implement security controls, like <tt>state</tt> checks. So relying on | implement security controls, like <tt>state</tt> checks. So, relying on | |||
clients to prevent access token phishing is likely to fail as well. | clients to prevent access token phishing is likely to fail as well. | |||
Moreover, given the ratio of clients to authorization and resource | Moreover, given the ratio of clients to authorization and resource servers, | |||
servers, it is considered the more viable approach to move as much as | it is considered the more viable approach to move as much as possible | |||
possible security-related logic to those entities. Clearly, the client | security-related logic to those servers. | |||
Clearly, the client | ||||
has to contribute to the overall security. However, there are alternative | has to contribute to the overall security. However, there are alternative | |||
countermeasures, as described before, that provide a | countermeasures, as described in Sections <xref target="pop_tokens" format="coun ter"/> and <xref target="aud_restriction" format="counter"/>, that provide a | |||
better balance between the involved parties.</t> | better balance between the involved parties.</t> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="open_redirection"><name>Open Redirection</name> | <section anchor="open_redirection"><name>Open Redirection</name> | |||
<t>The following attacks can occur when an authorization server or client has an open redirector. Such endpoints are sometimes implemented, | <t>The following attacks can occur when an authorization server or client has an open redirector. Such endpoints are sometimes implemented, | |||
for example, to show a message before a user is then redirected to an external | for example, to show a message before a user is then redirected to an external | |||
website, or to redirect users back to a URL they were intending to visit before | website, or to redirect users back to a URL they were intending to visit before | |||
being interrupted, e.g., by a login prompt.</t> | being interrupted, e.g., by a login prompt.</t> | |||
<section anchor="open_redirector_on_client"><name>Client as Open Redirector</nam e> | <section anchor="open_redirector_on_client"><name>Client as Open Redirector</nam e> | |||
<t>Clients MUST NOT expose open redirectors. Attackers may use open | <t>Clients <bcp14>MUST NOT</bcp14> expose open redirectors. Attackers may use op en | |||
redirectors to produce URLs pointing to the client and utilize them to | redirectors to produce URLs pointing to the client and utilize them to | |||
exfiltrate authorization codes and access tokens, as described in | exfiltrate authorization codes and access tokens, as described in | |||
<xref target="redir_uri_open_redir"/>. Another abuse case is to produce URLs tha t | <xref target="redir_uri_open_redir"/>. Another abuse case is to produce URLs tha t | |||
appear to point to the client. This might trick users into trusting the URL | appear to point to the client. This might trick users into trusting the URL | |||
and following it in their browser. This can be abused for phishing.</t> | and following it in their browser. This can be abused for phishing.</t> | |||
<t>In order to prevent open redirection, clients should only redirect if | <t>In order to prevent open redirection, clients should only redirect if | |||
the target URLs are allowed or if the origin and integrity of a | the target URLs are allowed or if the origin and integrity of a | |||
request can be authenticated. Countermeasures against open redirection | request can be authenticated. Countermeasures against open redirection | |||
are described by OWASP <xref target="owasp.redir"/>.</t> | are described by OWASP <xref target="owasp.redir"/>.</t> | |||
</section> | </section> | |||
<section anchor="authorization-server-as-open-redirector"><name>Authorization Se rver as Open Redirector</name> | <section anchor="authorization-server-as-open-redirector"><name>Authorization Se rver as Open Redirector</name> | |||
<t>Just as with clients, attackers could try to utilize a user's trust in | <t>Just as with clients, attackers could try to utilize a user's trust in | |||
the authorization server (and its URL in particular) for performing | the authorization server (and its URL in particular) for performing | |||
phishing attacks. OAuth authorization servers regularly redirect users | phishing attacks. OAuth authorization servers regularly redirect users | |||
to other websites (the clients), but must do so safely.</t> | to other websites (the clients), but they must do so safely.</t> | |||
<t><xref target="RFC6749"/>, Section 4.1.2.1, already prevents open redirects by | <t><xref target="RFC6749" sectionFormat="of" section="4.1.2.1"/> already prevent | |||
stating that the authorization server MUST NOT automatically redirect the user a | s open redirects by | |||
gent in case | stating that the authorization server <bcp14>MUST NOT</bcp14> automatically redi | |||
rect the user agent in case | ||||
of an invalid combination of <tt>client_id</tt> and <tt>redirect_uri</tt>.</t> | of an invalid combination of <tt>client_id</tt> and <tt>redirect_uri</tt>.</t> | |||
<t>However, an attacker could also utilize a correctly registered | <t>However, an attacker could also utilize a correctly registered | |||
redirect URI to perform phishing attacks. The attacker could, for | redirection URI to perform phishing attacks. The attacker could, for | |||
example, register a client via dynamic client registration <xref target="RFC7591 "/> | example, register a client via dynamic client registration <xref target="RFC7591 "/> | |||
and execute one of the following attacks:</t> | and execute one of the following attacks:</t> | |||
<ol spacing="compact"> | <ol spacing="compact"> | |||
<li>Intentionally send an erroneous authorization request, e.g., by using an | <li>Intentionally send an erroneous authorization request, e.g., by using an | |||
invalid scope value, thus instructing the authorization server to redirect | invalid scope value, thus instructing the authorization server to redirect | |||
the user-agent to its phishing site.</li> | the user agent to its phishing site.</li> | |||
<li>Intentionally send a valid authorization request with <tt>client_id</tt> and | <li>Intentionally send a valid authorization request with <tt>client_id</tt> and | |||
<tt>redirect_uri</tt> controlled by the attacker. After the user authenticates, the | <tt>redirect_uri</tt> controlled by the attacker. After the user authenticates, the | |||
authorization server prompts the user to provide consent to the request. If | authorization server prompts the user to provide consent to the request. If | |||
the user notices an issue with the request and declines the request, the | the user notices an issue with the request and declines the request, the | |||
authorization server still redirects the user agent to the phishing site. In | authorization server still redirects the user agent to the phishing site. In | |||
this case, the user agent will be redirected to the phishing site regardless | this case, the user agent will be redirected to the phishing site regardless | |||
of the action taken by the user.</li> | of the action taken by the user.</li> | |||
<li>Intentionally send a valid silent authentication request (<tt>prompt=none</t t>) | <li>Intentionally send a valid silent authentication request (<tt>prompt=none</t t>) | |||
with <tt>client_id</tt> and <tt>redirect_uri</tt> controlled by the attacker. In this | with <tt>client_id</tt> and <tt>redirect_uri</tt> controlled by the attacker. In this | |||
case, the authorization server will automatically redirect the user agent to | case, the authorization server will automatically redirect the user agent to | |||
the phishing site.</li> | the phishing site.</li> | |||
</ol> | </ol> | |||
<t>The authorization server MUST take precautions to prevent these threats. The authorization server MUST always | <t>The authorization server <bcp14>MUST</bcp14> take precautions to prevent thes e threats. The authorization server <bcp14>MUST</bcp14> always | |||
authenticate the user first and, with the exception of the silent authentication | authenticate the user first and, with the exception of the silent authentication | |||
use case, prompt the user for credentials when needed, before redirecting the | use case, prompt the user for credentials when needed, before redirecting the | |||
user. Based on its risk assessment, the authorization server needs to decide whe | user. Based on its risk assessment, the authorization server needs to decide whe | |||
ther it can trust | ther or not it can trust | |||
the redirect URI or not. It could take into account URI analytics done | the redirection URI. It could take into account URI analytics done | |||
internally or through some external service to evaluate the credibility and | internally or through some external service to evaluate the credibility and | |||
trustworthiness of content behind the URI, and the source of the redirect URI an d | trustworthiness of content behind the URI, and the source of the redirection URI and | |||
other client data.</t> | other client data.</t> | |||
<t>The authorization server SHOULD only automatically redirect the user agent if | <t>The authorization server <bcp14>SHOULD</bcp14> only automatically redirect th | |||
it trusts the | e user agent if it trusts the | |||
redirect URI. If the URI is not trusted, the authorization server MAY inform th | redirection URI. If the URI is not trusted, the authorization server <bcp14>MAY | |||
e user and rely on | </bcp14> inform the user and rely on | |||
the user to make the correct decision.</t> | the user to make the correct decision.</t> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="redirect_307"><name>307 Redirect</name> | <section anchor="redirect_307"><name>307 Redirect</name> | |||
<t>At the authorization endpoint, a typical protocol flow is that the authorizat ion server | <t>At the authorization endpoint, a typical protocol flow is that the authorizat ion server | |||
prompts the user to enter their credentials in a form that is then | prompts the user to enter their credentials in a form that is then | |||
submitted (using the HTTP POST method) back to the authorization | submitted (using the HTTP POST method) back to the authorization | |||
server. The authorization server checks the credentials and, if successful, redi rects | server. The authorization server checks the credentials and, if successful, redi rects | |||
the user agent to the client's redirection endpoint.</t> | the user agent to the client's redirection endpoint.</t> | |||
<t>In <xref target="RFC6749"/>, the HTTP status code 302 is used for this purpos e, but | <t>In <xref target="RFC6749"/>, the HTTP status code 302 (Found) is used for thi s purpose, but | |||
"any other method available via the user-agent to accomplish this | "any other method available via the user-agent to accomplish this | |||
redirection is allowed". When the status code 307 is used for | redirection is allowed". When the status code 307 is used for | |||
redirection instead, the user agent will send the user's credentials via | redirection instead, the user agent will send the user's credentials via | |||
HTTP POST to the client.</t> | HTTP POST to the client.</t> | |||
<t>This discloses the sensitive credentials to the client. If the client | <t>This discloses the sensitive credentials to the client. If the client | |||
is malicious, it can use the credentials to impersonate the user | is malicious, it can use the credentials to impersonate the user | |||
at the authorization server.</t> | at the authorization server.</t> | |||
<t>The behavior might be unexpected for developers but is defined in | <t>The behavior might be unexpected for developers but is defined in | |||
<xref target="RFC9110"/>, Section 15.4.8. This status code does not require the user | <xref target="RFC9110" sectionFormat="of" section="15.4.8"/>. This status code ( 307) does not require the user | |||
agent to rewrite the POST request to a GET request and thereby drop | agent to rewrite the POST request to a GET request and thereby drop | |||
the form data in the POST request body.</t> | the form data in the POST request body.</t> | |||
<t>In the HTTP standard <xref target="RFC9110"/>, only the status code 303 | <t>In the HTTP standard <xref target="RFC9110"/>, only the status code 303 | |||
unambiguously enforces rewriting the HTTP POST request to an HTTP GET | unambiguously enforces rewriting the HTTP POST request to an HTTP GET | |||
request. For all other status codes, including the popular 302, user | request. | |||
agents can opt not to rewrite POST to GET requests and therefore to | ||||
reveal the user's credentials to the client. (In practice, however, most | For all other status codes, including the popular 302, user | |||
user agents will only show this behaviour for 307 redirects.)</t> | agents can opt not to rewrite POST to GET requests, thereby | |||
causing the user's credentials to be revealed to the client. (In practice, howev | ||||
er, most | ||||
user agents will only show this behavior for 307 redirects.)</t> | ||||
<t>Authorization servers that redirect a request that potentially contains the u ser's credentials | <t>Authorization servers that redirect a request that potentially contains the u ser's credentials | |||
therefore MUST NOT use the HTTP 307 status code for redirection. If an | therefore <bcp14>MUST NOT</bcp14> use the HTTP 307 status code for redirection. If an | |||
HTTP redirection (and not, for example, JavaScript) is used for such a | HTTP redirection (and not, for example, JavaScript) is used for such a | |||
request, the authorization server SHOULD use HTTP status code 303 (See Other).</ t> | request, the authorization server <bcp14>SHOULD</bcp14> use HTTP status code 303 (See Other).</t> | |||
</section> | </section> | |||
<section anchor="tls_terminating"><name>TLS Terminating Reverse Proxies</name> | <section anchor="tls_terminating"><name>TLS Terminating Reverse Proxies</name> | |||
<t>A common deployment architecture for HTTP applications is to hide the | <t>A common deployment architecture for HTTP applications is to hide the | |||
application server behind a reverse proxy that terminates the TLS | application server behind a reverse proxy that terminates the TLS | |||
connection and dispatches the incoming requests to the respective | connection and dispatches the incoming requests to the respective | |||
application server nodes.</t> | application server nodes.</t> | |||
<t>This section highlights some attack angles of this deployment | <t>This section highlights some attack angles of this deployment | |||
architecture with relevance to OAuth and gives recommendations for | architecture with relevance to OAuth and gives recommendations for | |||
security controls.</t> | security controls.</t> | |||
skipping to change at line 1619 ¶ | skipping to change at line 1675 ¶ | |||
fields for client certificates and client certificate chains are defined | fields for client certificates and client certificate chains are defined | |||
in <xref target="RFC9440"/>.</t> | in <xref target="RFC9440"/>.</t> | |||
<t>If the reverse proxy passes through any header sent from the | <t>If the reverse proxy passes through any header sent from the | |||
outside, an attacker could try to directly send the faked header | outside, an attacker could try to directly send the faked header | |||
values through the proxy to the application server in order to | values through the proxy to the application server in order to | |||
circumvent security controls that way. For example, it is standard | circumvent security controls that way. For example, it is standard | |||
practice of reverse proxies to accept <tt>X-Forwarded-For</tt> headers and just | practice of reverse proxies to accept <tt>X-Forwarded-For</tt> headers and just | |||
add the origin of the inbound request (making it a list). Depending on | add the origin of the inbound request (making it a list). Depending on | |||
the logic performed in the application server, the attacker could | the logic performed in the application server, the attacker could | |||
simply add an allowed IP address to the header and render the protection useless .</t> | simply add an allowed IP address to the header and render the protection useless .</t> | |||
<t>A reverse proxy MUST therefore sanitize any inbound requests to ensure | <t>A reverse proxy <bcp14>MUST</bcp14> therefore sanitize any inbound requests t o ensure | |||
the authenticity and integrity of all header values relevant for the | the authenticity and integrity of all header values relevant for the | |||
security of the application servers.</t> | security of the application servers.</t> | |||
<t>If an attacker were able to get access to the internal network between | <t>If an attacker were able to get access to the internal network between | |||
the proxy and application server, the attacker could also try to | the proxy and application server, the attacker could also try to | |||
circumvent security controls in place. It is, therefore, essential to | circumvent security controls in place. Therefore, it is essential to | |||
ensure the authenticity of the communicating entities. Furthermore, | ensure the authenticity of the communicating entities. Furthermore, | |||
the communication link between the reverse proxy and application server | the communication link between the reverse proxy and application server | |||
MUST be protected against eavesdropping, injection, and replay of | <bcp14>MUST</bcp14> be protected against eavesdropping, injection, and replay of | |||
messages.</t> | messages.</t> | |||
</section> | </section> | |||
<section anchor="refresh_token_protection"><name>Refresh Token Protection</name> | <section anchor="refresh_token_protection"><name>Refresh Token Protection</name> | |||
<t>Refresh tokens are a convenient and user-friendly way to obtain new access | <t>Refresh tokens are a convenient and user-friendly way to obtain new access | |||
tokens. They also add | tokens. They also add | |||
to the security of OAuth, since they allow the authorization server to issue | to the security of OAuth, since they allow the authorization server to issue | |||
access tokens with a short lifetime and reduced scope, thus reducing the | access tokens with a short lifetime and reduced scope, thus reducing the | |||
potential impact of access token leakage.</t> | potential impact of access token leakage.</t> | |||
<section anchor="discussion-1"><name>Discussion</name> | <section anchor="discussion-1"><name>Discussion</name> | |||
<t>Refresh tokens are an attractive target for attackers since they | <t> | |||
represent the full scope of grant a resource owner delegated to a certain | Refresh tokens are an attractive target for attackers because they | |||
client and they are not further constrained to a specific resource. If an attack | represent the full scope of access granted to | |||
er is able to exfiltrate and successfully replay a | a certain client, and they are not further constrained to a specific | |||
resource. | ||||
If an attacker is able to exfiltrate and successfully replay a | ||||
refresh token, the attacker will be able to mint access tokens and use | refresh token, the attacker will be able to mint access tokens and use | |||
them to access resource servers on behalf of the resource owner.</t> | them to access resource servers on behalf of the resource owner.</t> | |||
<t><xref target="RFC6749"/> already provides robust baseline protection by requi ring</t> | <t><xref target="RFC6749"/> already provides robust baseline protection by requi ring</t> | |||
<ul spacing="compact"> | <ul spacing="compact"> | |||
<li>confidentiality of the refresh tokens in transit and storage,</li> | <li>confidentiality of the refresh tokens in transit and storage,</li> | |||
<li>the transmission of refresh tokens over TLS-protected connections between | <li>the transmission of refresh tokens over TLS-protected connections between | |||
authorization server and client,</li> | authorization server and client,</li> | |||
<li>the authorization server to maintain and check the binding of a refresh toke n | <li>the authorization server to maintain and check the binding of a refresh toke n | |||
to a certain client and authentication of this client during token refresh, | to a certain client and authentication of this client during token refresh, | |||
skipping to change at line 1664 ¶ | skipping to change at line 1724 ¶ | |||
</ul> | </ul> | |||
<t><xref target="RFC6749"/> also lays the foundation for further | <t><xref target="RFC6749"/> also lays the foundation for further | |||
(implementation-specific) security measures, such as refresh token expiration an d | (implementation-specific) security measures, such as refresh token expiration an d | |||
revocation as well as refresh token rotation by defining respective | revocation as well as refresh token rotation by defining respective | |||
error codes and response behaviors.</t> | error codes and response behaviors.</t> | |||
<t>This specification gives recommendations beyond the scope of | <t>This specification gives recommendations beyond the scope of | |||
<xref target="RFC6749"/> and clarifications.</t> | <xref target="RFC6749"/> and clarifications.</t> | |||
</section> | </section> | |||
<section anchor="recommendations-1"><name>Recommendations</name> | <section anchor="recommendations-1"><name>Recommendations</name> | |||
<t>Authorization servers MUST determine, based on a risk assessment, | <t>Authorization servers <bcp14>MUST</bcp14> determine, based on a risk assessme nt, | |||
whether to issue refresh tokens to a certain client. If the | whether to issue refresh tokens to a certain client. If the | |||
authorization server decides not to issue refresh tokens, the client | authorization server decides not to issue refresh tokens, the client | |||
MAY obtain a new access token by utilizing other grant types, such as the | <bcp14>MAY</bcp14> obtain a new access token by utilizing other grant types, suc h as the | |||
authorization code grant type. In such a case, the authorization | authorization code grant type. In such a case, the authorization | |||
server may utilize cookies and persistent grants to optimize the user | server may utilize cookies and persistent grants to optimize the user | |||
experience.</t> | experience.</t> | |||
<t>If refresh tokens are issued, those refresh tokens MUST be bound to | <t>If refresh tokens are issued, those refresh tokens <bcp14>MUST</bcp14> be bou nd to | |||
the scope and resource servers as consented by the resource owner. | the scope and resource servers as consented by the resource owner. | |||
This is to prevent privilege escalation by the legitimate client and reduce | This is to prevent privilege escalation by the legitimate client and reduce | |||
the impact of refresh token leakage.</t> | the impact of refresh token leakage.</t> | |||
<t>For confidential clients, <xref target="RFC6749"/> already requires that refr esh | <t>For confidential clients, <xref target="RFC6749"/> already requires that refr esh | |||
tokens can only be used by the client for which they were issued.</t> | tokens can only be used by the client for which they were issued.</t> | |||
<t>Authorization servers MUST utilize one of these methods to | <t>Authorization servers <bcp14>MUST</bcp14> utilize one of these methods to | |||
detect refresh token replay by malicious actors for public clients:</t> | detect refresh token replay by malicious actors for public clients:</t> | |||
<ul> | <ul> | |||
<li><strong>Sender-constrained refresh tokens:</strong> the authorization server | <li><strong>Sender-constrained refresh tokens:</strong> the authorization server | |||
cryptographically binds the refresh token to a certain client | cryptographically binds the refresh token to a certain client | |||
instance, e.g., by utilizing <xref target="RFC8705"/> or <xref target="RFC9449"/ >.</li> | instance, e.g., by utilizing <xref target="RFC8705"/> or <xref target="RFC9449"/ >.</li> | |||
<li><t><strong>Refresh token rotation:</strong> the authorization server issues a new | <li><t><strong>Refresh token rotation:</strong> the authorization server issues a new | |||
refresh token with every access token refresh response. The | refresh token with every access token refresh response. The | |||
previous refresh token is invalidated but information about the | previous refresh token is invalidated, but information about the | |||
relationship is retained by the authorization server. If a refresh | relationship is retained by the authorization server. If a refresh | |||
token is compromised and subsequently used by both the attacker | token is compromised and subsequently used by both the attacker | |||
and the legitimate client, one of them will present an invalidated | and the legitimate client, one of them will present an invalidated | |||
refresh token, which will inform the authorization server of the | refresh token, which will inform the authorization server of the | |||
breach. The authorization server cannot determine which party | breach. The authorization server cannot determine which party | |||
submitted the invalid refresh token, but it will revoke the | submitted the invalid refresh token, but it will revoke the | |||
active refresh token. This stops the attack at the cost of forcing | active refresh token. This stops the attack at the cost of forcing | |||
the legitimate client to obtain a fresh authorization grant.</t> | the legitimate client to obtain a fresh authorization grant.</t> | |||
<t>Implementation note: The grant to which a refresh token belongs | <t>Implementation note: The grant to which a refresh token belongs | |||
may be encoded into the refresh token itself. This can enable an | may be encoded into the refresh token itself. This can enable an | |||
authorization server to efficiently determine the grant to which a | authorization server to efficiently determine the grant to which a | |||
refresh token belongs, and by extension, all refresh tokens that | refresh token belongs, and by extension, all refresh tokens that | |||
need to be revoked. Authorization servers MUST ensure the | need to be revoked. Authorization servers <bcp14>MUST</bcp14> ensure the | |||
integrity of the refresh token value in this case, for example, | integrity of the refresh token value in this case, for example, | |||
using signatures.</t> | using signatures.</t> | |||
</li> | </li> | |||
</ul> | </ul> | |||
<t>Authorization servers MAY revoke refresh tokens automatically in case | <t>Authorization servers <bcp14>MAY</bcp14> revoke refresh tokens automatically in case | |||
of a security event, such as:</t> | of a security event, such as:</t> | |||
<ul spacing="compact"> | <ul spacing="compact"> | |||
<li>password change</li> | <li>password change or</li> | |||
<li>logout at the authorization server</li> | <li>logout at the authorization server.</li> | |||
</ul> | </ul> | |||
<t>Refresh tokens SHOULD expire if the client has been inactive for some | <t>Refresh tokens <bcp14>SHOULD</bcp14> expire if the client has been inactive f or some | |||
time, i.e., the refresh token has not been used to obtain fresh access | time, i.e., the refresh token has not been used to obtain fresh access | |||
tokens for some time. The expiration time is at the discretion of the | tokens for some time. The expiration time is at the discretion of the | |||
authorization server. It might be a global value or determined based | authorization server. It might be a global value or determined based | |||
on the client policy or the grant associated with the refresh token | on the client policy or the grant associated with the refresh token | |||
(and its sensitivity).</t> | (and its sensitivity).</t> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="client_impersonating"><name>Client Impersonating Resource Owner </name> | <section anchor="client_impersonating"><name>Client Impersonating Resource Owner </name> | |||
<t>Resource servers may make access control decisions based on the identity of a | <t>Resource servers may make access control decisions based on the identity of a | |||
resource owner for which an access token was issued, or based on the identity of | resource owner for which an access token was issued, or based on the identity of | |||
a client in the client credentials grant. For example, <xref target="RFC9068"/> (JSON Web | a client in the client credentials grant. For example, <xref target="RFC9068"/> (JSON Web | |||
Token (JWT) Profile for OAuth 2.0 Access Tokens) describes a data structure for | Token (JWT) Profile for OAuth 2.0 Access Tokens) describes a data structure for | |||
access tokens containing a <tt>sub</tt> claim defined as follows:</t> | access tokens containing a <tt>sub</tt> claim defined as follows:</t> | |||
<blockquote><t>In cases of access tokens obtained through grants where a resourc | <blockquote> | |||
e owner is | <t> | |||
involved, such as the authorization code grant, the value of <tt>sub</tt> SHOULD | In cases | |||
correspond to the subject identifier of the resource owner. In cases of access | of access tokens obtained through grants where a resource owner is | |||
tokens obtained through grants where no resource owner is involved, such as | involved, such as the authorization code grant, the value of "sub" | |||
the client credentials grant, the value of <tt>sub</tt> SHOULD correspond to an | <bcp14>SHOULD</bcp14> correspond to the subject identifier of the resource | |||
identifier the authorization server uses to indicate the client application.</t> | owner. | |||
</blockquote><t>If both options are possible, a resource server may mistake a cl | In cases of access tokens obtained through grants where no | |||
ient's identity | resource owner is involved, such as the client credentials grant, | |||
the value of "sub" <bcp14>SHOULD</bcp14> correspond to an identifier the | ||||
authorization server uses to indicate the client application. | ||||
</t> | ||||
</blockquote> | ||||
<t>If both options are possible, a resource server may mistake a client's identi | ||||
ty | ||||
for the identity of a resource owner. For example, if a client is able to choose | for the identity of a resource owner. For example, if a client is able to choose | |||
its own <tt>client_id</tt> during registration with the authorization server, a | its own <tt>client_id</tt> during registration with the authorization server, a | |||
malicious client may set it to a value identifying a resource owner (e.g., a | malicious client may set it to a value identifying a resource owner (e.g., a | |||
<tt>sub</tt> value if OpenID Connect is used). If the resource server cannot pro perly | <tt>sub</tt> value if OpenID Connect is used). If the resource server cannot pro perly | |||
distinguish between access tokens obtained with involvement of the resource | distinguish between access tokens obtained with involvement of the resource | |||
owner and those without, the client may accidentally be able to access resources | owner and those without, the client may accidentally be able to access resources | |||
belonging to the resource owner.</t> | belonging to the resource owner.</t> | |||
<t>This attack potentially affects not only implementations using <xref target=" RFC9068"/>, but | <t>This attack potentially affects not only implementations using <xref target=" RFC9068"/>, but | |||
also similar, bespoke solutions.</t> | also similar, bespoke solutions.</t> | |||
<section anchor="client_impersonating_countermeasures"><name>Countermeasures</na me> | <section anchor="client_impersonating_countermeasures"><name>Countermeasures</na me> | |||
<t>Authorization servers SHOULD NOT allow clients to influence their <tt>client_ | ||||
id</tt> or | <t>Authorization servers <bcp14>SHOULD NOT</bcp14> allow clients to influence th | |||
any claim that could cause confusion with a genuine resource owner if a common | eir <tt>client_id</tt> or | |||
any other claim that could cause confusion with a genuine resource owner if a co | ||||
mmon | ||||
namespace for client IDs and user identifiers exists, such as in the <tt>sub</tt > claim | namespace for client IDs and user identifiers exists, such as in the <tt>sub</tt > claim | |||
shown above. Where this cannot be avoided, authorization servers MUST provide | example from <xref target="RFC9068"/> shown in <xref target="client_impersonatin g"/> above. Where this cannot be avoided, authorization servers <bcp14>MUST</bcp 14> provide | |||
other means for the resource server to distinguish between the two types of | other means for the resource server to distinguish between the two types of | |||
access tokens.</t> | access tokens.</t> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="clickjacking"><name>Clickjacking</name> | <section anchor="clickjacking"><name>Clickjacking</name> | |||
<t>As described in Section 4.4.1.9 of <xref target="RFC6819"/>, the authorizatio n request is | <t>As described in <xref target="RFC6819" sectionFormat="of" section="4.4.1.9"/> , the authorization request is | |||
susceptible to clickjacking attacks, also called user interface redressing. In | susceptible to clickjacking attacks, also called user interface redressing. In | |||
such an attack, an attacker embeds the authorization endpoint user interface in | such an attack, an attacker embeds the authorization endpoint user interface in | |||
an innocuous context. A user believing to interact with that context, for | an innocuous context. A user believing to interact with that context, for | |||
example, by clicking on buttons, inadvertently interacts with the authorization | example, by clicking on buttons, inadvertently interacts with the authorization | |||
endpoint user interface instead. The opposite can be achieved as well: A user | endpoint user interface instead. The opposite can be achieved as well: A user | |||
believing to interact with the authorization endpoint might inadvertently type a | believing to interact with the authorization endpoint might inadvertently type a | |||
password into an attacker-provided input field overlaid over the original user | password into an attacker-provided input field overlaid over the original user | |||
interface. Clickjacking attacks can be designed such that users can hardly | interface. Clickjacking attacks can be designed such that users can hardly | |||
notice the attack, for example using almost invisible iframes overlaid on top of | notice the attack, for example, using almost invisible iframes overlaid on top o f | |||
other elements.</t> | other elements.</t> | |||
<t>An attacker can use this vector to obtain the user's authentication credentia ls, | <t>An attacker can use this vector to obtain the user's authentication credentia ls, | |||
change the scope of access granted to the client, and potentially access the | change the scope of access granted to the client, and potentially access the | |||
user's resources.</t> | user's resources.</t> | |||
<t>Authorization servers MUST prevent clickjacking attacks. Multiple | <t>Authorization servers <bcp14>MUST</bcp14> prevent clickjacking attacks. Multi ple | |||
countermeasures are described in <xref target="RFC6819"/>, including the use of the | countermeasures are described in <xref target="RFC6819"/>, including the use of the | |||
X-Frame-Options HTTP response header field and frame-busting | X-Frame-Options HTTP response header field and frame-busting | |||
JavaScript. In addition to those, authorization servers SHOULD also | JavaScript. In addition to those, authorization servers <bcp14>SHOULD</bcp14> al so | |||
use Content Security Policy (CSP) level 2 <xref target="W3C.CSP-2"/> or greater. </t> | use Content Security Policy (CSP) level 2 <xref target="W3C.CSP-2"/> or greater. </t> | |||
<t>To be effective, CSP must be used on the authorization endpoint and, | <t>To be effective, CSP must be used on the authorization endpoint and, | |||
if applicable, other endpoints used to authenticate the user and | if applicable, other endpoints used to authenticate the user and | |||
authorize the client (e.g., the device authorization endpoint, login | authorize the client (e.g., the device authorization endpoint, login | |||
pages, error pages, etc.). This prevents framing by unauthorized | pages, error pages, etc.). This prevents framing by unauthorized | |||
origins in user agents that support CSP. The client MAY permit being | origins in user agents that support CSP. The client <bcp14>MAY</bcp14> permit be ing | |||
framed by some other origin than the one used in its redirection | framed by some other origin than the one used in its redirection | |||
endpoint. For this reason, authorization servers SHOULD allow | endpoint. For this reason, authorization servers <bcp14>SHOULD</bcp14> allow | |||
administrators to configure allowed origins for particular clients | administrators to configure allowed origins for particular clients | |||
and/or for clients to register these dynamically.</t> | and/or for clients to register these dynamically.</t> | |||
<t>Using CSP allows authorization servers to specify multiple origins in | <t>Using CSP allows authorization servers to specify multiple origins in | |||
a single response header field and to constrain these using flexible | a single response header field and to constrain these using flexible | |||
patterns (see <xref target="W3C.CSP-2"/> for details). Level 2 of this standard provides | patterns (see <xref target="W3C.CSP-2"/> for details). Level 2 of CSP provides | |||
a robust mechanism for protecting against clickjacking by using | a robust mechanism for protecting against clickjacking by using | |||
policies that restrict the origin of frames (using <tt>frame-ancestors</tt>) | policies that restrict the origin of frames (by using <tt>frame-ancestors</tt>) | |||
together with those that restrict the sources of scripts allowed to | together with those that restrict the sources of scripts allowed to | |||
execute on an HTML page (by using <tt>script-src</tt>). A non-normative | execute on an HTML page (by using <tt>script-src</tt>). A non-normative | |||
example of such a policy is shown in the following listing:</t> | example of such a policy is shown in the following listing:</t> | |||
<artwork><![CDATA[HTTP/1.1 200 OK | <sourcecode type="http-message"><![CDATA[ | |||
HTTP/1.1 200 OK | ||||
Content-Security-Policy: frame-ancestors https://ext.example.org:8000 | Content-Security-Policy: frame-ancestors https://ext.example.org:8000 | |||
Content-Security-Policy: script-src 'self' | Content-Security-Policy: script-src 'self' | |||
X-Frame-Options: ALLOW-FROM https://ext.example.org:8000 | X-Frame-Options: ALLOW-FROM https://ext.example.org:8000 | |||
... | ... | |||
]]> | ]]></sourcecode> | |||
</artwork> | ||||
<t>Because some user agents do not support <xref target="W3C.CSP-2"/>, this tech nique | <t>Because some user agents do not support <xref target="W3C.CSP-2"/>, this tech nique | |||
SHOULD be combined with others, including those described in | <bcp14>SHOULD</bcp14> be combined with others, including those described in | |||
<xref target="RFC6819"/>, unless such legacy user agents are explicitly unsuppor ted | <xref target="RFC6819"/>, unless such legacy user agents are explicitly unsuppor ted | |||
by the authorization server. Even in such cases, additional | by the authorization server. Even in such cases, additional | |||
countermeasures SHOULD still be employed.</t> | countermeasures <bcp14>SHOULD</bcp14> still be employed.</t> | |||
</section> | </section> | |||
<section anchor="rec_ibc"><name>Attacks on In-Browser Communication Flows</name> | <section anchor="rec_ibc"><name>Attacks on In-Browser Communication Flows</name> | |||
<t>If the authorization response is sent with in-browser communication technique s | <t>If the authorization response is sent with in-browser communication technique s | |||
like postMessage <xref target="WHATWG.postmessage_api"/> instead of HTTP redirec ts, messages may | like postMessage <xref target="WHATWG.postmessage_api"/> instead of HTTP redirec ts, messages may | |||
inadvertently be sent to malicious origins or injected from malicious origins.</ t> | inadvertently be sent to malicious origins or injected from malicious origins.</ t> | |||
<section anchor="examples"><name>Examples</name> | <section anchor="examples"><name>Examples</name> | |||
<t>The following non-normative pseudocode examples of attacks using in-browser | <t>The following non-normative pseudocode examples of attacks using in-browser | |||
communication are described in <xref target="research.rub"/>:</t> | communication are described in <xref target="research.rub"/>.</t> | |||
<section anchor="insufficient-limitation-of-receiver-origins"><name>Insufficient Limitation of Receiver Origins</name> | <section anchor="insufficient-limitation-of-receiver-origins"><name>Insufficient Limitation of Receiver Origins</name> | |||
<t>When sending the authorization response or token response via | <t>When sending the authorization response or token response via | |||
postMessage, the authorization server sends the response to the wildcard | postMessage, the authorization server sends the response to the wildcard | |||
origin "*" instead of the client's origin. When the window to which the | origin "*" instead of the client's origin. When the window to which the | |||
response is sent is controlled by an attacker, the attacker can read the | response is sent is controlled by an attacker, the attacker can read the | |||
response.</t> | response.</t> | |||
<artwork><![CDATA[window.opener.postMessage( | <sourcecode type="javascript"><![CDATA[ | |||
window.opener.postMessage( | ||||
{ | { | |||
code: "ABC", | code: "ABC", | |||
state: "123" | state: "123" | |||
}, | }, | |||
"*" // any website in the opener window can receive the message | "*" // any website in the opener window can receive the message | |||
) | ) | |||
]]> | ]]></sourcecode> | |||
</artwork> | ||||
</section> | </section> | |||
<section anchor="insufficient-uri-validation"><name>Insufficient URI Validation< /name> | <section anchor="insufficient-uri-validation"><name>Insufficient URI Validation< /name> | |||
<t>When sending the authorization response or token response via | <t>When sending the authorization response or token response via | |||
postMessage, the authorization server may not check the | postMessage, the authorization server may not check the | |||
receiver origin against the redirect URI and instead, for example, send | receiver origin against the redirection URI and instead, for example, may send | |||
the response to an origin provided by an attacker. This is analogous to | the response to an origin provided by an attacker. This is analogous to | |||
the attack described in <xref target="insufficient_uri_validation"/>.</t> | the attack described in <xref target="insufficient_uri_validation"/>.</t> | |||
<artwork><![CDATA[window.opener.postMessage( | <sourcecode type="javascript"><![CDATA[ | |||
window.opener.postMessage( | ||||
{ | { | |||
code: "ABC", | code: "ABC", | |||
state: "123" | state: "123" | |||
}, | }, | |||
"https://attacker.example" // attacker-provided value | "https://attacker.example" // attacker-provided value | |||
) | ) | |||
]]> | ]]></sourcecode> | |||
</artwork> | ||||
</section> | </section> | |||
<section anchor="injection-after-insufficient-validation-of-sender-origin"><name >Injection after Insufficient Validation of Sender Origin</name> | <section anchor="injection-after-insufficient-validation-of-sender-origin"><name >Injection after Insufficient Validation of Sender Origin</name> | |||
<t>A client that expects the authorization response or token response via | <t>A client that expects the authorization response or token response via | |||
postMessage may not validate the sender origin of the message. This | postMessage may not validate the sender origin of the message. This | |||
may allow an attacker to inject an authorization response or token response | may allow an attacker to inject an authorization response or token response | |||
into the client.</t> | into the client.</t> | |||
<t>In the case of a maliciously injected authorization response, the attack | <t>In the case of a maliciously injected authorization response, the attack | |||
is a variant of the CSRF attacks described in <xref target="csrf"/>. The | is a variant of the CSRF attacks described in <xref target="csrf"/>. The | |||
countermeasures described in <xref target="csrf"/> apply to this attack as well. </t> | countermeasures described in <xref target="csrf"/> apply to this attack as well. </t> | |||
<t>In the case of a maliciously injected token response, sender-constrained | <t>In the case of a maliciously injected token response, sender-constrained | |||
access tokens as described in <xref target="pop_tokens"/> may prevent the attack under | access tokens as described in <xref target="pop_tokens"/> may prevent the attack under | |||
some circumstances, but additional countermeasures as described next are | some circumstances, but additional countermeasures as described in <xref target= "recommendations-1-1"/> are | |||
generally required.</t> | generally required.</t> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="recommendations-1-1"><name>Recommendations</name> | <section anchor="recommendations-1-1"><name>Recommendations</name> | |||
<t>When comparing client receiver origins against pre-registered origins, | <t>When comparing client receiver origins against pre-registered origins, | |||
authorization servers MUST utilize exact string matching as described in | authorization servers <bcp14>MUST</bcp14> utilize exact string matching as descr | |||
<xref target="iuv_countermeasures"/>. Authorization servers MUST send postMessag | ibed in | |||
es to | <xref target="iuv_countermeasures"/>. Authorization servers <bcp14>MUST</bcp14> | |||
send postMessages to | ||||
trusted client receiver origins, as shown in the following, non-normative exampl e:</t> | trusted client receiver origins, as shown in the following, non-normative exampl e:</t> | |||
<artwork><![CDATA[window.opener.postMessage( | <sourcecode type="javascript"><![CDATA[ | |||
window.opener.postMessage( | ||||
{ | { | |||
code: "ABC", | code: "ABC", | |||
state: "123" | state: "123" | |||
}, | }, | |||
"https://client.example" // use explicit client origin | "https://client.example" // use explicit client origin | |||
) | ) | |||
]]> | ]]></sourcecode> | |||
</artwork> | ||||
<t>Wildcard origins like "*" in postMessage MUST NOT be used as attackers can us | <t>Wildcard origins like "*" in postMessage <bcp14>MUST NOT</bcp14> be used, as | |||
e them | attackers can use them | |||
to leak a victim's in-browser message to malicious origins. | to leak a victim's in-browser message to malicious origins. | |||
Both measures contribute to the prevention of leakage of authorization codes and | Both measures contribute to the prevention of leakage of authorization codes and | |||
access tokens (see <xref target="insufficient_uri_validation"/>).</t> | access tokens (see <xref target="insufficient_uri_validation"/>).</t> | |||
<t>Clients MUST prevent injection of in-browser messages on the client | <t>Clients <bcp14>MUST</bcp14> prevent injection of in-browser messages on the c | |||
receiver endpoint. Clients MUST utilize exact string matching to compare | lient | |||
receiver endpoint. Clients <bcp14>MUST</bcp14> utilize exact string matching to | ||||
compare | ||||
the initiator origin of an in-browser message with the authorization | the initiator origin of an in-browser message with the authorization | |||
server origin, as shown in the following, non-normative example:</t> | server origin, as shown in the following, non-normative example:</t> | |||
<artwork><![CDATA[window.addEventListener("message", (e) => { | <sourcecode type="javascript"><![CDATA[ | |||
window.addEventListener("message", (e) => { | ||||
// validate exact authorization server origin | // validate exact authorization server origin | |||
if (e.origin === "https://honest.as.example") { | if (e.origin === "https://honest.as.example") { | |||
// process e.data.code and e.data.state | // process e.data.code and e.data.state | |||
} | } | |||
}) | }) | |||
]]> | ]]></sourcecode> | |||
</artwork> | ||||
<t>Since in-browser communication flows only apply a different communication | <t>Since in-browser communication flows only apply a different communication | |||
technique (i.e., postMessage instead of HTTP redirect), all measures protecting | technique (i.e., postMessage instead of HTTP redirect), all measures protecting | |||
the authorization response listed in <xref target="rec_redirect"/> MUST be appli ed equally.</t> | the authorization response listed in <xref target="rec_redirect"/> <bcp14>MUST</ bcp14> be applied equally.</t> | |||
</section> | </section> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="Acknowledgements"><name>Acknowledgements</name> | ||||
<t>We would like to thank | ||||
Brock Allen, | ||||
Annabelle Richard Backman, | ||||
Dominick Baier, | ||||
Vittorio Bertocci, | ||||
Brian Campbell, | ||||
Bruno Crispo, | ||||
William Dennis, | ||||
George Fletcher, | ||||
Matteo Golinelli, | ||||
Dick Hardt, | ||||
Joseph Heenan, | ||||
Pedram Hosseyni, | ||||
Phil Hunt, | ||||
Tommaso Innocenti, | ||||
Louis Jannett, | ||||
Jared Jennings, | ||||
Michael B. Jones, | ||||
Engin Kirda, | ||||
Konstantin Lapine, | ||||
Neil Madden, | ||||
Christian Mainka, | ||||
Jim Manico, | ||||
Nov Matake, | ||||
Doug McDorman, | ||||
Ali Mirheidari, | ||||
Vladislav Mladenov, | ||||
Karsten Meyer zu Selhausen, | ||||
Kaan Onarioglu, | ||||
Aaron Parecki, | ||||
Michael Peck, | ||||
Johan Peeters, | ||||
Nat Sakimura, | ||||
Guido Schmitz, | ||||
Jörg Schwenk, | ||||
Rifaat Shekh-Yusef, | ||||
Travis Spencer, | ||||
Petteri Stenius, | ||||
Tomek Stojecki, | ||||
Tim Wuertele, | ||||
David Waite and | ||||
Hans Zandbelt | ||||
for their valuable feedback.</t> | ||||
</section> | ||||
<section anchor="IANA"><name>IANA Considerations</name> | <section anchor="IANA"><name>IANA Considerations</name> | |||
<t>This draft makes no requests to IANA.</t> | <t>This document has no IANA actions.</t> | |||
</section> | </section> | |||
<section anchor="Security"><name>Security Considerations</name> | <section anchor="Security"><name>Security Considerations</name> | |||
<t>Security considerations are described in <xref target="recommendations"/>, <x ref target="secmodel"/>, and <xref target="attacks_and_mitigations"/>.</t> | <t>Security considerations are described in Sections <xref target="recommendatio ns" format="counter"/>, <xref target="secmodel" format="counter"/>, and <xref ta rget="attacks_and_mitigations" format="counter"/>.</t> | |||
</section> | </section> | |||
</middle> | </middle> | |||
<back> | <back> | |||
<displayreference target="I-D.bradley-oauth-jwt-encoded-state" to="JWT-ENCODED-S | ||||
TATE"/> | ||||
<displayreference target="I-D.ietf-oauth-token-binding" to="TOKEN-BINDING"/> | ||||
<displayreference target="I-D.ietf-oauth-v2-1" to="OAUTH-V2.1"/> | ||||
<references><name>References</name> | <references><name>References</name> | |||
<references><name>Normative References</name> | <references><name>Normative References</name> | |||
<reference anchor="BCP195" target="https://www.rfc-editor.org/info/bcp195"> | ||||
<front> | <referencegroup anchor="BCP195" target="https://www.rfc-editor.org/info/bcp195"> | |||
<title>BCP195</title> | <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8996.xm | |||
<author> | l"/> | |||
<organization>IETF</organization> | <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9325.xm | |||
</author> | l"/> | |||
</front> | </referencegroup> | |||
</reference> | ||||
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.3986.xml" /> | <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.3986.xml" /> | |||
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6749.xml" /> | <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6749.xml" /> | |||
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6750.xml" /> | <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6750.xml" /> | |||
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6819.xml" /> | <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6819.xml" /> | |||
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7521.xml" /> | <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7521.xml" /> | |||
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7523.xml" /> | <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7523.xml" /> | |||
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8252.xml" /> | <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8252.xml" /> | |||
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8414.xml" /> | <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8414.xml" /> | |||
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8705.xml" /> | <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8705.xml" /> | |||
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9068.xml" /> | <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9068.xml" /> | |||
</references> | </references> | |||
<references><name>Informative References</name> | <references><name>Informative References</name> | |||
<!-- [I-D.bradley-oauth-jwt-encoded-state] IESG state: Expired as of 06/17/24--> | ||||
<xi:include href="https://bib.ietf.org/public/rfc/bibxml3/reference.I-D.bradley- oauth-jwt-encoded-state.xml"/> | <xi:include href="https://bib.ietf.org/public/rfc/bibxml3/reference.I-D.bradley- oauth-jwt-encoded-state.xml"/> | |||
<!-- [I-D.ietf-oauth-token-binding] IESG state: Expired as of 06/17/24--> | ||||
<xi:include href="https://bib.ietf.org/public/rfc/bibxml3/reference.I-D.ietf-oau th-token-binding.xml"/> | <xi:include href="https://bib.ietf.org/public/rfc/bibxml3/reference.I-D.ietf-oau th-token-binding.xml"/> | |||
<!-- [I-D.ietf-oauth-v2-1] IESG state: I-D Exists as of 06/17/24--> | ||||
<xi:include href="https://bib.ietf.org/public/rfc/bibxml3/reference.I-D.ietf-oau th-v2-1.xml"/> | <xi:include href="https://bib.ietf.org/public/rfc/bibxml3/reference.I-D.ietf-oau th-v2-1.xml"/> | |||
<reference anchor="OAuth.Post" target="https://openid.net/specs/oauth-v2-form-po st-response-mode-1_0.html"> | <reference anchor="OAuth.Post" target="https://openid.net/specs/oauth-v2-form-po st-response-mode-1_0.html"> | |||
<front> | <front> | |||
<title>OAuth 2.0 Form Post Response Mode</title> | <title>OAuth 2.0 Form Post Response Mode</title> | |||
<author fullname="Mike Jones" initials="M." surname="Jones"> | <author fullname="Mike Jones" initials="M." surname="Jones"> | |||
<organization>Microsoft</organization> | <organization>Microsoft</organization> | |||
</author> | </author> | |||
<author fullname="Brian Campbell" initials="B." surname="Campbell"> | <author fullname="Brian Campbell" initials="B." surname="Campbell"> | |||
<organization>Ping Identity</organization> | <organization>Ping Identity</organization> | |||
</author> | </author> | |||
<date year="2015" month="April" day="27"/> | <date year="2015" month="April" day="27"/> | |||
</front> | </front> | |||
<refcontent>The OpenID Foundation</refcontent> | ||||
</reference> | </reference> | |||
<reference anchor="OAuth.Responses" target="https://openid.net/specs/oauth-v2-mu ltiple-response-types-1_0.html"> | <reference anchor="OAuth.Responses" target="https://openid.net/specs/oauth-v2-mu ltiple-response-types-1_0.html"> | |||
<front> | <front> | |||
<title>OAuth 2.0 Multiple Response Type Encoding Practices</title> | <title>OAuth 2.0 Multiple Response Type Encoding Practices</title> | |||
<author fullname="Breno de Medeiros" initials="B." surname="de Medeiros"> | <author fullname="Breno de Medeiros" initials="B." surname="de Medeiros" rol e="editor"> | |||
<organization>Google</organization> | <organization>Google</organization> | |||
</author> | </author> | |||
<author fullname="Mihai Scurtescu" initials="M." surname="Scurtescu"> | <author fullname="Mihai Scurtescu" initials="M." surname="Scurtescu"> | |||
<organization>Google</organization> | <organization>Google</organization> | |||
</author> | </author> | |||
<author fullname="Peter Tarjan" surname="Tarjan"> | <author fullname="Peter Tarjan" surname="Tarjan"> | |||
<organization>Facebook</organization> | <organization>Facebook</organization> | |||
</author> | </author> | |||
<author fullname="Mike Jones" initials="M." surname="Jones"> | <author fullname="Mike Jones" initials="M." surname="Jones"> | |||
<organization>Microsoft</organization> | <organization>Microsoft</organization> | |||
</author> | </author> | |||
<date year="2014" month="Feb" day="25"/> | <date year="2014" month="Feb" day="25"/> | |||
</front> | </front> | |||
<refcontent>The OpenID Foundation</refcontent> | ||||
</reference> | </reference> | |||
<reference anchor="OpenID.Core" target="https://openid.net/specs/openid-connect- core-1_0.html"> | <reference anchor="OpenID.Core" target="https://openid.net/specs/openid-connect- core-1_0.html"> | |||
<front> | <front> | |||
<title>OpenID Connect Core 1.0 incorporating errata set 2</title> | <title>OpenID Connect Core 1.0 incorporating errata set 2</title> | |||
<author fullname="Nat Sakimura" initials="N." surname="Sakimura"> | <author fullname="Nat Sakimura" initials="N." surname="Sakimura"> | |||
<organization>NAT.Consulting</organization> | <organization>NAT.Consulting</organization> | |||
</author> | </author> | |||
<author fullname="John Bradley" initials="J." surname="Bradley"> | <author fullname="John Bradley" initials="J." surname="Bradley"> | |||
<organization>Yubico</organization> | <organization>Yubico</organization> | |||
</author> | </author> | |||
<author fullname="Mike Jones" initials="M." surname="Jones"> | <author fullname="Mike Jones" initials="M." surname="Jones"> | |||
<organization>Self-Issued Consulting</organization> | <organization>Self-Issued Consulting</organization> | |||
</author> | </author> | |||
<author fullname="Breno de Medeiros" initials="B." surname="de Medeiros"> | <author fullname="Breno de Medeiros" initials="B." surname="de Medeiros"> | |||
<organization>Google</organization> | <organization>Google</organization> | |||
</author> | </author> | |||
<author fullname="Chuck Mortimore" initials="C." surname="Mortimore"> | <author fullname="Chuck Mortimore" initials="C." surname="Mortimore"> | |||
<organization>Disney</organization> | <organization>Disney</organization> | |||
</author> | </author> | |||
<date year="2023" month="Dec" day="15"/> | <date year="2023" month="Dec" day="15"/> | |||
</front> | </front> | |||
<refcontent>The OpenID Foundation</refcontent> | ||||
</reference> | </reference> | |||
<reference anchor="OpenID.Discovery" target="https://openid.net/specs/openid-con nect-discovery-1_0.html"> | <reference anchor="OpenID.Discovery" target="https://openid.net/specs/openid-con nect-discovery-1_0.html"> | |||
<front> | <front> | |||
<title>OpenID Connect Discovery 1.0 incorporating errata set 2</title> | <title>OpenID Connect Discovery 1.0 incorporating errata set 2</title> | |||
<author fullname="Nat Sakimura" initials="N." surname="Sakimura"> | <author fullname="Nat Sakimura" initials="N." surname="Sakimura"> | |||
<organization>NAT.Consulting</organization> | <organization>NAT.Consulting</organization> | |||
</author> | </author> | |||
<author fullname="John Bradley" initials="J." surname="Bradley"> | <author fullname="John Bradley" initials="J." surname="Bradley"> | |||
<organization>Yubico</organization> | <organization>Yubico</organization> | |||
</author> | </author> | |||
<author fullname="Mike Jones" initials="M." surname="Jones"> | <author fullname="Mike Jones" initials="M." surname="Jones"> | |||
<organization>Self-Issued Consulting</organization> | <organization>Self-Issued Consulting</organization> | |||
</author> | </author> | |||
<author fullname="Edmund Jay" initials="E." surname="Jay"> | <author fullname="Edmund Jay" initials="E." surname="Jay"> | |||
<organization>Illumila</organization> | <organization>Illumila</organization> | |||
</author> | </author> | |||
<date year="2023" month="Dec" day="15"/> | <date year="2023" month="Dec" day="15"/> | |||
</front> | </front> | |||
<refcontent>The OpenID Foundation</refcontent> | ||||
</reference> | </reference> | |||
<reference anchor="OpenID.JARM" target="https://openid.net/specs/openid-financia l-api-jarm.html"> | <reference anchor="OpenID.JARM" target="https://openid.net/specs/openid-financia l-api-jarm.html"> | |||
<front> | <front> | |||
<title>Financial-grade API: JWT Secured Authorization Response Mode for OAut h 2.0 (JARM)</title> | <title>Financial-grade API: JWT Secured Authorization Response Mode for OAut h 2.0 (JARM)</title> | |||
<author fullname="Torsten Lodderstedt" initials="T." surname="Lodderstedt"> | <author fullname="Torsten Lodderstedt" initials="T." surname="Lodderstedt"> | |||
<organization>Yes</organization> | <organization>Yes</organization> | |||
</author> | </author> | |||
<author fullname="Brian Campbell" initials="B." surname="Campbell"> | <author fullname="Brian Campbell" initials="B." surname="Campbell"> | |||
<organization>Ping</organization> | <organization>Ping</organization> | |||
</author> | </author> | |||
<date year="2018" month="Oct" day="17"/> | <date year="2018" month="Oct" day="17"/> | |||
</front> | </front> | |||
<refcontent>The OpenID Foundation</refcontent> | ||||
</reference> | </reference> | |||
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml" /> | <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml" /> | |||
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7591.xml" /> | <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7591.xml" /> | |||
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7636.xml" /> | <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7636.xml" /> | |||
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8174.xml" /> | <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8174.xml" /> | |||
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8707.xml" /> | <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8707.xml" /> | |||
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9101.xml" /> | <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9101.xml" /> | |||
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9110.xml" /> | <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9110.xml" /> | |||
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9126.xml" /> | <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9126.xml" /> | |||
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9207.xml" /> | <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9207.xml" /> | |||
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9396.xml" /> | <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9396.xml" /> | |||
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9440.xml" /> | <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9440.xml" /> | |||
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9449.xml" /> | <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9449.xml" /> | |||
<reference anchor="W3C.CSP-2" target="https://www.w3.org/TR/CSP2"> | ||||
<reference anchor="W3C.CSP-2" target="https://www.w3.org/TR/2016/REC-CSP2-201612 | ||||
15/"> | ||||
<front> | <front> | |||
<title>Content Security Policy Level 2</title> | <title>Content Security Policy Level 2</title> | |||
<author initials="M." surname="West"/> | <author initials="M." surname="West"/> | |||
<author initials="A." surname="Barth"/> | <author initials="A." surname="Barth"/> | |||
<author initials="D." surname="Veditz"/> | <author initials="D." surname="Veditz"/> | |||
<date year="2015" month="July"/> | <date year="2016" month="December"/> | |||
</front> | </front> | |||
<refcontent>W3C Recommendation</refcontent> | ||||
<annotation>Latest version available at <eref target="https://www.w3.org/TR/CSP2 | ||||
/" brackets="angle" />.</annotation> | ||||
</reference> | </reference> | |||
<reference anchor="W3C.WebAuthn" target="https://www.w3.org/TR/2021/REC-webauthn -2-20210408/"> | <reference anchor="W3C.WebAuthn" target="https://www.w3.org/TR/2021/REC-webauthn -2-20210408/"> | |||
<front> | <front> | |||
<title>Web Authentication: An API for accessing Public Key Credentials Level 2</title> | <title>Web Authentication: An API for accessing Public Key Credentials Level 2</title> | |||
<author fullname="Jeff Hodges" initials="J." surname="Hodges"> | <author fullname="Jeff Hodges" initials="J." surname="Hodges"> | |||
<organization>Google</organization> | <organization>Google</organization> | |||
</author> | </author> | |||
<author fullname="J.C. Jones" initials="J.C." surname="Jones"> | <author fullname="J.C. Jones" initials="J.C." surname="Jones"> | |||
<organization>Mozilla</organization> | <organization>Mozilla</organization> | |||
</author> | </author> | |||
<author fullname="Michael B. Jones" initials="M.B." surname="Jones"> | <author fullname="Michael B. Jones" initials="M.B." surname="Jones"> | |||
<organization>Microsoft</organization> | <organization>Microsoft</organization> | |||
</author> | </author> | |||
<author fullname="Akshay Kumar" initials="A." surname="Kumar"> | <author fullname="Akshay Kumar" initials="A." surname="Kumar"> | |||
<organization>Microsoft</organization> | <organization>Microsoft</organization> | |||
</author> | </author> | |||
<author fullname="Emil Lundberg" initials="E." surname="Lundberg"> | <author fullname="Emil Lundberg" initials="E." surname="Lundberg"> | |||
<organization>Yubico</organization> | <organization>Yubico</organization> | |||
</author> | </author> | |||
<date year="2021" month="Apr" day="08"/> | <date year="2021" month="Apr" day="08"/> | |||
</front> | </front> | |||
<refcontent>W3C Recommendation</refcontent> | ||||
<annotation>Latest version available at <eref target="https://www.w3.org/TR/we | ||||
bauthn-2/" brackets="angle"/>.</annotation> | ||||
</reference> | </reference> | |||
<reference anchor="W3C.WebCrypto" target="https://www.w3.org/TR/2017/REC-WebCryp toAPI-20170126/"> | <reference anchor="W3C.WebCrypto" target="https://www.w3.org/TR/2017/REC-WebCryp toAPI-20170126/"> | |||
<front> | <front> | |||
<title>Web Cryptography API</title> | <title>Web Cryptography API</title> | |||
<author fullname="Mark Watson" initials="M." surname="Watson"> | <author fullname="Mark Watson" initials="M." surname="Watson" role="editor"> | |||
<organization>Netflix</organization> | <organization>Netflix</organization> | |||
</author> | </author> | |||
<date year="2017" month="January" day="26"/> | <date year="2017" month="January" day="26"/> | |||
</front> | </front> | |||
<refcontent>W3C Recommendation</refcontent> | ||||
<annotation>Latest version available at <eref target="https://www.w3.org/TR/We | ||||
bCryptoAPI/" brackets="angle"/>.</annotation> | ||||
</reference> | </reference> | |||
<reference anchor="W3C.webappsec-referrer-policy" target="https://w3c.github.io/ | ||||
webappsec-referrer-policy"> | <reference anchor="W3C.webappsec-referrer-policy" target="https://www.w3.org/TR/ | |||
2017/CR-referrer-policy-20170126/"> | ||||
<front> | <front> | |||
<title>Referrer Policy</title> | <title>Referrer Policy</title> | |||
<author initials="J." surname="Eisinger"> | <author initials="J." surname="Eisinger"> | |||
<organization>Google Inc.</organization> | <organization>Google Inc.</organization> | |||
</author> | </author> | |||
<author initials="E." surname="Stark"> | <author initials="E." surname="Stark"> | |||
<organization>Google Inc.</organization> | <organization>Google Inc.</organization> | |||
</author> | </author> | |||
<date year="2017" month="April" day="20"/> | <date year="2017" month="January" day="26"/> | |||
</front> | </front> | |||
<annotation>Latest version available at <eref target="https://www.w3.org/TR/re ferrer-policy/" brackets="angle"/>.</annotation> | ||||
</reference> | </reference> | |||
<reference anchor="WHATWG.CORS" target="https://fetch.spec.whatwg.org/#http-cors -protocol"> | <reference anchor="WHATWG.CORS" target="https://fetch.spec.whatwg.org/#http-cors -protocol"> | |||
<front> | <front> | |||
<title>Fetch Standard: CORS protocol</title> | <title>CORS protocol</title> | |||
<author/> | <author> | |||
<date/> | <organization>WHATWG</organization> | |||
</author> | ||||
<date day="17" month="June" year="2024"/> | ||||
</front> | </front> | |||
<refcontent>Fetch: Living Standard, Section 3.2</refcontent> | ||||
</reference> | </reference> | |||
<reference anchor="WHATWG.postmessage_api" target="https://html.spec.whatwg.org/ multipage/web-messaging.html#web-messaging"> | <reference anchor="WHATWG.postmessage_api" target="https://html.spec.whatwg.org/ multipage/web-messaging.html#web-messaging"> | |||
<front> | <front> | |||
<title>HTML Living Standard: Cross-document messaging</title> | <title>Cross-document messaging</title> | |||
<author/> | <author> | |||
<date/> | <organization>WHATWG</organization> | |||
</author> | ||||
<date day="19" month="August" year="2024"/> | ||||
</front> | </front> | |||
<refcontent>HTML: Living Standard, Section 9.3</refcontent> | ||||
</reference> | </reference> | |||
<reference anchor="arXiv.1508.04324v2" target="https://arxiv.org/abs/1508.04324v 2/"> | <reference anchor="arXiv.1508.04324v2" target="https://arxiv.org/abs/1508.04324v 2/"> | |||
<front> | <front> | |||
<title>On the security of modern Single Sign-On Protocols: Second-Order Vuln erabilities in OpenID Connect</title> | <title>On the security of modern Single Sign-On Protocols: Second-Order Vuln erabilities in OpenID Connect</title> | |||
<author fullname="Vladislav Mladenov" initials="V." surname="Mladenov"> | <author fullname="Vladislav Mladenov" initials="V." surname="Mladenov"> | |||
<organization/> | <organization/> | |||
</author> | </author> | |||
<author fullname="Christian Mainka" initials="C." surname="Mainka"> | <author fullname="Christian Mainka" initials="C." surname="Mainka"> | |||
<organization/> | <organization/> | |||
</author> | </author> | |||
<author fullname="Jörg Schwenk" initials="J." surname="Schwenk"> | <author fullname="Jörg Schwenk" initials="J." surname="Schwenk"> | |||
<organization/> | <organization/> | |||
</author> | </author> | |||
<date year="2016" month="January" day="7"/> | <date year="2016" month="January" day="7"/> | |||
</front> | </front> | |||
<seriesInfo name="arXiv" value="1508.04324v2"/> | <refcontent>arXiv:1508.04324v2</refcontent> | |||
<seriesInfo name="DOI" value="10.48550/arXiv.1508.04324"/> | ||||
</reference> | </reference> | |||
<reference anchor="arXiv.1601.01229" target="https://arxiv.org/abs/1601.01229/"> | <reference anchor="arXiv.1601.01229" target="https://arxiv.org/abs/1601.01229/"> | |||
<front> | <front> | |||
<title>A Comprehensive Formal Security Analysis of OAuth 2.0</title> | <title>A Comprehensive Formal Security Analysis of OAuth 2.0</title> | |||
<author fullname="Daniel Fett" initials="D." surname="Fett"> | <author fullname="Daniel Fett" initials="D." surname="Fett"> | |||
<organization/> | <organization/> | |||
</author> | </author> | |||
<author fullname="Ralf Küsters" initials="R." surname="Küsters"> | <author fullname="Ralf Küsters" initials="R." surname="Küsters"> | |||
<organization/> | <organization/> | |||
</author> | </author> | |||
<author fullname="Guido Schmitz" initials="G." surname="Schmitz"> | <author fullname="Guido Schmitz" initials="G." surname="Schmitz"> | |||
<organization/> | <organization/> | |||
</author> | </author> | |||
<date year="2016" month="January" day="6"/> | <date year="2016" month="January" day="6"/> | |||
</front> | </front> | |||
<seriesInfo name="arXiv" value="1601.01229"/> | <refcontent>arXiv:1601.01229</refcontent> | |||
<seriesInfo name="DOI" value="10.48550/arXiv.1601.01229"/> | ||||
</reference> | </reference> | |||
<reference anchor="arXiv.1704.08539" target="https://arxiv.org/abs/1704.08539/"> | <reference anchor="arXiv.1704.08539" target="https://arxiv.org/abs/1704.08539/"> | |||
<front> | <front> | |||
<title>The Web SSO Standard OpenID Connect: In-Depth Formal Security Analysi s and Security Guidelines</title> | <title>The Web SSO Standard OpenID Connect: In-Depth Formal Security Analysi s and Security Guidelines</title> | |||
<author fullname="Daniel Fett" initials="D." surname="Fett"> | <author fullname="Daniel Fett" initials="D." surname="Fett"> | |||
<organization/> | <organization/> | |||
</author> | </author> | |||
<author fullname="Ralf Küsters" initials="R." surname="Küsters"> | <author fullname="Ralf Küsters" initials="R." surname="Küsters"> | |||
<organization/> | <organization/> | |||
</author> | </author> | |||
<author fullname="Guido Schmitz" initials="G." surname="Schmitz"> | <author fullname="Guido Schmitz" initials="G." surname="Schmitz"> | |||
<organization/> | <organization/> | |||
</author> | </author> | |||
<date year="2017" month="April" day="27"/> | <date year="2017" month="April" day="27"/> | |||
</front> | </front> | |||
<seriesInfo name="arXiv" value="1704.08539"/> | <refcontent>arXiv:1704.08539</refcontent> | |||
<seriesInfo name="DOI" value="10.48550/arXiv.1704.08539"/> | ||||
</reference> | </reference> | |||
<reference anchor="arXiv.1901.11520" target="https://arxiv.org/abs/1901.11520/"> | <reference anchor="arXiv.1901.11520" target="https://arxiv.org/abs/1901.11520/"> | |||
<front> | <front> | |||
<title>An Extensive Formal Security Analysis of the OpenID Financial-grade A PI</title> | <title>An Extensive Formal Security Analysis of the OpenID Financial-grade A PI</title> | |||
<author fullname="Daniel Fett" initials="D." surname="Fett"> | <author fullname="Daniel Fett" initials="D." surname="Fett"> | |||
<organization/> | <organization/> | |||
</author> | </author> | |||
<author fullname="Pedram Hosseyni" initials="P." surname="Hosseyni"> | <author fullname="Pedram Hosseyni" initials="P." surname="Hosseyni"> | |||
<organization/> | <organization/> | |||
</author> | </author> | |||
<author fullname="Ralf Küsters" initials="R." surname="Küsters"> | <author fullname="Ralf Küsters" initials="R." surname="Küsters"> | |||
<organization/> | <organization/> | |||
</author> | </author> | |||
<date year="2019" month="January" day="31"/> | <date year="2019" month="January" day="31"/> | |||
</front> | </front> | |||
<seriesInfo name="arXiv" value="1901.11520"/> | <refcontent>arXiv:1901.11520</refcontent> | |||
<seriesInfo name="DOI" value="10.48550/arXiv.1901.11520"/> | ||||
</reference> | </reference> | |||
<reference anchor="bug.chromium" target="https://issues.chromium.org/issues/4007 6763"> | <reference anchor="bug.chromium" target="https://issues.chromium.org/issues/4007 6763"> | |||
<front> | <front> | |||
<title>Referer header includes URL fragment when opening link using New Tab< /title> | <title>Referer header includes URL fragment when opening link using New Tab< /title> | |||
<author/> | <author/> | |||
<date/> | <date/> | |||
</front> | </front> | |||
<refcontent>Chromium Issue Tracker, Issue ID: 40076763</refcontent> | ||||
</reference> | </reference> | |||
<reference anchor="owasp.redir" target="https://cheatsheetseries.owasp.org/cheat sheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html"> | <reference anchor="owasp.redir" target="https://cheatsheetseries.owasp.org/cheat sheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html"> | |||
<front> | <front> | |||
<title>OWASP Cheat Sheet Series - Unvalidated Redirects and Forwards</title> | <title>Unvalidated Redirects and Forwards Cheat Sheet</title> | |||
<author/> | <author> | |||
<organization>OWASP Foundation</organization> | ||||
</author> | ||||
<date/> | <date/> | |||
</front> | </front> | |||
<refcontent>OWASP Cheat Sheet Series</refcontent> | ||||
</reference> | </reference> | |||
<reference anchor="research.cmu" target="https://css.csail.mit.edu/6.858/2012/re | ||||
adings/oauth-sso.pdf"> | <reference anchor="research.cmu" target="https://www.microsoft.com/en-us/researc | |||
h/wp-content/uploads/2016/02/OAuthDemystified.pdf"> | ||||
<front> | <front> | |||
<title>OAuth Demystified for Mobile Application Developers</title> | <title>OAuth Demystified for Mobile Application Developers</title> | |||
<author fullname="Eric Chen" initials="E." surname="Chen"> | <author fullname="Eric Chen" initials="E." surname="Chen"> | |||
<organization abbrev="CMU">Carnegie Mellon University</organization> | <organization abbrev="CMU">Carnegie Mellon University</organization> | |||
</author> | </author> | |||
<author fullname="Yutong Pei" initials="Y." surname="Pei"> | <author fullname="Yutong Pei" initials="Y." surname="Pei"> | |||
<organization abbrev="CMU">Carnegie Mellon University</organization> | <organization abbrev="CMU">Carnegie Mellon University</organization> | |||
</author> | </author> | |||
<author fullname="Shuo Chen" initials="S." surname="Chen"> | <author fullname="Shuo Chen" initials="S." surname="Chen"> | |||
<organization abbrev="MR">Microsoft Research</organization> | <organization abbrev="MR">Microsoft Research</organization> | |||
skipping to change at line 2245 ¶ | skipping to change at line 2324 ¶ | |||
<organization abbrev="CMU">Carnegie Mellon University</organization> | <organization abbrev="CMU">Carnegie Mellon University</organization> | |||
</author> | </author> | |||
<author fullname="Robert Kotcher" initials="R." surname="Kotcher"> | <author fullname="Robert Kotcher" initials="R." surname="Kotcher"> | |||
<organization abbrev="CMU">Carnegie Mellon University</organization> | <organization abbrev="CMU">Carnegie Mellon University</organization> | |||
</author> | </author> | |||
<author fullname="Patrick Tague" initials="P." surname="Tague"> | <author fullname="Patrick Tague" initials="P." surname="Tague"> | |||
<organization abbrev="CMU">Carnegie Mellon University</organization> | <organization abbrev="CMU">Carnegie Mellon University</organization> | |||
</author> | </author> | |||
<date year="2014" month="November"/> | <date year="2014" month="November"/> | |||
</front> | </front> | |||
<format type="pdf" target="https://css.csail.mit.edu/6.858/2012/readings/oauth | <refcontent>CCS '14: Proceedings of the 2014 ACM SIGSAC Conference on Computer | |||
-sso.pdf"/> | and Communications Security, pp. 892-903</refcontent> | |||
<seriesInfo name="DOI" value="10.1145/2660267.2660323"/> | ||||
</reference> | </reference> | |||
<reference anchor="research.jcs_14" target="https://www.doc.ic.ac.uk/~maffeis/pa pers/jcs14.pdf"> | <reference anchor="research.jcs_14" target="https://www.doc.ic.ac.uk/~maffeis/pa pers/jcs14.pdf"> | |||
<front> | <front> | |||
<title>Discovering concrete attacks on website authorization by formal analy sis</title> | <title>Discovering concrete attacks on website authorization by formal analy sis</title> | |||
<author fullname="Chetan Bansal" initials="C." surname="Bansal"> | <author fullname="Chetan Bansal" initials="C." surname="Bansal"> | |||
<organization/> | <organization/> | |||
</author> | </author> | |||
<author fullname="Karthikeyan Bhargavan" initials="K." surname="Bhargavan"> | <author fullname="Karthikeyan Bhargavan" initials="K." surname="Bhargavan"> | |||
<organization/> | <organization/> | |||
</author> | </author> | |||
<author fullname="Antoine Delignat-Lavaud" initials="A." surname="Delignat-L avaud"> | <author fullname="Antoine Delignat-Lavaud" initials="A." surname="Delignat-L avaud"> | |||
<organization/> | <organization/> | |||
</author> | </author> | |||
<author fullname="Sergio Maffeis" initials="S." surname="Maffeis"> | <author fullname="Sergio Maffeis" initials="S." surname="Maffeis"> | |||
<organization/> | <organization/> | |||
</author> | </author> | |||
<date year="2014" month="April" day="23"/> | <date year="2014" month="April" day="23"/> | |||
</front> | </front> | |||
<format type="pdf" target="https://www.doc.ic.ac.uk/~maffeis/papers/jcs14.pdf" | <refcontent>Journal of Computer Security, vol. 22, no. 4, pp. 601-657</refcont | |||
/> | ent> | |||
<seriesInfo name="DOI" value="10.3233/JCS-140503"/> | ||||
</reference> | </reference> | |||
<reference anchor="research.rub" target="https://distinct-sso.com/paper.pdf"> | ||||
<reference anchor="research.rub" target="https://dl.acm.org/doi/pdf/10.1145/3548 | ||||
606.3560692"> | ||||
<front> | <front> | |||
<title>DISTINCT: Identity Theft using In-Browser Communications in Dual-Wind ow Single Sign-On</title> | <title>DISTINCT: Identity Theft using In-Browser Communications in Dual-Wind ow Single Sign-On</title> | |||
<author fullname="Louis Jannett" initials="L." surname="Jannett"> | <author fullname="Louis Jannett" initials="L." surname="Jannett"> | |||
<organization/> | <organization/> | |||
</author> | </author> | |||
<author fullname="Vladislav Mladenov" initials="V." surname="Mladenov"> | <author fullname="Vladislav Mladenov" initials="V." surname="Mladenov"> | |||
<organization/> | <organization/> | |||
</author> | </author> | |||
<author fullname="Christian Mainka" initials="C." surname="Mainka"> | <author fullname="Christian Mainka" initials="C." surname="Mainka"> | |||
<organization/> | <organization/> | |||
</author> | </author> | |||
<author fullname="Jörg Schwenk" initials="J." surname="Schwenk"> | <author fullname="Jörg Schwenk" initials="J." surname="Schwenk"> | |||
<organization/> | <organization/> | |||
</author> | </author> | |||
<date year="2022" month="November" day="7"/> | <date year="2022" month="November" day="7"/> | |||
</front> | </front> | |||
<refcontent>CCS '22: Proceedings of the 2022 ACM SIGSAC Conference on Computer and Communications Security</refcontent> | ||||
<seriesInfo name="DOI" value="10.1145/3548606.3560692"/> | <seriesInfo name="DOI" value="10.1145/3548606.3560692"/> | |||
</reference> | </reference> | |||
<reference anchor="research.rub2" target="https://www.nds.rub.de/media/ei/arbeit en/2021/05/03/masterthesis.pdf"> | <reference anchor="research.rub2" target="https://www.nds.rub.de/media/ei/arbeit en/2021/05/03/masterthesis.pdf"> | |||
<front> | <front> | |||
<title>Security Analysis of Real-Life OpenID Connect Implementations</title> | <title>Security Analysis of Real-Life OpenID Connect Implementations</title> | |||
<author fullname="Christian Fries" initials="C." surname="Fries"> | <author fullname="Christian Fries" initials="C." surname="Fries"> | |||
<organization/> | <organization/> | |||
</author> | </author> | |||
<date year="2020" month="December" day="20"/> | <date year="2020" month="December" day="20"/> | |||
</front> | </front> | |||
<refcontent>Master's thesis, Ruhr-Universität Bochum (RUB)</refcontent> | ||||
</reference> | </reference> | |||
<reference anchor="research.ubc" target="https://passwordresearch.com/papers/pap | ||||
er267.html"> | <reference anchor="research.ubc" target="https://css.csail.mit.edu/6.858/2012/re | |||
adings/oauth-sso.pdf"> | ||||
<front> | <front> | |||
<title>The Devil is in the (Implementation) Details: An Empirical Analysis o f OAuth SSO Systems</title> | <title>The Devil is in the (Implementation) Details: An Empirical Analysis o f OAuth SSO Systems</title> | |||
<author fullname="San-Tsai Sun" initials="S.-T." surname="Sun"> | <author fullname="San-Tsai Sun" initials="S.-T." surname="Sun"> | |||
<organization abbrev="UBC">University of British Columbia</organization> | <organization abbrev="UBC">University of British Columbia</organization> | |||
</author> | </author> | |||
<author fullname="Konstantin Beznosov" initials="K." surname="Beznosov"> | <author fullname="Konstantin Beznosov" initials="K." surname="Beznosov"> | |||
<organization abbrev="UBC">University of British Columbia</organization> | <organization abbrev="UBC">University of British Columbia</organization> | |||
</author> | </author> | |||
<date year="2012" month="October"/> | <date year="2012" month="October"/> | |||
</front> | </front> | |||
<format type="HTML" target="https://passwordresearch.com/papers/paper267.html" | <refcontent>Proceedings of the 2012 ACM conference on Computer and communicati | |||
/> | ons security (CCS '12), pp. 378-390</refcontent> | |||
<seriesInfo name="DOI" value="10.1145/2382196.2382238"/> | ||||
</reference> | </reference> | |||
<reference anchor="research.udel" target="https://www.eecis.udel.edu/~hnw/paper/ | ||||
ccs16a.pdf"> | <reference anchor="research.udel" target="https://dl.acm.org/doi/pdf/10.1145/297 | |||
6749.2978387"> | ||||
<front> | <front> | |||
<title>All Your DNS Records Point to Us: Understanding the Security Threats of Dangling DNS Records</title> | <title>All Your DNS Records Point to Us: Understanding the Security Threats of Dangling DNS Records</title> | |||
<author fullname="Daiping Liu" initials="D." surname="Liu"/> | <author fullname="Daiping Liu" initials="D." surname="Liu"/> | |||
<author fullname="Shuai Hao" initials="S." surname="Hao"/> | <author fullname="Shuai Hao" initials="S." surname="Hao"/> | |||
<author fullname="Haining Wang" initials="H." surname="Wang"/> | <author fullname="Haining Wang" initials="H." surname="Wang"/> | |||
<date year="2016" month="October" day="24"/> | <date year="2016" month="October" day="24"/> | |||
</front> | </front> | |||
<refcontent>CCS '16: Proceedings of the 2016 ACM SIGSAC Conference on Computer | ||||
and Communications Security, pp. 1414-1425</refcontent> | ||||
<seriesInfo name="DOI" value="10.1145/2976749.2978387"/> | ||||
</reference> | </reference> | |||
</references> | </references> | |||
</references> | </references> | |||
<section anchor="document-history"><name>Document History</name> | <section numbered="false" anchor="Acknowledgements"><name>Acknowledgements</name | |||
<t>[[ To be removed from the final specification ]]</t> | > | |||
<t>-29</t> | <t>We would like to thank | |||
<contact fullname="Brock Allen"/>, | ||||
<ul spacing="compact"> | <contact fullname="Annabelle Richard Backman"/>, | |||
<li>Fix broken reference</li> | <contact fullname="Dominick Baier"/>, | |||
</ul> | <contact fullname="Vittorio Bertocci"/>, | |||
<t>-28</t> | <contact fullname="Brian Campbell"/>, | |||
<contact fullname="Bruno Crispo"/>, | ||||
<ul spacing="compact"> | <contact fullname="William Dennis"/>, | |||
<li>Various editorial fixes</li> | <contact fullname="George Fletcher"/>, | |||
<li>Address feedback from IESG ballot</li> | <contact fullname="Matteo Golinelli"/>, | |||
</ul> | <contact fullname="Dick Hardt"/>, | |||
<t>-27</t> | <contact fullname="Joseph Heenan"/>, | |||
<contact fullname="Pedram Hosseyni"/>, | ||||
<ul spacing="compact"> | <contact fullname="Phil Hunt"/>, | |||
<li>Mostly editorial feedback from Microsoft incorporated</li> | <contact fullname="Tommaso Innocenti"/>, | |||
<li>Feedback from SECDIR review incorporated</li> | <contact fullname="Louis Jannett"/>, | |||
</ul> | <contact fullname="Jared Jennings"/>, | |||
<t>-26</t> | <contact fullname="Michael B. Jones"/>, | |||
<contact fullname="Engin Kirda"/>, | ||||
<ul spacing="compact"> | <contact fullname="Konstantin Lapine"/>, | |||
<li>Feedback from ARTART review incorporated</li> | <contact fullname="Neil Madden"/>, | |||
<li>Gen-ART review (typo fixes)</li> | <contact fullname="Christian Mainka"/>, | |||
</ul> | <contact fullname="Jim Manico"/>, | |||
<t>-25</t> | <contact fullname="Nov Matake"/>, | |||
<contact fullname="Doug McDorman"/>, | ||||
<ul spacing="compact"> | <contact fullname="Karsten Meyer zu Selhausen"/>, | |||
<li>Shepherd's writeup feedback: Removed discussion on outdated POP approaches</ | <contact fullname="Ali Mirheidari"/>, | |||
li> | <contact fullname="Vladislav Mladenov"/>, | |||
<li>Shepherd's writeup feedback: Clarify relationship to other document.</li> | <contact fullname="Kaan Onarioglu"/>, | |||
<li>Shepherd's writeup feedback: Expand abbreviations</li> | <contact fullname="Aaron Parecki"/>, | |||
<li>Shepherd's writeup feedback: Better explain attacker model</li> | <contact fullname="Michael Peck"/>, | |||
<li>Shepherd's writeup feedback: Various editorial changes</li> | <contact fullname="Johan Peeters"/>, | |||
<li>AD review: Mention updated documents in abstract</li> | <contact fullname="Nat Sakimura"/>, | |||
<li>AD review: Fix HTTP reference</li> | <contact fullname="Guido Schmitz"/>, | |||
<li>AD review: Clarification in the attacker model</li> | <contact fullname="Jörg Schwenk"/>, | |||
<li>AD review: Various editorial and minor changes</li> | <contact fullname="Rifaat Shekh-Yusef"/>, | |||
</ul> | <contact fullname="Travis Spencer"/>, | |||
<t>-24</t> | <contact fullname="Petteri Stenius"/>, | |||
<contact fullname="Tomek Stojecki"/>, | ||||
<ul spacing="compact"> | <contact fullname="David Waite"/>, | |||
<li>Some feedback from shepherd's writeup incorporated</li> | <contact fullname="Tim Würtele"/>, and | |||
<li>Cleaned up references</li> | <contact fullname="Hans Zandbelt"/> | |||
<li>Clarification on mix-up attack</li> | for their valuable feedback.</t> | |||
<li>Add researcher names to acknowledgements</li> | ||||
<li>Removed sentence stating that only MTLS is standardized; DPoP is now as well | ||||
</li> | ||||
</ul> | ||||
<t>-23</t> | ||||
<ul spacing="compact"> | ||||
<li>Added CORS considerations</li> | ||||
<li>Reworded <xref target="client_impersonating_countermeasures"/> to be more in | ||||
line with OAuth 2.1</li> | ||||
<li>Editorial changes</li> | ||||
<li>Clarifications and updated references</li> | ||||
</ul> | ||||
<t>-22</t> | ||||
<ul spacing="compact"> | ||||
<li>Added section on securing in-browser communication</li> | ||||
<li>Merged section on phishing via AS into existing section on open redirectors< | ||||
/li> | ||||
<li>Restructure and move section on sender-constrained tokens</li> | ||||
<li>Mention RFCs for Private Key JWK method</li> | ||||
</ul> | ||||
<t>-21</t> | ||||
<ul spacing="compact"> | ||||
<li>Improved wording on phishing via AS</li> | ||||
</ul> | ||||
<t>-20</t> | ||||
<ul spacing="compact"> | ||||
<li>Improved description of authorization code injection attacks and PKCE protec | ||||
tion</li> | ||||
<li>Removed recommendation for MTLS in discussion (not reflected in actual Recom | ||||
mendations section)</li> | ||||
<li>Reworded "placeholder" text in security considerations.</li> | ||||
<li>Alphabetized list of names and fixed unicode problem</li> | ||||
<li>Explained Clickjacking</li> | ||||
<li>Explained Open Redirectors</li> | ||||
<li>Clarified references to attacker model by including a link to <xref target=" | ||||
secmodel"/></li> | ||||
<li>Clarified description of "CSRF tokens" and reference to RFC6819</li> | ||||
<li>Described that OIDC can prevent access token injection</li> | ||||
<li>Updated references</li> | ||||
</ul> | ||||
<t>-19</t> | ||||
<ul spacing="compact"> | ||||
<li>Changed affiliation of Andrey Labunets</li> | ||||
<li>Editorial change to clarify the new recommendations for refresh tokens</li> | ||||
</ul> | ||||
<t>-18</t> | ||||
<ul spacing="compact"> | ||||
<li>Fix editorial and spelling issues.</li> | ||||
<li>Change wording for disallowing HTTP redirect URIs.</li> | ||||
</ul> | ||||
<t>-17</t> | ||||
<ul spacing="compact"> | ||||
<li>Make the use of metadata RECOMMENDED for both servers and clients</li> | ||||
<li>Make announcing PKCE support in metadata the RECOMMENDED way (before: either | ||||
metadata or deployment-specific way)</li> | ||||
<li>AS also MUST NOT expose open redirectors.</li> | ||||
<li>Mention that attackers can collaborate.</li> | ||||
<li>Update recommendations regarding mix-up defense, building upon <xref target= | ||||
"RFC9207"/>.</li> | ||||
<li>Improve description of mix-up attack.</li> | ||||
<li>Make HTTPS mandatory for most redirect URIs.</li> | ||||
</ul> | ||||
<t>-16</t> | ||||
<ul spacing="compact"> | ||||
<li>Make MTLS a suggestion instead of RECOMMENDED.</li> | ||||
<li>Add important requirements when using nonce for code injection protection.</ | ||||
li> | ||||
<li>Highlight requirements for refresh token sender-constraining.</li> | ||||
<li>Make PKCE a MUST for public clients.</li> | ||||
<li>Describe PKCE Downgrade Attacks and countermeasures.</li> | ||||
<li>Allow variable port numbers in localhost redirect URIs as in RFC8252, Sectio | ||||
n 7.3.</li> | ||||
</ul> | ||||
<t>-15</t> | ||||
<ul spacing="compact"> | ||||
<li>Update reference to DPoP</li> | ||||
<li>Fix reference to RFC8414</li> | ||||
<li>Move to xml2rfcv3</li> | ||||
</ul> | ||||
<t>-14</t> | ||||
<ul spacing="compact"> | ||||
<li>Added info about using CSP to prevent clickjacking</li> | ||||
<li>Changes from WGLC feedback</li> | ||||
<li>Editorial changes</li> | ||||
<li>AS MUST announce PKCE support either in metadata or using deployment-specifi | ||||
c ways (before: SHOULD)</li> | ||||
</ul> | ||||
<t>-13</t> | ||||
<ul spacing="compact"> | ||||
<li>Discourage use of Resource Owner Password Credentials Grant</li> | ||||
<li>Added text on client impersonating resource owner</li> | ||||
<li>Recommend asymmetric methods for client authentication</li> | ||||
<li>Encourage use of PKCE mode "S256"</li> | ||||
<li>PKCE may replace state for CSRF protection</li> | ||||
<li>AS SHOULD publish PKCE support</li> | ||||
<li>Cleaned up discussion on auth code injection</li> | ||||
<li>AS MUST support PKCE</li> | ||||
</ul> | ||||
<t>-12</t> | ||||
<ul spacing="compact"> | ||||
<li>Added updated attacker model</li> | ||||
</ul> | ||||
<t>-11</t> | ||||
<ul spacing="compact"> | ||||
<li>Adapted section 2.1.2 to outcome of consensus call</li> | ||||
<li>more text on refresh token inactivity and implementation note on refresh tok | ||||
en replay detection via refresh token rotation</li> | ||||
</ul> | ||||
<t>-10</t> | ||||
<ul spacing="compact"> | ||||
<li>incorporated feedback by Joseph Heenan</li> | ||||
<li>changed occurrences of SHALL to MUST</li> | ||||
<li>added text on lack of token/cert binding support tokens issued in | ||||
the authorization response as justification to not recommend | ||||
issuing tokens there at all</li> | ||||
<li>added requirement to authenticate clients during code exchange | ||||
(PKCE or client credential) to 2.1.1.</li> | ||||
<li>added section on refresh tokens</li> | ||||
<li>editorial enhancements to 2.1.2 based on feedback</li> | ||||
</ul> | ||||
<t>-09</t> | ||||
<ul spacing="compact"> | ||||
<li>changed text to recommend not to use implicit but code</li> | ||||
<li>added section on access token injection</li> | ||||
<li>reworked sections 3.1 through 3.3 to be more specific on implicit | ||||
grant issues</li> | ||||
</ul> | ||||
<t>-08</t> | ||||
<ul spacing="compact"> | ||||
<li>added recommendations re implicit and token injection</li> | ||||
<li>uppercased key words in Section 2 according to RFC 2119</li> | ||||
</ul> | ||||
<t>-07</t> | ||||
<ul spacing="compact"> | ||||
<li>incorporated findings of Doug McDorman</li> | ||||
<li>added section on HTTP status codes for redirects</li> | ||||
<li>added new section on access token privilege restriction based on | ||||
comments from Johan Peeters</li> | ||||
</ul> | ||||
<t>-06</t> | ||||
<ul spacing="compact"> | ||||
<li>reworked section 3.8.1</li> | ||||
<li>incorporated Phil Hunt's feedback</li> | ||||
<li>reworked section on mix-up</li> | ||||
<li>extended section on code leakage via referrer header to also cover | ||||
state leakage</li> | ||||
<li>added Daniel Fett as author</li> | ||||
<li>replaced text intended to inform WG discussion by recommendations | ||||
to implementors</li> | ||||
<li>modified example URLs to conform to RFC 2606</li> | ||||
</ul> | ||||
<t>-05</t> | ||||
<ul spacing="compact"> | ||||
<li>Completed sections on code leakage via referrer header, attacks in | ||||
browser, mix-up, and CSRF</li> | ||||
<li>Reworked Code Injection Section</li> | ||||
<li>Added reference to OpenID Connect spec</li> | ||||
<li>removed refresh token leakage as respective considerations have | ||||
been given in section 10.4 of RFC 6749</li> | ||||
<li>first version on open redirection</li> | ||||
<li>incorporated Christian Mainka's review feedback</li> | ||||
</ul> | ||||
<t>-04</t> | ||||
<ul spacing="compact"> | ||||
<li>Restructured document for better readability</li> | ||||
<li>Added best practices on Token Leakage prevention</li> | ||||
</ul> | ||||
<t>-03</t> | ||||
<ul spacing="compact"> | ||||
<li>Added section on Access Token Leakage at Resource Server</li> | ||||
<li>incorporated Brian Campbell's findings</li> | ||||
</ul> | ||||
<t>-02</t> | ||||
<ul spacing="compact"> | ||||
<li>Folded Mix up and Access Token leakage through a bad AS into new | ||||
section for dynamic OAuth threats</li> | ||||
<li>reworked dynamic OAuth section</li> | ||||
</ul> | ||||
<t>-01</t> | ||||
<ul spacing="compact"> | ||||
<li>Added references to mitigation methods for token leakage</li> | ||||
<li>Added reference to Token Binding for Authorization Code</li> | ||||
<li>incorporated feedback of Phil Hunt</li> | ||||
<li>fixed numbering issue in attack descriptions in section 2</li> | ||||
</ul> | ||||
<t>-00 (WG document)</t> | ||||
<ul spacing="compact"> | ||||
<li>turned the ID into a WG document and a BCP</li> | ||||
<li>Added federated app login as topic in Other Topics</li> | ||||
</ul> | ||||
</section> | </section> | |||
</back> | </back> | |||
<!-- [rfced] Please review the "Inclusive Language" portion of the online | ||||
Style Guide <https://www.rfc-editor.org/styleguide/part2/#inclusive_language> | ||||
and let us know if any changes are needed. Updates of this nature typically | ||||
result in more precise language, which is helpful for readers. | ||||
For example, please consider whether the following should be updated: | ||||
native | ||||
--> | ||||
</rfc> | </rfc> | |||
End of changes. 353 change blocks. | ||||
904 lines changed or deleted | 839 lines changed or added | |||
This html diff was produced by rfcdiff 1.48. |