Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Circumventing Origin restriction with proxies #34

Open
elf-pavlik opened this issue Dec 18, 2018 · 16 comments
Open

Circumventing Origin restriction with proxies #34

elf-pavlik opened this issue Dec 18, 2018 · 16 comments

Comments

@elf-pavlik
Copy link
Member

https://github.com/solid/web-access-control-spec#referring-to-origins-ie-web-apps

When a compliant server receives a request from a web application running in a browser, the browser will send an extra warning HTTP header, the Origin header.

What about cases where 'malicious' app running in a browser uses a proxy to change the Origin header? I think it might work differently with WebID-OIDC and WebID-TLS.

Malicious app still would need to know which 'allowed' origin to use but let's consider scenario where it knows that 'allowed' origin and proxy sets header to it.

@michielbdejong
Copy link
Contributor

For webid-oidc this is not a problem, because the token that the web app obtains is specific to both webid and app origin. A web app can only obtain a token that is tied to its own origin.

For webid-tls, I don't know, I'll find out!

@elf-pavlik
Copy link
Member Author

Do you refer to aud field in ID Token? I don't know how exactly NSS uses it to verify client's origin, maybe @dmitrizagidulin can link to relevant code. I think of a case where NSS acts just as a Resource Server and app/client gets ID Token from some other OP which as I understand handles the client registration.

@jaxoncreed
Copy link

jaxoncreed commented Apr 4, 2019

This is a reason to move towards client-id based origin tokens. User client id as the origin

@elf-pavlik
Copy link
Member Author

solid/webid-oidc-spec#12 should address it, I will close this one once it gets resolved

@gobengo
Copy link

gobengo commented Apr 4, 2019

I have lots of OIDC context, but limited web-access-control.

I threw out a straw man of removing from the spec this (since it might be adding a MUST that allows unauthorized access via proxy)

When an Origin header is present then BOTH the authenticated agent AND the origin MUST be allowed access

Dmitri mentioned that would face resistance as such. But a better alternative should be developed, then this language removed.

A followup proposal that should be less controversial is to add a warning to the spec right before that MUST

WARNING: This normative language is at-risk of removal because it can be exploited. See this issue (link needed) for progress on a safe alternative.

michielbdejong added a commit to michielbdejong/webid-oidc-spec that referenced this issue Jun 18, 2019
Creating this as a placeholder, it's still incomplete in several aspects:
* we should mention somewhere why PoP token issuer is better than Origin header (namely because of solid/web-access-control-spec#34)
* we should mention that a PoP token is only valid if the issuer is listed in the id token's audiences (is this something the IDP checks and then signs for? I don't even know)
@csarven csarven self-assigned this May 17, 2021
@timbl
Copy link

timbl commented Jun 15, 2021

If a bad proxy does not forward the Origin header, then the CORS security is broken by the bad proxy. Don’t use or implement bad proxies. This does not change WAC.

@elf-pavlik
Copy link
Member Author

I'm describing here possibility of application running in a web browser intentionally using properly implemented proxy which by design allows it to advertise whatever Origin party providing the application wants that application to claim on requests.
Party providing (hosting) the application, is the same party which controls the proxy.

@michielbdejong
Copy link
Contributor

Don’t use or implement bad proxies.

But it's not the data owner or the benevolent Solid app developer that is using this bad proxy. In this scenario, it is an evil attacker doing it. And even if we adhere to this ourselves, unfortunately we can't effectively police this for the web as a whole. So I think this issue remains unresolved by the Solid spec as it currently stands.

@csarven
Copy link
Member

csarven commented Jan 14, 2025

I don't mean to undermine the concerns raised here, but it's equally important to ensure the correct interpretation of the published WAC, the Origin header, and related details.

