Subject: [OAUTH-WG] Redirection in authorization code flow: GET vs POST

From: Josh Mandel <[email-masked]>
Date: Fri, 11 Aug 2017 16:00:10 -0400

Hi All,

I've just encountered a server that performs a redirect (back to the
client's redirect_uri) via POST instead of GET. This was surprising
behavior to me and broke my client implementation — but citing chapter and
verse, the server developer pointed out that
https://tools.ietf.org/html/rfc6749#section-1.7 says

While the examples in this specification show the use of the HTTP 302
> status code, any other method available via the user-agent to accomplish
> this redirection is allowed and is considered to be an implementation
> detail.

Is triggering a POST-based redirect (e.g. with this technique
<https://gist.github.com/jmandel/4704d1efed8578a67a6f9b600ffd0c63)>) to the
redirect_url (including url query parameters for state and code) indeed
considered a "method available via the user-agent to accomplish this
redirection"? In other words, should a well-behaved OAuth client be
prepared to receive GETs as well as POSTs to its redirect_uri? If so, what
would be the considerations for a server choosing between GET and POST?

Best,

  Josh

---

From: Josh Mandel <[email-masked]>
Date: Fri, 11 Aug 2017 16:08:11 -0400

Fixing my "with this technique" url: it should have been
https://gist.github.com/jmandel/4704d1efed8578a67a6f9b600ffd0c63 .

On Fri, Aug 11, 2017 at 4:00 PM, Josh Mandel <[email-masked]> wrote:

> verse, the server developer pointed out that https://tools.ietf.org/
> html/rfc6749#section-1.7 says
>
> <https://gist.github.com/jmandel/4704d1efed8578a67a6f9b600ffd0c63)>) to
> the redirect_url (including url query parameters for state and code) indeed

---

From: Jim Manico <[email-masked]>
Date: Fri, 11 Aug 2017 15:17:28 -0500

I would take it a step further. GET's leak parameters even over HTTPS. I advise all GET based OAuth communication to be switched to POST, a much more security centric verb.

Aloha,
--
Jim Manico

> On Aug 11, 2017, at 3:08 PM, Josh Mandel <[email-masked]> wrote:
> 
> Fixing my "with this technique" url: it should have been https://gist.github.com/jmandel/4704d1efed8578a67a6f9b600ffd0c63 .
> 
>> I've just encountered a server that performs a redirect (back to the client's redirect_uri) via POST instead of GET. This was surprising behavior to me and broke my client implementation — but citing chapter and verse, the server developer pointed out that https://tools.ietf.org/html/rfc6749#section-1.7 says 
>> 
>>> While the examples in this specification show the use of the HTTP 302 status code, any other method available via the user-agent to accomplish this redirection is allowed and is considered to be an implementation detail.
>> 
>> Is triggering a POST-based redirect (e.g. with this technique) to the redirect_url (including url query parameters for state and code) indeed considered a "method available via the user-agent to accomplish this redirection"? In other words, should a well-behaved OAuth client be prepared to receive GETs as well as POSTs to its redirect_uri? If so, what would be the considerations for a server choosing between GET and POST?
>> 
>> Best,
>> 
>>   Josh
> 
> _______________________________________________
> OAuth mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/oauth

---

From: John Bradley <[email-masked]>
Date: Fri, 11 Aug 2017 16:18:49 -0400

OpenID Connect formally defined a POST response mode.

http://openid.net/specs/oauth-v2-form-post-response-mode-1_0.html <http://openid.net/specs/oauth-v2-form-post-response-mode-1_0.html>

The OAuth 2 spec docent preclude it.  

The safest thing for a client is to accept both.  
The main advantages of POST is that it docent leak in the referrer, and can handle larger responses without the browser choking in some cases.

Size is more of an issue in Connect where a id_token may be returned in the front channel and POST allows for the larger response without the client needing to have JS extract the fragment.

That is why Connect defined it and OAuth largely assumes that for code get is OK.
For security GET responses should add headers to prevent referrer from leaking the code.

We are adding advice on that to the Security document that is being updated now.

John B.

