On 8 Dec 2020, at 22:47, Brian Campbell
<bcampb...@pingidentity.com
<mailto:bcampb...@pingidentity.com>> wrote:
Danial recently added some text to the working copy of the
draft with
https://github.com/danielfett/draft-dpop/commit/f4b42058
<https://github.com/danielfett/draft-dpop/commit/f4b42058>
that I think aims to better convey the "nutshell: XSS = Game
over" sentiment and maybe dissuade folks from looking to
DPoP as a cure-all for browser based applications.
Admittedly a lot of the initial impetus behind producing the
draft in the first place was born out of discussions around
browser based apps. But it's neither specific to browser
based apps nor a panacea for them. I hope the language in
the document and how it's recently been presented is
reflective of that reality.
The more specific discussions/recommendations around
in-browser apps are valuable (if somewhat over my head) but
might be more appropriate in the OAuth 2.0 for Browser-Based
Apps
<https://datatracker.ietf.org/doc/draft-ietf-oauth-browser-based-apps/>
draft.
With respect to the contents of the DPoP draft, I am still
keen to try and flush out some consensus around the question
posed in the start of this thread, which is effectively
whether or not to include a hash of the access token in the
proof. Acknowledging that "XSS = Game over" does sort of
evoke a tendency to not even bother with such incremental
protections (what I've tried to humorously coin as "XSS
Nihilism" with no success). And as such, I do think that
leaving it how it is (no AT hash in the proof) is not
unreasonable. But, as Filip previously articulated,
including the AT hash in the proof would prevent potentially
prolonged access to protected resources even when the victim
is offline. And that seems maybe worthwhile to have in the
protocol, given that it's not a huge change to the spec. But
it's a trade-off either way and I'm personally on the fence
about it.
Including an RT hash in the proof seems more niche. Best I
can tell, it would guard against prolonged offline access to
protected resources when access tokens are bearer and the RT
was DPoP-bound and also gets rotated. The trade-off there
seems less worth it (I think an RT hash would be more
awkward in the protocol too).
On Fri, Dec 4, 2020 at 5:40 AM Philippe De Ryck
<phili...@pragmaticwebsecurity.com
<mailto:phili...@pragmaticwebsecurity.com>> wrote:
The suggestion to use a web worker to ensure that
proofs cannot be pre-computed is a good one I think.
(You could also use a sandboxed iframe for a separate
sub/sibling-domain - dpop.example.com
<http://dpop.example.com/>).
An iframe with a different origin would also work (not
really sandboxing, as that implies the use of the
sandbox attribute to enforce behavioral restrictions).
The downside of an iframe is the need to host additional
HTML, vs a script file for the worker, but the effect is
indeed the same.
For scenario 4, I think this only works if the attacker
can trick/spoof the AS into using their redirect_uri?
Otherwise the AC will go to the legitimate app which
will reject it due to mismatched state/PKCE. Or are you
thinking of XSS on the redirect_uri itself? I think
probably a good practice is that the target of a
redirect_uri should be a very minimal and locked down
page to avoid this kind of possibility. (Again, using a
separate sub-domain to handle tokens and DPoP seems
like a good idea).
My original thought was to use a silent flow with Web
Messaging. The scenario would go as follows:
1. Setup a Web Messaging listener to receive the
incoming code
2. Create a hidden iframe with the DOM APIs
3. Create an authorization request such as
“//authorize?response_type=code&client_id=...&redirect_uri=https%3A%2F%example.com
<http://example.com/>&state=...&code_challenge=7-ffnU1EzHtMfxOAdlkp_WixnAM_z9tMh3JxgjazXAk&code_challenge_method=S256&prompt=none&response_mode=web_message/”
4. Load this URL in the iframe, and wait for the result
5. Retrieve code in the listener, and use PKCE (+ DPoP
if needed) to exchange it for tokens
This puts the attacker in full control over every aspect
of the flow, so no need to manipulate any of the parameters.
After your comment, I also believe an attacker can run
the same scenario without the
“/response_mode=web_message/”. This would go as follows:
1. Create a hidden iframe with the DOM APIs
2. Setup polling to read the URL (this will be possible
for same-origin pages, not for cross-origin pages)
3. Create an authorization request such as
“//authorize?response_type=code&client_id=...&redirect_uri=https%3A%2F%example.com
<http://example.com/>&state=...&code_challenge=7-ffnU1EzHtMfxOAdlkp_WixnAM_z9tMh3JxgjazXAk&code_challenge_method=S256/”
4. Load this URL in the iframe, and keep polling
5. Detect the redirect back to the application with the
code in the URL, retrieve code, and use PKCE (+ DPoP if
needed) to exchange it for tokens
In step 5, the application is likely to also try to
exchange the code. This will fail due to a mismatching
PKCE verifier. While noisy, I don’t think it affects the
scenario.
IMO, the online attack scenario (i.e., proxying
malicious requests through the victim’s browser) is
quite appealing to an attacker, despite the apparent
inconvenience:
- the victim’s browser may be inside a corporate
firewall or VPN, allowing the attacker to effectively
bypass these restrictions
- the attacker’s traffic is mixed in with the user’s
own requests, making them harder to distinguish or to block
Overall, DPoP can only protect against XSS to the same
level as HttpOnly cookies. This is not nothing, but it
means it only prevents relatively naive attacks. Given
the association of public key signatures with strong
authentication, people may have overinflated
expectations if DPoP is pitched as an XSS defence.
Yes, in the cookie world this is known as “Session
Riding”. Having the worker for token isolation would
make it possible to enforce a coarse-grained policy on
outgoing requests to prevent total abuse of the AT.
My main concern here is the effort of doing DPoP in a
browser versus the limited gains. It may also give a
false sense of security.
With all this said, I believe that the AS can lock down
its configuration to reduce these attack vectors. A few
initial ideas:
1. Disable silent flows for SPAs using RT rotation
2. Use the sec-fetch headers to detect and reject
non-silent iframe-based flows
For example, an OAuth 2.0 flow in an iframe in
Brave/Chrome carries these headers:
/
sec-fetch-dest: iframe
sec-fetch-mode: navigate
sec-fetch-site: cross-site
sec-fetch-user: ?1
/
Philippe
/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./