There are too many assumptions in this thread for my liking, but suffice it to say that if a malicious actor has already managed to achieve one or more of the following: authenticate the end-user, have the end-user use a malicious application, have the end-user use a malicious proxy, or gain knowledge of the Authorization, then yes, some malicious activities could occur. However, I doubt this set of conditions or similar ones are uniquely tied to WAC. It would be worth examining whether equivalent concerns are raised in other specifications and go from there.

That said, what https://solid.github.io/web-access-control-spec/#authorization-evaluation-origin , https://solid.github.io/web-access-control-spec/#web-origin-authorization and https://solid.github.io/web-access-control-spec/#security-privacy-review-first-third-party (see also ctrl+f "origin" for more Origin related stuff) details is that if the Origin header field is present in the HTTP request, which is intended as a warning set by the user agent - see for example, https://www.rfc-editor.org/rfc/rfc6454 , https://html.spec.whatwg.org/multipage/browsers.html#origin for why that header is set and what values it can hold - then acl:origin can be used towards the Authorization evaluation.

Based on my understanding which stems from studying numerous issues, reviewing the WAC documentation and implementations to date, engaging in community discussions, and analysing feedback on the specification, a malicious actor wouldn't necessarily need to go to the lengths mentioned above to bypass the origin check. They could simply omit the Origin header field from the request.

@michielbdejong
Copy link
Contributor

michielbdejong commented Jan 15, 2025

Hi Sarven,

[...] then yes, some malicious activities could occur. However, I doubt this set of conditions or similar ones are uniquely tied to WAC.

You're right in principle, but the problem arises from the combination of WAC with dynamic client registration. If an IDP only allows clients such as web browers or data browsers which are trusted to fully impersonate the authenticating agent, then there is no problem, and then acl:origin, when correctly applied, makes sense. But let's consider the common case, where WAC is combined with an IDP that allows dynamic client registration. Then, with no restrictions on clients other than acl:origin triples, there are three possible situations:

  • a) no acl:origin triple is included in an Authorization -> any (dynamically registered) client is allowed to represent the agent
  • b) a matching acl:origin triple is included -> the client is authorized even if an Origin header is present
  • c) a non-matching acl:origin triple is included -> the client is still authorized, but only if it omits the Origin header

This means that effectively an acl:origin triple only excludes a small set of situations, and it is no replacement for actively vetted client registration by the IDP. In that sense, it's not necessarily broken, but it does become a footgun when combined with dynamic client registration. So yes, this worries me. I think we should discuss a number of things:

  1. I would be a little bit less worried if instead of checking the Origin header, we would check the aud field of the identity token used to generate the DPoP token. It's still a bit tricky that the storage is trusting the agent's IDP to vouch for the identity of the client, but I think the trust chain storage -> agent -> IDP -> redirect_uri -> client is sound, as long as the IDP has a non-circumventable way to tell the storage (via the aud field of the identity token that is referenced in the DPoP token) which client it thinks it gave the token to. This would be a spec change which I think we should make.

  2. Another spec change we should consider is the allow-then-deny nature of acl:origin triples. If no acl:origin triple is present for an Authorization, then that means "any origin which has achieved dynamic client registration at the IDP of the agent". Maybe it would be safer if instead the omission would mean "no origin except maybe the same-origin of the storage, and/or the origin of the WebID of the agent".

  3. there is a problem with how some implementations of WAC phrase the consent dialog. It doesn't sufficiently warn the user about the amount of access they are giving to the relying party.

  4. some implementations of WAC silently ignore the acl:origin triples, maybe it would be more secure if they should instead fail hard with some sort of 'not implemented' error, to prevent a false sense of security.

a malicious actor wouldn't necessarily need to go to the lengths mentioned above to bypass the origin check. They could simply omit the Origin header field from the request.

I'm not sure I understand. Which lengths? I interpreted your post as saying acl:origin is pretty safe, but in this statement you seem to be saying that it can be circumvented, and that it's even really simple for the attacker to do so? Maybe I misunderstood.

@timbl
Copy link

timbl commented Jan 15, 2025