> On Aug 11, 2017, at 4:08 PM, Josh Mandel <[email-masked]> wrote:
> 
> Fixing my "with this technique" url: it should have been https://gist.github.com/jmandel/4704d1efed8578a67a6f9b600ffd0c63 <https://gist.github.com/jmandel/4704d1efed8578a67a6f9b600ffd0c63> .
> 
> On Fri, Aug 11, 2017 at 4:00 PM, Josh Mandel <[email-masked] <mailto:[email-masked]>> wrote:
> Hi All,
> 
> I've just encountered a server that performs a redirect (back to the client's redirect_uri) via POST instead of GET. This was surprising behavior to me and broke my client implementation — but citing chapter and verse, the server developer pointed out that https://tools.ietf.org/html/rfc6749#section-1.7 <https://tools.ietf.org/html/rfc6749#section-1.7> says 
> 
> Is triggering a POST-based redirect (e.g. with this technique <https://gist.github.com/jmandel/4704d1efed8578a67a6f9b600ffd0c63)>) to the redirect_url (including url query parameters for state and code) indeed considered a "method available via the user-agent to accomplish this redirection"? In other words, should a well-behaved OAuth client be prepared to receive GETs as well as POSTs to its redirect_uri? If so, what would be the considerations for a server choosing between GET and POST?
> 
> Best,
> 
>   Josh
>

---

From: Jim Manico <[email-masked]>
Date: Sat, 12 Aug 2017 09:55:03 -0500

> The _*safest*_ thing for a client is to accept both. 

I politely (and strongly) disagree with this statement. The safest thing
for a client is to only accept POST or other verbs where any kind of
sensitive data is NOT kept in the URL. Sensitive data in URL's leak like
a sieve, even over HTTPS.

Respectfully,
Jim

On 8/11/17 3:18 PM, John Bradley wrote:
> http://openid.net/specs/oauth-v2-form-post-response-mode-1_0.html
>
> The main advantages of POST is that it docent leak in the referrer,
> and can handle larger responses without the browser choking in some cases.
>
> Size is more of an issue in Connect where a id_token may be returned
> in the front channel and POST allows for the larger response without
> the client needing to have JS extract the fragment.
>
>> On Aug 11, 2017, at 4:08 PM, Josh Mandel <[email-masked]
>> <mailto:[email-masked]>> wrote:
>>
>>     I've just encountered a server that performs a redirect (back to
>>     the client's redirect_uri) via POST instead of GET. This was
>>     surprising behavior to me and broke my client implementation —
>>     but citing chapter and verse, the server developer pointed out
>>     that https://tools.ietf.org/html/rfc6749#section-1.7
>>     <https://tools.ietf.org/html/rfc6749#section-1.7> says 
>>
>>         While the examples in this specification show the use of the
>>         HTTP 302 status code, any other method available via the
>>         user-agent to accomplish this redirection is allowed and is
>>         considered to be an implementation detail.
>>
>>
>>     <https://gist.github.com/jmandel/4704d1efed8578a67a6f9b600ffd0c63%29>)
>>     to the redirect_url (including url query parameters for state and
>>     code) indeed considered a "method available via the user-agent to
>>     accomplish this redirection"? In other words, should a
>>     well-behaved OAuth client be prepared to receive GETs as well as
>>     POSTs to its redirect_uri? If so, what would be the
>>     considerations for a server choosing between GET and POST?
>>
>>     Best,
>>
>>       Josh
>>
>>
>> [email-masked] <mailto:[email-masked]>

-- 
Jim Manico
Manicode Security
https://www.manicode.com

---

From: John Bradley <[email-masked]>
Date: Sat, 12 Aug 2017 12:43:40 -0400

>From a interoperability perspective accepting both is best.

Get is mostly OK with the correct headers to stop referer leakage.
Fragment should only be used with real JS clients in the browser and not
with servers.

That is the general direction of the new security advice.

People wanting to use POST should probably follow the connect spec for
response mode to be explicit about it.

John B.

On Aug 12, 2017 10:55, "Jim Manico" <[email-masked]> wrote:

> > The *safest* thing for a client is to accept both.
>
> sensitive data is NOT kept in the URL. Sensitive data in URL's leak like a
> sieve, even over HTTPS.
> Respectfully,
> Jim
>
>
>
> The main advantages of POST is that it docent leak in the referrer, and
> can handle larger responses without the browser choking in some cases.
>
> Size is more of an issue in Connect where a id_token may be returned in
> the front channel and POST allows for the larger response without the
> client needing to have JS extract the fragment.
>
>> verse, the server developer pointed out that https://tools.ietf.org/ht
>> ml/rfc6749#section-1.7 says
>>
>> to the redirect_url (including url query parameters for state and code)
>> indeed considered a "method available via the user-agent to accomplish this
> OAuth mailing [email-masked]://www.ietf.org/mailman/listinfo/oauth
>
>
> --
> Jim Manico
> Manicode Securityhttps://www.manicode.com
>
>

---

From: Jim Manico <[email-masked]>
Date: Sat, 12 Aug 2017 14:00:22 -0500

> Get is mostly OK with the correct headers to stop referrer leakage.

Those work in new-ish browsers only. Referrer is only one GET leakage vector.

>  Fragment should only be used with real JS clients in the browser and not with servers.  

Fragment behavior is very different in modern browsers, which is one reason why many security folks recommend against the implicit grant type. (I'll double check on this one)

Respectfully,
--
Jim Manico
@Manicode

> On Aug 12, 2017, at 11:43 AM, John Bradley <[email-masked]> wrote:
> 
> Get is mostly OK with the correct headers to stop referer leakage.   Fragment should only be used with real JS clients in the browser and not with servers.  
> 
> People wanting to use POST should probably follow the connect spec for response mode to be explicit about it.  
> 
> John B. 
> 
>> I politely (and strongly) disagree with this statement. The safest thing for a client is to only accept POST or other verbs where any kind of sensitive data is NOT kept in the URL. Sensitive data in URL's leak like a sieve, even over HTTPS.
>> 
>> Respectfully,
>> Jim
>> 
>>

---

From: Thomas Broyer <[email-masked]>
Date: Sun, 13 Aug 2017 15:20:49 +0000

Rejecting a GET with code in the URL means that the code is never "used" at
the AS, so can still be exchanged for an access token; and rejecting the
request does not mean it won't leak. So reject if you like from the user's
point of view, but "consume" the code anyway (and then immediately revoke
the token, maybe), or you're probably making things worse (if you're
worried of leaking 5min one-time codes, particularly when that code cannot
be used without a client_secret and/or PKCE code_verifier)

Disclaimer: not a security expert here.

---

From: Jim Manico <[email-masked]>
Date: Sun, 13 Aug 2017 12:36:54 -0400

> Rejecting a GET with code in the URL means that the code is never
"used" at the AS, so can still be exchanged for an access token; and
rejecting the request does not mean it won't leak

That's a good point Thomas. I still think secure OAuth workflows should
totally avoid putting any kind of sensitive data in URI's for any step,
including POST /Actions/ that leak like a GET query parameter.

> So reject if you like from the user's point of view, but "consume" the
code anyway (and then immediately revoke the token, maybe), or you're
probably making things worse

Interesting point, but I think if the standard reflected this suggestion
it would be less likely that implementer will do it.

> (if you're worried of leaking 5min one-time codes, particularly when that code cannot be used without a client_secret
and/or PKCE code_verifier)

Also a good point. This specific step in the workflow might not be at
risk as much as other steps, but I see a LOT of folks putting sensitive
data in tokens and I'm trying to help avoid that leakage.

Thanks for your feedback.

Aloha, Jim

On 8/13/17 11:20 AM, Thomas Broyer wrote:
> Rejecting a GET with code in the URL means that the code is never
> "used" at the AS, so can still be exchanged for an access token; and
> rejecting the request does not mean it won't leak. So reject if you
> like from the user's point of view, but "consume" the code anyway (and
> then immediately revoke the token, maybe), or you're probably making
> things worse (if you're worried of leaking 5min one-time codes,
> particularly when that code cannot be used without a client_secret
> and/or PKCE code_verifier)
>
> Le sam. 12 août 2017 16:55, Jim Manico <[email-masked]
> <mailto:[email-masked]>> a écrit :
>
>     I politely (and strongly) disagree with this statement. The safest
>     thing for a client is to only accept POST or other verbs where any
>     kind of sensitive data is NOT kept in the URL. Sensitive data in
>     URL's leak like a sieve, even over HTTPS.
>
>     Respectfully,
>     Jim
>
>
>
>>     The main advantages of POST is that it docent leak in the
>>     referrer, and can handle larger responses without the browser
>>     choking in some cases.
>>
>>     Size is more of an issue in Connect where a id_token may be
>>     returned in the front channel and POST allows for the larger
>>     response without the client needing to have JS extract the fragment.
>>
>>>         I've just encountered a server that performs a redirect
>>>         (back to the client's redirect_uri) via POST instead of GET.
>>>         This was surprising behavior to me and broke my client
>>>         implementation — but citing chapter and verse, the server
>>>         developer pointed out
>>>         that https://tools.ietf.org/html/rfc6749#section-1.7 says 
>>>
>>>             While the examples in this specification show the use of
>>>             the HTTP 302 status code, any other method available via
>>>             the user-agent to accomplish this redirection is allowed
>>>             and is considered to be an implementation detail.
>>>
>>>
>>>         to the redirect_url (including url query parameters for
>>>         state and code) indeed considered a "method available via
>>>         the user-agent to accomplish this redirection"? In other
>>>         words, should a well-behaved OAuth client be prepared to
>>>         receive GETs as well as POSTs to its redirect_uri? If so,
>>>         what would be the considerations for a server choosing
>>>         between GET and POST?
>>>
>>>         Best,
>>>
>>>           Josh
>>>
>>>

-- 
Jim Manico
Manicode Security
https://www.manicode.com