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

Escalation to code execution #16

Open
weizman opened this issue Aug 28, 2024 · 13 comments
Open

Escalation to code execution #16

weizman opened this issue Aug 28, 2024 · 13 comments

Comments

@weizman
Copy link
Collaborator

weizman commented Aug 28, 2024

The escalation-to-code-execution part of the explainer requires us to address it and think about it:

More thoughts:

I think I'm leaning towards option#2 (meta tag) which is a great sweet spot in the middle between a header and a JS API, because:

  • It's a better version of the header, because it is more unlikely to inject tags, and even more so to inject them high enough in the initial HTML so that they bypass the RIC dictation of the web app itself
  • It's a better version of the header, because it's less of an escalation - if attackers can inject HTML, they might as well inject a script or an iframe
  • It's a better version of the JS API, because it deviates significantly less from the original proposal

That being said, when comparing option#3 to the serviceWorker API, it makes a lot of sense, as the 2 are much alike in terms of power and SOP sensitivity

All in all, a lot to ponder, but what's becoming more clear to me is that option#1 (current proposal's state) is probably the worst one...

@guybedford
Copy link

In the case of the meta tag, would the CSP rules still apply to the script? If that were the case it would seem to rule out the remaining con?

@weizman
Copy link
Collaborator Author

weizman commented Aug 29, 2024

Originally, I said the same thing before #15 got merged (exactly here), but then @yoavweiss said (rightfully so) how this wasn't a good answer, given how many consumers of the API could very likely be not very well informed about the importance of a strong CSP configuration.
Now, it's one thing that they don't embrace a mechanizm such as CSP that can only upgrade their security, but it's a different story if they embrace RIC and it actually lowers their security if they are not capable of doing so in combination with CSP settings they weren't expecting. Or also, what if they just don't want to limit such scenarios with CSP, but do want to make use of RIC? If such a state lowers their security in some sense (as opposed to only improve it or leave it at the same level), then the API design might require some more thinking.

@guybedford
Copy link

Perhaps the RIC script it self could be script-src on the fallback but have a more refined CSP policy like ric-src that could be used to provide more granular control via the CSP?

@mhofman
Copy link

mhofman commented Sep 4, 2024

The biggest issue with non-header alternatives is in how to make sure it applies before any script in the current document. For example a script tag could appear before the meta tag. And for service workers, they are designed to not impede the first load of a page that previously didn't have a service worker installed.

@weizman
Copy link
Collaborator Author

weizman commented Sep 4, 2024

Perhaps the RIC script it self could be script-src on the fallback but have a more refined CSP policy like ric-src that could be used to provide more granular control via the CSP?

Perhaps, but feels like things are getting messier going down this path.. Would prefer to come up with something that introduces less things to be aware of

@weizman
Copy link
Collaborator Author

weizman commented Sep 4, 2024

The biggest issue with non-header alternatives is in how to make sure it applies before any script in the current document. For example a script tag could appear before the meta tag. And for service workers, they are designed to not impede the first load of a page that previously didn't have a service worker installed.

Why is it important though? From my perspective, being able to decide when RIC kicks in, and to allow scripts to run before it, is a feature rather than a bug.

Obviously you should make sure it's dictated before other scripts, but maybe you prefer not to for whatever use case relevant to you, nothing wrong with that.

@mhofman
Copy link

mhofman commented Sep 4, 2024

Why is it important though? From my perspective, being able to decide when RIC kicks in, and to allow scripts to run before it, is a feature rather than a bug.

The RIC script will apply to other realms as the first script running. If the same RIC script also applies to the main realm, it may run after these other scripts have run. I suppose there is a bigger question of in the common use case, would the main page RIC script would be the same as for dependent realms.

@weizman
Copy link
Collaborator Author

weizman commented Sep 9, 2024

Being an issue worth pondering, we dived into this concern in the last Endo meeting and came back with some excellent conclusions of what restrictions we must apply so that a header remains the proper way to go with:

  • A JavaScript API is probably the worst way to go, given how:
    • It allows other JavaScript entities to register their own RIC at runtime
    • It introduces a significant block to rendering (the RIC script is determined only while parsing the DOM)
    • It introduces a potential state where JS code can be evaluated both before and after the RIC script which can be considered rather inconsistent behaviour
  • A Header is indeed a new way to turn a header into XSS, which is very bad, but can be mitigated enough if RIC only accepts 1st party URLs and requires the content type of the resource to be of JavaScript
    • Given this restriction, there's no reason to worry about allowing RIC via a meta tag either
    • One concern in this context was if an attacker would manage to find a way to reflect JS from a 1st party resource to point RIC to
      • In addition to being very unlikely to find both this and a way to add/modify headers, requiring a JS content type would also help in mitigating such risk
  • The significant downside to this (which I really wanted to avoid) is that such design will prevent/make it very hard for 3rd party vendors to ship their logic via RIC (they would have to form a server-side integration with their clients), but unfortunately it doesn't seem it would be possible to provide such a solution without generating significant security risks.

These should be formalized and integrated into the explainer.

https://youtu.be/V1qHJXX9BZk

@weizman
Copy link
Collaborator Author

weizman commented Sep 12, 2024

while #26 address this issue, we (@yoavweiss) decided to consult the Security WG on our conclusions, so this issue remains open for wno

@ddworken
Copy link

Generally, I think the approach of requiring same-origin JS URLs is reasonable. The one additional rule I'd suggest there is that we should also block redirects, so as to ensure that open redirects don't lead to bypasses.

I will say that from my perspective as someone who would be interested in using this feature, the same-origin restriction will make usage tricky. Ideally, we'd be doing something like setting Initial-JS: https://gstatic.com/prototype-pollution-mitigation.js on all pages. If we had to use a same-origin URL, this would become much harder to deploy.

One possible idea would be doing something along the lines of a site-wide well-known file. For example, example.com/.well-known/script-includes.json could enumerate the 3P URLs that are allowed to be referenced. And the well-known file could be cached site-wide to minimize performance impact.

@weizman
Copy link
Collaborator Author

weizman commented Sep 29, 2024

@ddworken, I'm still thinking about the rest of your (great) points, I want some time to ponder those.

One quick question that does come to mind though, can you elaborate on your open redirects concern?

Do you mean, disallow the JavaScript code in the RIC script to perform a redirection? Why do you reckon we should block this specifically, and how is this different from any other regular script having the ability to perform such redirection? Especially under the (current) assumption that both such scripts originate from the same origin as the app.

@ddworken
Copy link

ddworken commented Oct 9, 2024

Yeah! So my concern is specifically about ensuring that Content-Security-Policy: realm-init /some/open-redirect?dest=https://example.com/foo.js doesn't work. This could mean either:

  1. Not allowing the JS URL to serve redirects at all
  2. Allowing it to serve redirects, but ensuring that the redirect is same-origin

I think this is probably a pretty small and easily addressable concern. :)

@weizman
Copy link
Collaborator Author

weizman commented Oct 13, 2024

Thoughts? @ddworken #38

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

No branches or pull requests

4 participants