The original question is "What about cases where 'malicious' app running in a browser uses a proxy to change the Origin header? " It did not specify who runs the proxy - the bad person or a good person running NSS. If a bad person can run a proxy, then a bad person can run a curl script to do anything anyway. So no new exprosure.

If a good person is running a normal NSS cors-circumventing proxy, then the proxy can always preserve the origin: header which may be in the spec already.

@michielbdejong Origin: headers are designed to protect against malicious Web Apps. That is their only function. They reduce the power of the user, not increase. Web Apps cannot remove the origin header because the browser forces them on. WAC Origin things allow Soldi programs which are trusted to use the CORS headers to actually access other data, as otherwise they are blocked by the browsers, which hate web apps. So it is a Origin: is a double-negative situation. Web apps are specifically more dangerous than anything else because they run without any installation as users browse the web.

@michielbdejong
Copy link
Contributor

michielbdejong commented Jan 15, 2025

Ah, I think I understand the confusion now. This is unrelated to the NSS cors-circumventing proxy. And yes, the bad person could easily choose to use curl or any other tool.

I tried to explain two issues related to acl:origin, of which this is one, in the following two-part video:

In particular in https://youtu.be/Om-ftweaP8g?t=301 talks about how we could securely identify clients if we would implement something like solid/webid-oidc-spec#34 (but our current way of doing it is not secure).

@michielbdejong
Copy link
Contributor

Actually @jaxoncreed pointed me to https://solidproject.org/TR/oidc#tokens-id which explicitly states that the azp claim (not the Origin header) is used to identify clients. I'll create a PR to update this spec to match that.

@michielbdejong
Copy link
Contributor

Should we close this issue in favour of #81? It seems to be a sub-topic of that.

@michielbdejong
Copy link
Contributor

Ah wait, there's something I hadn't realised about WAC acl:origin. It was never intended to replace the need for acl:client.

See this statement from @csarven on that issue:

Current #authorization-evaluation does not observe client identifiers so any client would be granted access. This is not to be conflated with what's intended or constrained with acl:origin!

And explicit statement in the spec:

The presence of the acl:origin property and its value is taken into account in the evaluation only when the HTTP request includes the Origin header (Web Origin Authorization).

And this most recent comment by @woutermont (who actually implemented a fix in CommunitySolidServer/CommunitySolidServer#1537 and then closed that a few years later):

absence of client identification in WAC

And this comment from Henry on the same day proposing another implementation of client identification in WAC.

I think the premise of this issue is (and this was also always my interpretation, and also the premise of the design of our app launcher experiment 6 years ago), that acl:origin was meant to be a form of client identification.

So maybe the real question is: what is acl:originuseful for. And maybe the answer is not: to identify the client.

@michielbdejong
Copy link
Contributor

michielbdejong commented Jan 16, 2025

It is suggested in solid/specification#59 (comment) that this is a question that is answered in the spec, in particular in the following three sections:

I'm noting in particular the following sentence:

The Origin header warns the server that a possibly untrusted Web application is being used.

Seeing also what MDN says about the Same-origin policy:

It helps isolate potentially malicious documents, reducing possible attack vectors. For example, it prevents a malicious website on the Internet from running JS in a browser to read data from a third-party webmail service (which the user is signed into) or a company intranet (which is protected from direct access by the attacker by not having a public IP address) and relaying that data to the attacker.

These are two good examples of how acl:origin can be useful, and neither of them are related to identifying clients, and neither of them can be circumvented by using a proxy.

  • if the user of the browser is logged in to their WAC-controlled storage, for instance with a cookie, then acl:origin restricts the use of that logged-in state. This cannot be circumvented with a proxy, because the proxy would not have access to the cookie.
  • if the WAC-controlled storage exists on an intranet, then similarly, an acl:origin restriction cannot be circumvented with a proxy, because the proxy would exist outside the intranet.

So yeah, I finally understand now. :) I think we can close this issue.

@elf-pavlik do you agree?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants