-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathdraft-lodderstedt-oauth-security-topics.xml
649 lines (617 loc) · 33.2 KB
/
draft-lodderstedt-oauth-security-topics.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
<?xml version="1.0" encoding="US-ASCII"?>
<!--
This template is for creating an Internet Draft using xml2rfc, which
is available here: http://xml.resource.org.
-->
<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [
<!-- One method to get references from the online citation libraries.
There has to be one entity for each item to be referenced.
An alternate method (rfc include) is described in the references. -->
<!ENTITY RFC2119 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2119.xml">
<!ENTITY RFC2629 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2629.xml">
<!ENTITY RFC3552 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.3552.xml">
<!ENTITY I-D.narten-iana-considerations-rfc2434bis SYSTEM "http://xml.resource.org/public/rfc/bibxml3/reference.I-D.narten-iana-considerations-rfc2434bis.xml">
]>
<?xml-stylesheet type='text/xsl' href='rfc2629.xslt' ?>
<?xml-stylesheet type='text/xsl' href='rfc2629.xslt' ?>
<?rfc strict="yes" ?>
<!-- give errors regarding ID-nits and DTD validation -->
<!-- control the table of contents (ToC) -->
<?rfc toc="yes"?>
<!-- generate a ToC -->
<?rfc tocdepth="4"?>
<!-- the number of levels of subsections in ToC. default: 3 -->
<!-- control references -->
<?rfc symrefs="yes"?>
<!-- use symbolic references tags, i.e, [RFC2119] instead of [1] -->
<?rfc sortrefs="yes" ?>
<!-- sort the reference entries alphabetically -->
<!--
control vertical white space (using these PIs as follows is
recommended by the RFC Editor)
-->
<?rfc compact="yes" ?>
<!-- do not start each main section on a new page -->
<?rfc subcompact="no" ?>
<!-- keep one blank line between list items -->
<!-- end of list of popular I-D processing instructions -->
<rfc category="bcp" docName="draft-lodderstedt-oauth-security-topics-01"
ipr="trust200902">
<!--
category values: std, bcp, info, exp, and historic ipr values:
full3667, noModification3667, noDerivatives3667 you can add the
attributes updates="NNNN" and obsoletes="NNNN" they will automatically
be output with "(if approved)"
-->
<!-- ***** FRONT MATTER ***** -->
<front>
<!--
The abbreviated title is used in the page header - it is only
necessary if the full title is longer than 39 characters
-->
<title abbrev="Security Topics">OAuth Security Topics</title>
<author fullname="Torsten Lodderstedt" initials="T." role="editor"
surname="Lodderstedt">
<organization>Deutsche Telekom AG</organization>
<address>
<email>[email protected]</email>
<!-- uri and facsimile elements may also be added -->
</address>
</author>
<author fullname="John Bradley" initials="J." surname="Bradley">
<organization>Ping Identity</organization>
<address>
<email>[email protected]</email>
</address>
</author>
<author fullname="Andrey Labunets" initials="A." surname="Labunets">
<organization>Facebook</organization>
<address>
<email>[email protected]</email>
</address>
</author>
<date day="16" month="November" year="2016" />
<!-- Meta-data Declarations -->
<area>Security Area</area>
<workgroup>Open Authentication Protocol</workgroup>
<!--
WG name at the upperleft corner of the doc, IETF is fine for
individual submissions. If this element is not present, the default
is "Network Working Group", which is used by the RFC Editor as a nod
to the history of the IETF.
-->
<keyword>security</keyword>
<keyword>oauth2</keyword>
<!--
Keywords will be incorporated into HTML output files in a meta tag
but they have no effect on text or nroff output. If you submit your
draft to the RFC Editor, the keywords will be used for the search
engine.
-->
<abstract>
<t>This draft gives a comprehensive overview on open OAuth security topics.
It is intended to serve as a working document for the OAuth working group
to systematically capture and discuss these security topics and respective
mitigations and eventually recommend best current practice and also OAuth
extensions needed to cope with the respective security threats.</t>
</abstract>
</front>
<middle>
<section anchor="Introduction" title="Introduction">
<t>It's been a while since OAuth has been published in
<xref target="RFC6749">RFC 6749</xref> and <xref target="RFC6750">RFC 6750</xref>.
Since
publication, OAuth 2.0 has gotten massive traction in the market and became the
standard for API protection and, as foundation of OpenID Connect, identity
providing.
<list style="symbols">
<t>OAuth implementations are being attacked through known implementation
weaknesses and anti-patterns (XSRF, referrer header). Although most of these
threats are discussed in <xref target="RFC6819">RFC 6819</xref>, continued exploitation
demonstrates there may be a need for more specific recommendations or that the existing
mitigations are too difficult to deploy.</t>
<t>Technology has changed, e.g. the way browsers treat fragments in some situations,
which may change the implicit grant's underlying security model.</t>
<t>OAuth is used in much more dynamic setups than originally anticipated, creating new
challenges with respect to security. Those challenges go beyond the original
scope of both <xref target="RFC6749">RFC 6749</xref> and <xref target="RFC6819">RFC 6819</xref>.</t>
</list>
</t>
<t>This remainder of the document is organized as follows: The next section
describes various scenarios how OAuth credentials (namely access tokens and
authorization codes) may be disclosed to attackers and proposes
countermeasures. Afterwards, the document discusses attacks possible with
captured credential and how they may be prevented. The last
sections discuss additional threats.</t>
</section>
<section anchor="cred_leakage" title="OAuth Credentials Leakage">
<section title="Redirect URI validation of authorization requests">
<t>The following implementation issue has been observed: Some authorization
servers allow clients to register redirect URI patterns instead of
complete redirect URIs. In those cases, the authorization servers,
at runtime, match the actual redirect URI parameter value at the
authorization endpoint against this pattern. This approach
allows clients to encode transaction state into additional
redirect URI parameters or to register just a single pattern for
multiple redirect URIs. As a downside, it turned out to be more
complex to implement and error prone to manage than exact
redirect URI matching. Several successful attacks have been
observed in the wild, which utilized flaws in the pattern
matching implementation or concrete configurations. Such a flaw
effectively breaks client identification or authentication
(depending on grant and client type) and allows the attacker to
obtain an authorization code or access token, either
<list style="symbols">
<t>by directly sending the user agent to a URI under the attackers
control or</t>
<t>usually via the client as open redirector in conjunction with
fragment handling (implicit grant) carrying the response including
the respective OAuth credentials.</t>
</list>
</t>
<section title="Authorization Code Grant">
<t>For a public client using the grant type code, an attack
would look as follows: </t>
<t>Let's assume the pattern "https://*.example.com/*" had been registered
for the client "s6BhdRkqt3". This pattern allows redirect URI from any
host residing in the domain example.com. So if an attacker manager to
establish a host or subdomain in "example.com" he can impersonate the
legitimate client. Assume the attacker sets up the host
"evil.example.com".</t>
<t>
<list style="format (%d)" counter="my_count">
<t>The attacker needs to trick the user into opening a tampered URL
in his browser, which launches a page under the attacker's control,
say "https://www.evil.com".</t>
<t>This URL initiates an authorization request with the client id
of a legitimate client to the authorization endpoint. This is the
example authorization request (line breaks are for display purposes only):
</t>
</list>
</t>
<t>
<figure>
<artwork><![CDATA[GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=xyz
&redirect_uri=https%3A%2F%2Fevil.client.example.com%2Fcb HTTP/1.1
Host: server.example.com]]></artwork>
</figure>
</t>
<t>
<list style="format (%d)" counter="my_count">
<t>The authorization validates the redirect URI in order to identify the
client. Since the pattern allows arbitrary domains host names in
"example.com", the authorization request is processed under the legitimate
client's identity. This includes the way the request for user consent is
presented to the user. If auto-approval is allowed (which is not
recommended for public clients according to RFC 6749), the attack can be
performed even easier.</t>
<t>If the user does not recognize the attack, the code is issued and directly
sent to the attacker's client.</t>
<t>Since the attacker impersonated a public client, it can directly exchange
the code for tokens at the respective token endpoint.</t>
</list>
</t>
<t>Note: This attack will not work for confidential clients, since the
code exchange requires authentication with the legitimate client's
secret. The attacker will need to utilize the legitimate client to
redeem the code. This and other kinds of injections are covered in
Section <xref format="title" target="cred_injection"/>.</t>
</section>
<section title="Implicit Grant">
<t>The attack described above for grant type authorization code works
similarly for the implicit grant. If the attacker is able to send the
authorization response to a URI under his control, he will directly get
access to the fragment carrying the access token.</t>
<t>Additionally, it is possible to conduct an attack utilizing the way
user agents treat fragments in case of redirects. User agents re-attach
fragments to the destination URL of a redirect if the location header does not contain a
fragment (see <xref target="RFC7231"/>, section 9.5). In this
attack this behavior is combined with the client as an open redirector
in order to get access to access tokens. This allows circumvention even of
strict redirect URI patterns.</t>
<t>Assume the pattern for client "s6BhdRkqt3" is
"https://client.example.com/cb?*", i.e. any parameter is allowed for
redirects to "https://client.example.com/cb". Unfortunately, the client
exposes an open redirector. This endpoint supports a parameter
"redirect_to", which takes a target URL and will send the browser to
this URL using a HTTP 302.</t>
<t>
<list style="format (%d)" counter="my_count1">
<t>Same as above, the attacker needs to trick the user into opening a
tampered URL in his browser, which launches a page under the attacker's control,
say "https://www.evil.com".</t>
<t>The URL initiates an authorization request, which is very
similar to the attack on the code flow. As differences, it utilizes the
open redirector by encoding "redirect_to=https://client.evil.com" into
the redirect URI and it uses the response type "token" (line breaks
are for display purposes only):</t>
</list>
</t>
<t>
<figure>
<artwork><![CDATA[GET /authorize?response_type=token&client_id=s6BhdRkqt3&state=xyz
&redirect_uri=https%3A%2F%2Fclient.example.com%2Fcb%26redirect_to
%253Dhttps%253A%252F%252Fclient.evil.com%252Fcb HTTP/1.1
Host: server.example.com]]></artwork>
</figure>
</t>
<t>
<list style="format (%d)" counter="my_count1">
<t>Since the redirect URI matches the registered pattern, the authorization server
allows the request and sends the resulting access token with a 302 redirect (some
response parameters are omitted for better readability)</t>
</list>
</t>
<t>
<figure>
<artwork><![CDATA[HTTP/1.1 302 Found
Location: https://client.example.com/cb?
redirect_to%3Dhttps%3A%2F%2Fclient.evil.com%2Fcb
#access_token=2YotnFZFEjr1zCsicMWpAA&...]]></artwork>
</figure>
</t>
<t>
<list style="format (%d)" counter="my_count1">
<t>At the example.com, the request arrives at the open redirector. It will read the
redirect parameter and will issue a HTTP 302 to the URL "https://evil.example.com/cb".</t>
</list>
</t>
<t>
<figure>
<artwork><![CDATA[HTTP/1.1 302 Found
Location: https://client.evil.com/cb]]></artwork>
</figure>
</t>
<t>
<list style="format (%d)" counter="my_count1">
<t>Since the redirector at example.com does not include a fragment in the Location header,
the user agent will re-attach the original fragment <vspace/>"#access_token=2YotnFZFEjr1zCsicMWpAA&..."
to the URL and will navigate to the following URL:</t>
</list>
</t>
<t>
<figure>
<artwork><![CDATA[https://client.evil.com/cb#access_token=2YotnFZFEjr1zCsicMWpAA&...]]></artwork>
</figure>
</t>
<t>
<list style="format (%d)" counter="my_count1">
<t>The attacker's page at client.evil.com can access the fragment and obtain the access token.</t>
</list>
</t>
</section>
<section title="Countermeasure: exact redirect URI matching">
<t>Since the cause of the implementation and management issues is the complexity
of the pattern matching, this document proposes to recommend general use of exact
redirect URI matching instead, i.e. the authorization server shall compare the two
URIs using simple string comparison as defined in <xref target="RFC3986"/>, Section 6.2.1..</t>
<t>This would cause the following impacts:
<list style="symbols">
<t>This change will require all OAuth clients to maintain the transaction state (and XSRF tokens)
in the "state" parameter. This is a normative change to RFC 6749 since section 3.1.2.2 allows for
dynamic URI query parameters in the redirect URI. In order to assess the practical impact, the
working group needs to collect data whether this feature is used in deployed reality today.</t>
<t>The
working group might also consider this change as a step towards improved interoperability for OAuth
implementations since RFC 6749 is somehow vague on redirect URI validation. There is especially no
rule for pattern matching. So one may assume all clients utilizing pattern matching will do so in a
deployment specific way. On the other hand, RFC 6749 already recommends exact matching if the full
URL had been registered.</t>
<t>Clients with multiple redirect URIs need to register all of them explicitly.
<vspace/>Note: clients with just a single redirect URI would not even need to send a redirect URI
with the authorization request. Does it make sense to emphasize this option? Would that further
simplify use of the protocol?</t>
<t>Exact redirect matching does not work for native apps utilizing a local web server due to
dynamic port numbers - at least wild cards for port numbers are required.
<vspace/>Note: Does redirect uri validation solve any problem for native apps? Effective against
impersonation when used in conjunction with claimed HTTPS redirect URIs only.</t>
</list>
</t>
<t>Additional recommendations:
<list style="symbols">
<t>It is also advisable that the domains on which callbacks are hosted should not expose open redirectors (see respective section).</t>
<t>As a further recommendation, clients may drop fragments via intermediary URL with fix fragment
(e.g. https://developers.facebook.com/blog/post/552/) to prevent the user agent from appending any unintended fragments.</t>
</list>
</t>
<t>Alternatives to exact redirect URI matching: authenticate client using digital
signatures (JAR? https://tools.ietf.org/html/draft-ietf-oauth-jwsreq-09), ...</t>
</section>
</section>
<section title="Authorization code leakage via referrer headers">
<t>The section above already discussed use of the referrer header for one kind of attack to obtain
OAuth credentials. It is also possible authorization codes are unintentionally disclosed to attackers,
if a OAuth client renders a page containing links to other pages (ads, faq, ...) as result of a
successful authorization request. </t>
<t>If the user clicks onto one of those links and the target is under the control of an attacker,
it can get access to the response URL in the referrer header.</t>
<t>It is also possible that an attacker injects cross-domain content somehow into the page, such
as <img> (f.e. if this is blog web site etc.): the implication is obviously the same - loading this
content by browser results in leaking referrer with a code.</t>
<section title="Countermeasures">
<t>There are some means to prevent leakage as described above:</t>
<t>
<list style="symbols">
<t>Use of the HTML link attribute rel="noreferrer" (Chrome 52.0.2743.116, FF 49.0.1, Edge 38.14393.0.0, IE/Win10)</t>
<t>Use of the "referrer" meta link attribute (possible values e.g. noreferrer, origin, ...)
(cf. https://w3c.github.io/webappsec-referrer-policy/ - work in progress (seems Google, Chrome and Edge support it))</t>
<t>Redirect to intermediate page (sanitize history) before sending user agent to other pages<vspace/>Note: double
check redirect/referrer header behavior</t>
<t>Use form post mode instead of redirect for authorization response</t>
</list>
</t>
<t>Note: There shouldn't be a referer header when loading HTTP content from a
HTTPS -loaded page (e.g. help/faq pages)</t>
<t>Note: This kind of attack is not applicable to the implicit grant since fragments are not be included in
referrer headers (cf. https://tools.ietf.org/html/rfc7231#section-5.5.2)</t>
</section>
</section>
<section title="Code in browser history (TBD)">
<t>When browser navigates to "client.com/redirection_endpoint?code=abcd" as a result
of a redirect from a provider's authorization endpoint.</t>
<t>Proposal for counter-measures: code is one time use, has limited duration, is bound to client id/secret (confidential clients only)</t>
</section>
<section title="Access token in browser history (TBD)">
<t>When a client or just a web site which already has a token deliberately navigates to a page like
provider.com/get_user_profile?access_token=abcdef.. Actually RFC6750 discourages this practice and asks to
transfer tokens via a header, but in practice web sites often just pass access token in query</t>
<t>When browser navigates to client.com/redirection_endpoint#access_token=abcef as a result of a
redirect from a provider's authorization endpoint.</t>
<t>Proposal: replace implicit flow with postmessage communication</t>
</section>
<section title="Access token on bad resource servers (TBD)">
<t>In the beginning, the basic assumption of OAuth 2.0 was that the OAuth client is implemented
for and tightly bound to a certain deployment. It therefore knows the URLs of the authorization
and resource servers upfront, at development/deployment time. So well-known URLs to resource
servers serve as trust anchor. The validation whether the client talks to a legitimate resource
server is based on TLS server authentication (see <xref target="RFC6819"/>, Section 4.5.4).</t>
<t>As OAuth clients nowadays more and more bind dynamically at runtime to authorization and resource
servers, there need to be alternative solutions to ensure clients do not deliver access tokens to
bad resource servers.</t>
<t>...</t>
<t>Potential mitigations:
<list style="symbols">
<t>PoP (https://tools.ietf.org/html/draft-ietf-oauth-pop-architecture-08)</t>
<t>Token Binding (https://tools.ietf.org/html/draft-jones-oauth-token-binding-00)</t>
<t>OAuth Response Metadata (https://tools.ietf.org/html/draft-sakimura-oauth-meta-07)</t>
<t>Resource Indicators (https://tools.ietf.org/html/draft-campbell-oauth-resource-indicators-01)</t>
<t>...</t>
</list>
</t>
</section>
<section title="Mix-Up (TBD)">
<t>Mix-up is another kind of attack on more dynamic OAuth scenarios (or at least
scenarios where a OAuth client interacts with multiple authorization servers). The
goal of the attack is to obtain an authorization code or an access token by
tricking the client into sending those credentials to the attacker (which acts as
MITM between client and authorization server)</t>
<t>A detailed description of the attack and potential counter-measures is
given in cf. https://tools.ietf.org/html/draft-ietf-oauth-mix-up-mitigation-01.</t>
<t>Potential mitigations:
<list style="symbols">
<t>AS returns client_id and its iss in the response. Client compares
this data to AS it believed it sent the user agent to.</t>
<t>ID token (so requires OpenID Connect) carries client id and issuer</t>
<t>register AS-specific redirect URIs, bind transaction to AS</t>
<t>...</t>
</list>
</t>
</section>
</section>
<section anchor="cred_injection" title="OAuth Credentials Injection">
<t>Credential injection means an attacker somehow obtained a valid OAuth
credential (code or token) and is able to utilize this to impersonate the
legitimate resource owner or to cause a victim to access resources under
the attacker's control (XSRF). </t>
<section title="Code Injection">
<t>In such an attack, the adversary attempts to inject a stolen authorization
code into a legitimate client on a device under his control. In the simplest
case, the attacker would want to use the code in his own client. But there
are situations where this might not be possible or intended. Example are:
<list style="symbols">
<t>The code is bound to a particular confidential client and the attacker is
unable to obtain the required client credentials to redeem the code himself and/or</t>
<t>The attacker wants to access certain functions in this particular client. As an example,
the attacker potentially wants to impersonate his victim in a certain app.</t>
<t>Another
example could be that access to the authorization and resource servers is some
how limited to networks, the attackers is unable to access directly.</t>
</list>
</t>
<t>How does an attack look like?</t>
<t>
<list style="format (%d)">
<t>The attacker obtains an authorization code by executing any of the attacks described
above (<xref format="title" target="cred_leakage"/>).</t>
<t>It performs an OAuth authorization process with the legitimate client on his device.</t>
<t>The attacker injects the stolen authorization code in the response of the
authorization server to the legitimate client.</t>
<t>The client sends the code to the authorization server's token endpoint,
along with client id, client secret and actual redirect_uri.</t>
<t>The authorization server checks the client secret, whether the code was issued to the
particular client and whether the actual redirect URI matches the redirect_uri parameter.</t>
<t>If all checks succeed, the authorization server issues access and other tokens
to the client. </t>
<t>The attacker just impersonated the victim.</t>
</list>
</t>
<t>Obviously, the check in step (5) will fail, if the code was issued to
another client id, e.g. a client set up by the attacker.</t>
<t>An attempt to inject a code obtained via a malware pretending to be the legitimate client
should also be detected, if the authorization server stored the complete redirect URI used
in the authorization request and compares it with the redirect_uri parameter.</t>
<t><xref target="RFC6749"/>, Section 4.1.3, requires the AS to ...
"ensure that the "redirect_uri"
parameter is present if the "redirect_uri" parameter was included in the initial
authorization request as described in Section 4.1.1, and if included ensure that
their values are identical." In the attack scenario described above, the legitimate
client would use the correct redirect URI it always uses for authorization requests.
But this URI would not match the tampered redirect URI used by the attacker (otherwise,
the redirect would not land at the attackers page). So the authorization server would
detect the attack and refuse to exchange the code.</t>
<t>Note: this check could also detect attempt to inject a code, which had been obtained
from another instance of the same client on another device, if certain conditions are fulfilled:
<list style="symbols">
<t>the redirect URI itself needs to contain a nonce or another kind of one-time use, secret data and</t>
<t>the client has bound this data to this particular instance</t>
</list>
</t>
<t>But this approach conflicts with the idea to enforce exact redirect URI matching
at the authorization endpoint. Moreover, it has been observed that providers very often ignore the
redirect_uri check requirement at this stage, maybe, because it doesn't seem to be security-critical
from reading the spec.</t>
<t>Other providers just pattern match the redirect_uri parameter against the registered
redirect URI pattern. This saves the authorization server from storing the link between the
actual redirect URI and the respective authorization code for every transaction. But this kind of
check obviously does not fulfill the intent of the spec, since the tampered redirect URI is not
considered. So any attempt to inject a code obtained using the client_id of a legitimate client
or by utilizing the legitimate client on another device won't be detected in the respective deployments.</t>
<t>It is also assumed that the requirements defined in <xref target="RFC6749"/>, Section 4.1.3,
increase client implementation
complexity as clients need to memorize or re-construct the correct redirect URI for the call
to the tokens endpoint.</t>
<t>The authors therefore propose to the working group to drop this feature in favor of more
effective and (hopefully) simpler approaches to code injection prevention as described in the
following section.</t>
<section title="Proposed Counter Measures">
<t>The general proposal is to bind every particular authorization code to a certain client on a
certain device (or in a certain user agent) in the context of a certain transaction.
There are multiple technical solutions to achieve this goal:</t>
<t>
<list hangIndent="8" style="hanging">
<t hangText="Nonce">OpenID Connect's existing "nonce" parameter is used for this purpose.
The nonce value is one time use and created by the client. The client is supposed to bind
it to the user agent session and sends it with the initial request to the OpenId Provider
(OP). The OP associates the nonce to the authorization code and attests this binding in the
ID token, which is issued as part of the code exchange at the token endpoint. If an attacker
injected an authorization code in the authorization response, the nonce value in the client
session and the nonce value in the ID token will not match and the attack is detected.
assumption: attacker cannot get hold of the user agent state on the victims device, where he
has stolen the respective authorization code.
<vspace/>
pro:
<vspace/>
- existing feature, used in the wild
<vspace/>
con:
<vspace/>
- OAuth does not have an ID Token - would need to push that down the stack</t>
<t hangText="State">It has been discussed in the security workshop in December to use
the OAuth state value much similar in the way as described above. In the case of the
state value, the idea is to add a further parameter state to the code exchange request.
The authorization server then compares the state value it associated with the code and the
state value in the parameter. If those values do not match, it is considered an attack and
the request fails. Note: a variant of this solution would be send a hash of the state (in
order to prevent bulky requests and DoS).
<vspace/>
pro:
<vspace/>
- use existing concept
<vspace/>
con:
<vspace/>
- state needs to fulfil certain requirements (one time use, complexity)
<vspace/>- new parameter means normative spec change</t>
<t hangText="PKCE">Basically, the PKCE challenge/verifier could be used in the
same way as Nonce or State. In contrast to its original intention, the verifier
check would fail although the client uses its correct verifier but the code is
associated with a challenge, which does not match.
<vspace/>
pro:
<vspace/>
- existing and deployed OAuth feature
<vspace/>
con:
<vspace/>
- currently used and recommended for native apps, not web apps</t>
<t hangText="Token Binding">Code must be bind to UA-AS and UA-Client legs -
requires further data (extension to response) to manifest binding id for
particular code.
<vspace/>Note: token binding could be used in conjunction with
PKCE as an option (https://tools.ietf.org/html/draft-campbell-oauth-tbpkce).
<vspace/>
pro:
<vspace/>
- highly secure
<vspace/>
con:
<vspace/>
- highly sophisticated, requires browser support, will it work for native apps?</t>
<t hangText="per instance client id/secret">...</t>
</list>
</t>
<t>Note on pre-warmed secrets: An attacker can circumvent the counter-measures described
above if he is able to create the respective secret on a device under his control, which
is then used in the victim's authorization request.
<vspace/>Exact redirect URI matching of authorization requests can prevent the attacker
from using the pre-warmed secret in the faked authorization transaction on the victim's
device.
<vspace/>Unfortunately it does not work for all kinds of OAuth clients. It is effective
for web and JS apps, for native apps with claimed URLs. What about other native apps?
Treat nonce or PKCE challenge as replay detection tokens (needs to ensure cluster-wide one-time use)?</t>
</section>
<section title="Access Token Injection (TBD)">
<t>Note: An attacker in possession of an access token can access any resources the
access token gives him the permission to. This kind of attacks simply illustrates the fact
that bearer tokens utilized by OAuth are reusable similar to passwords unless they are
protected by further means.
<vspace/>(where do we treat access token replay/use at the resource server?
https://tools.ietf.org/html/rfc6819#section-4.6.4 has some text about it but is it sufficient?)</t>
<t>The attack described in this section is about injecting a stolen access token into
a legitimate client on a device under the adversaries control. The attacker wants to
impersonate a victim and cannot use his own client, since he wants to access certain
functions in this particular client.</t>
<t>Proposal: token binding, hybrid flow+nonce(OIDC), other cryptographical
binding between access token and user agent instance</t>
</section>
<section title="XSRF (TBD)">
<t>injection of code or access token on a victim's device (e.g. to
cause client to access resources under the attacker's control)</t>
<t>mitigation: XSRF tokens (one time use) w/ user agent binding
(cf. https://www.owasp.org/index.php/CrossSite_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet)</t>
</section>
</section>
</section>
<section anchor="other" title="Other Attacks">
<t>Using the AS as Open Redirector - error handling AS (redirects) (draft-ietf-oauth-closing-redirectors-00)</t>
<t>Using the Client as Open Redirector</t>
<t>redirect via status code 307 - use 302</t>
</section>
<section title="Other Topics">
<t>why to rotate refresh tokens</t>
<t>how to support multi AS per RS</t>
<t>...</t>
<t>differentiate native, JS and web clients</t>
<t>federated login to apps (code flow to own AS in browser and federated login to 3rd party IDP in browser)</t>
</section>
<section anchor="Acknowledgements" title="Acknowledgements">
<t>We would like to thank ... for their valuable feedback.</t>
</section>
<section anchor="IANA" title="IANA Considerations">
<t>This draft includes no request to IANA.</t>
</section>
<section anchor="Security" title="Security Considerations">
<t>All relevant security considerations have been given in the
functional specification.</t>
</section>
</middle>
<back>
<references title="Normative References">
<?rfc include="reference.RFC.3986"?>
<?rfc include="reference.RFC.6749"?>
<?rfc include="reference.RFC.6750"?>
<?rfc include="reference.RFC.6819"?>
<?rfc include="reference.RFC.7231"?>
</references>
<!--
<references title="Informative References">
</references> -->
<section anchor="History" title="Document History">
<t>[[ To be removed from the final specification ]]</t>
<t>-01 <list style="symbols">
<t>Added references to mitigation methods for token leakage</t>
<t>Added reference to Token Binding for Authorization Code</t>
</list></t>
</section>
</back>
</rfc>