I was mentioning it primarily as another example of the assumption that GET 
requests are safe. However, the draft rfc6265bis [1] does seem concerned about 
this, and mentions <link rel=prerender> as a possible attack vector. This would 
again potentially pull the access token into the renderer’s memory space (until 
site isolation becomes widespread). 

I also have a general dislike of SameSite cookies as a defence against CSRF. 
There are CSRF-like attacks that are not strictly cross-*site* but are 
cross-origin (CORF?). For example, subdomain hijacking is relatively common [2] 
and completely defeats SameSite. As the draft itself says [3]:

<quote>

   "SameSite" cookies offer a robust defense against CSRF attack when
   deployed in strict mode, and when supported by the client.  It is,
   however, prudent to ensure that this designation is not the extent of
   a site's defense against CSRF, as same-site navigations and
   submissions can certainly be executed in conjunction with other
   attack vectors such as cross-site scripting.

   Developers are strongly encouraged to deploy the usual server-side
   defenses (CSRF tokens, ensuring that "safe" HTTP methods are
   idempotent, etc) to mitigate the risk more fully.
</quote>

If we recommend SameSite for this, IMO we should do so only with the same 
caveats expressed in the httpbis draft. 

[1]: 
https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-07#section-5.3.7.1
[2]: https://www.hackerone.com/blog/Guide-Subdomain-Takeovers#
[3]: https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-07#section-8.8.1

Cheers,

Neil

> On 19 Feb 2021, at 23:18, Brian Campbell <bcampb...@pingidentity.com> wrote:
> 
> 
> Thanks Neil, 
> Appreciate the insight and recommendations. I think we can incorporate that, 
> more or less, into the next revision. 
> One point to dig into just a bit more, you said that 'SameSite has a "GET-out 
> clause" in the form of “lax”'. As I understand it, such a cookie would still 
> only be sent on a cross-site GET resulting from a top-level  navigation. And 
> in the context of the bff-token endpoint, that significantly reduces the ways 
> a cross-site request could be initiated and those ways (pop-up or full page 
> redirection) further limits the likelihood of the malicious party being able 
> to read response data. 
> 
>> On Thu, Feb 18, 2021 at 5:08 AM Neil Madden <neil.mad...@forgerock.com> 
>> wrote:
>> Thanks for following up, Brian. Responses below.
>> 
>>> On 17 Feb 2021, at 22:48, Brian Campbell <bcampb...@pingidentity.com> wrote:
>>> 
>>> Always appreciate (and often learn from) your insights, Neil. I'd like to 
>>> dig into the CSRF thing a bit more though to understand better and 
>>> hopefully do the right thing in the draft. 
>>> 
>>> It seems to me that a GET at the bff-token endpoint is "safe" in that it's 
>>> effectively just a read.
>> 
>> Well it’s a read that returns an access token. It’s “safe” in the sense of 
>> side-effects, but we absolutely want to preserve the confidentiality of what 
>> is returned and only allow it to be accessed by authorized clients (the 
>> legitimate frontend). At the moment the only thing keeping that safe is the 
>> JSON content type. For example, imagine a world in which the token-bff 
>> endpoint instead returned the access token as HTML:
>> 
>> <div id=“accessToken”>abcd</div>
>> 
>> Then as an attacker I can simply embed an iframe on my site that refers to 
>> your bff-endpoint and then parse the access token out of the DOM. The 
>> browser will happily load that iframe and send along the cookie when it 
>> makes the request. If you have CORS enabled on your site (with 
>> Access-Control-Allow-Credentials) then any of the allowed CORS origins can 
>> directly call the bff-token endpoint and read the access token even in JSON 
>> form. There have also been historical same-origin policy bypasses using 
>> Flash, Adobe Reader, or other plugins (thankfully now largely eliminated), 
>> or by redefining JavaScript prototypes - see 
>> https://haacked.com/archive/2009/06/25/json-hijacking.aspx/ . These are 
>> largely fixed, but I wouldn’t bet on there never being another one.
>> 
>> 
>>> There could be a "cache miss" where the backend attempts to use a refresh 
>>> token it has to get a new access token from the remote AS, which will be 
>>> more resource intensive but doesn't fundamentally alter the state of the 
>>> backend so is still "safe". That in conjunction with your pointing to 
>>> Cross-Origin Read Blocking makes me think your concern isn't so much about 
>>> traditional CSRF used to take some malicious action but rather about 
>>> somehow (speculative side-channel attacks, problems with javascript 
>>> interpreters, other similar vectors that are somewhat beyond me) accessing 
>>> the data of the response to a forged cross site request. Correct me if I'm 
>>> wrong. I don't know if or how much the distinction matters in terms of 
>>> mitigation approach but I'm keen to better understand.  
>> 
>> As explained above, because the endpoint returns JSON it _should_ be 
>> impossible to directly read the response from a cross-origin read (unless 
>> explicitly enabled with CORS). But you may still be able to embed that 
>> response in an <img> or similar. Because people are terrible at setting 
>> correct Content-Type headers on responses, browsers often ignore them and 
>> instead try to sniff what the real content type is: so if the response looks 
>> a bit like a valid image format (or PDF or JavaScript or whatever) then it 
>> might try and render it. No doubt this will fail, but at that point the data 
>> has already been loaded into the address space of the renderer process for 
>> the attacker’s site. That means that it is then vulnerable to attacks like 
>> Spectre that bypass normal memory protection. The browser vendors consider 
>> this to be a real threat, hence CORB.
>> 
>> The most important thing for a cookie-based JSON API to do is to return a 
>> correct Content-Type header and to also return X-Content-Type-Options: 
>> nosniff to prevent browsers from trying to sniff the real content-type. (I 
>> have an example in my book where the failure to do this can actually turn a 
>> JSON API into a vector for XSS attacks, even if you have no SPA frontend 
>> component at all).
>> 
>> (You should also mark the cookie as HttpOnly because this prevents the 
>> cookie ever entering the address space of a renderer process in modern 
>> browsers - an actual genuine security benefit of HttpOnly cookies).
>> 
>> But my worry is that this is still basically trusting the client to perform 
>> critical security checks, and historically browsers have had plenty of 
>> bypasses in this area. So for something as high-value as an access token I’d 
>> prefer that any request using cookie-based authentication is protected by 
>> proactive CSRF defences to prevent malicious requests being allowed in the 
>> first place.
>> 
>>> 
>>> It sounds like your preference for only POST rests in an assumption that 
>>> the larger app will already have in place some CSRF defenses and by using 
>>> POST the bff-token endpoint will basically inherit said defenses. Or is 
>>> POST by itself good enough (the CORB writeup seems to suggest that the 
>>> context in which a POST could be made is more guarded against side channel 
>>> stuff)?  But perhaps then the draft should be more explicit about CSRF 
>>> defense? Saying it just has to be done. Or like even mandating a 
>>> non-standard header be in the request, "X-Neil-says-beware-CSRF: yuppers" 
>>> as a strawman. With such a header it could remain a GET. And I kinda like 
>>> GET because it is really a request for data.  Or perhaps the request should 
>>> be a POST with built-in CSRF protection by changing it to carry any 
>>> parameters as JSON in the body with "{}" for the case of no parameters 
>>> specified?  Or just make it a PUT and call it good? Not sure any of these 
>>> are good ideas but just trying to hash out the most appropriate thing to 
>>> do. 
>> 
>> Right, the preference for POST is because it's more likely to trigger CSRF 
>> defences, which often consider GET/HEAD requests to be “safe”. Even before 
>> Spectre, there is a whole array of side-channel attacks for extracting 
>> information from cross-site responses: https://xsleaks.dev . Note that even 
>> SameSite has a "GET-out clause" in the form of “lax”.
>> 
>> So yes, the real requirement is that the endpoint should have adequate CSRF 
>> protection. Requiring a special header has had bypasses in the past (again, 
>> mostly using Flash).
>> 
>> So I think we should recommend the following:
>> 
>> 1. The response MUST contain a correct Content-Type: application/json header 
>> and X-Content-Type-Options: nosniff.
>> 2. The cookie SHOULD be marked as HttpOnly.
>> 3. The endpoint MUST NOT be accessible via CORS.
>> 4. The endpoint SHOULD have adequate CSRF protections in place. At a minimum 
>> the cookie should be marked as SameSite. 
>> 
>> We could perhaps add an informational reference to 
>> https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html
>>  given that there is a changing landscape around cookies at the moment. If 
>> the browser vendors do eliminate 3rd-party cookies then 1, 3, and 4 become 
>> largely unnecessary (although 3 might still be a risk due to sub-domain 
>> hijacking, and 1 will always be good practice).
>> 
>> — Neil
>> 
>>> 
>>> That got a little rambly, sorry. But hopefully it makes some sense. 
>>> 
>>>> On Sun, Feb 14, 2021 at 1:17 AM Neil Madden <neil.mad...@forgerock.com> 
>>>> wrote:
>>>> 
>>>> The combination of the bff-token endpoint recommending the use of GET 
>>>> requests together with the hint to use cookie-based authentication is 
>>>> likely going to punch a hole in most CSRF defenses, which assume that GETs 
>>>> are safe. The only thing preventing this being exploitable is Cross-Origin 
>>>> Read Blocking 
>>>> (https://chromium.googlesource.com/chromium/src/+/master/services/network/cross_origin_read_blocking_explainer.md)
>>>>  due to the JSON content-type. That makes me really nervous. We should at 
>>>> least mandate X-Content-Type-Options: nosniff on that response. I’d feel 
>>>> more comfortable if this was a POST request only. 
>>>> 
>>>> — Neil
>>>> 
>>> 
>>> CONFIDENTIALITY NOTICE: This email may contain confidential and privileged 
>>> material for the sole use of the intended recipient(s). Any review, use, 
>>> distribution or disclosure by others is strictly prohibited.  If you have 
>>> received this communication in error, please notify the sender immediately 
>>> by e-mail and delete the message and any file attachments from your 
>>> computer. Thank you.
>> 
>> 
>> ForgeRock values your Privacy
> 
> CONFIDENTIALITY NOTICE: This email may contain confidential and privileged 
> material for the sole use of the intended recipient(s). Any review, use, 
> distribution or disclosure by others is strictly prohibited.  If you have 
> received this communication in error, please notify the sender immediately by 
> e-mail and delete the message and any file attachments from your computer. 
> Thank you.

-- 
ForgeRock values your Privacy <https://www.forgerock.com/your-privacy>
_______________________________________________
OAuth mailing list
OAuth@ietf.org
https://www.ietf.org/mailman/listinfo/oauth

Reply via email to