-
Notifications
You must be signed in to change notification settings - Fork 16
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鈥檒l occasionally send you account related emails.
Already on GitHub? Sign in to your account
Initial feedback on version "22 July 2016" #1
Comments
Doh...I left out @intchloe from the list of us chatting about this on twitter. |
Mostly I agree with what @ptoomey3 said, as he seems like a rational fellow. Here are some of my thoughts:
{
"baseline-csp": {
"sources": {
"default": ["'none'"],
"img": ["'self'", "https://github.io"],
"script": ["'self'", "https://cdn.query.com"]
},
"report-only": true
},
"hsts": {
"max-age": 31536000,
"includeSubDomains": true,
"preload": true
},
"nosniff": true,
}
I guess altogether that would make the header look something like:
|
Another option, instead of (or in addition to) integrity is having a |
I wonder how the request header I'm not a fan of the idea, because this already kinda works in most web servers. One advantage is that we won't send to big headers. Also, I see issues with using dynamic CSP here as @ptoomey3 mentioned as well. This could kinda be a footgun too - if we don't use I've had the same issues as @ptoomey3 with some pages not having a CSP sat. With a complex site structure it's very easy to miss some subpaths that should have a CSP. PS. I like when examples are used. That's why I had a hard time understanding the |
Oh. Hi, everyone. I wasn't actually ready to throw this to the world, but, since you're here, hello! :) I slapped this together during IETF downtime, so take it with a grain or two of salt. It's a pretty rough strawman to spawn some discussion. Let's see what y'all had to say:
The goal here was to simplify things by using normal HTTP caching rules. That is, I'd expect
No, it doesn't. I haven't gotten to the implementation bits yet. :) The idea is that we'd treat it just like another header. If you're using a "baseline" policy, it would be just like including another
It needs to live somewhere, as I think we need some way to reduce the number of preflights in cases where we know we don't need them. As you note, that whole bit of CORS is a hack around the status quo at that time. If we can assert that the server understands CORS, then the preflights are just wasted requests. In any event, I agree that it's a new feature, but since it has origin-wide implications, it makes sense to me to make it part of the manifest. Aaaaand now I'm hopping on a plane. I'll try to get through the rest of the discussion later this weekend. Thanks for the (earlier than expected!) feedback! |
Keeping the format the same means that we'd just be able to inject the string as a header; from a browser implementer's perspective, that's the simplest thing to do, as we can do it up in the network stack without any understanding of the meaning of the things we're putting in place. Honestly, if we invent a new syntax for CSP, I have about 80 other changes I'd make at the same time. :) I'm not sure this is the right way to do that, as it's something of an orthogonal task which would require a new header anyway.
No, the intent in this draft is for it to be the filename in the well-known directory.
I don't actually want to include files from anywhere. Setting policy for an origin is potentially dangerous, and I don't want to give folks other than the server owner the ability to inject policy. Locking things down to a
As above, I'd like to not reinvent browser caching rules. The closer we can keep the manifest file's behavior to any other HTTP request, the happier I am.
I don't understand the attack you're suggesting. Could you clarify? It sounds like you're saying that folks who change their user agent from
The point of section 5.1 is that the name of the manifest file ~is a cookie, as a server could provide a unique manifest to each user, and thus reidentify them via the request HTTP header. Given that, we'd need to be sure that we give it the same lifetime as a cookie from a user's perspective. If a user clears their cookies or cache, we should clear out the stored manifest as well.
Does it? I'm not so sure. I think we need a pinning mechanism of some sort. I don't think that the pinning mechanism I sketched out in https://w3c.github.io/webappsec-csp/pinning/ works. This is my second pass. Happy to take a third, but I think it's functionality we need.
Yes. Which is a big advantage, really. Also, this can ensure that you don't miss things like error pages, which I know has bitten Google in the past.
Yup. That's something to work out. I think the
I think the draft addresses this scenario. That is, if
then the server can respond with:
That will trigger an update in the client, as the name is new. The update, like the original, will happen synchronously, before the page is loaded. Does this not address the scenario you're concerned with?
Examples are a great way of sketching things out before writing the algorithms. Figuring out what developers should see is a nice way of figuring out how things should work. Glad you appreciate them. :) |
No, you are correct. I was not understanding how the request header would work. I thought the client would have it's preferred version number of the manifest (based on the servers response) and not always trying to have the latest version. Then this is not a privacy issue for spoofed user agents, but like you said; it could work as cookies. Thank you for clarifying!
I was referring to However, we should't rely on web servers (too much). I agree that a manifest is much better than trying to send headers there we want them.
It does. As long as the server updates the Took some time to understand how everything could work, so on seconds thoughts I like the design! My thoughts of dynamic policies: if we can send a specific version number of the manifest designed for the current path:.
I see some issues with implementing this, but I'm really curious to see how we can solve this :) |
I don't see how this:
Is any different from this:
(which has the same CSP inside it) Either way, somebody had access to write the server headers and presumably is the server owner. But maybe I'm just missing something? My reason for the flexibility is that historically in larger projects I have found that the people who run the web servers are not the same people that that write the application. And that is often a problem when it comes to the implementation of CSP, much time lost opening issues and shuffling tickets back and forth. It also makes coordination for new releases a lot more cumbersome. If you could just set it as above, the web server people would never need to be contacted at all. |
@marumari: In short, I see the fact that this mechanism requires cross-cutting cooperation from the folks responsible for running an entire origin as a feature, not a bug. I've attempted to spell that out in https://mikewest.github.io/security-policy-manifest/#why-well-known. Basically, you're right to say that there's no difference between That said, I'm happy to be convinced that I'm being overly cautious. I'd like to start with overly cautious, though. It's much easier to roll back restrictions than to impost them ex post facto. |
So, I'm reading: https://mikewest.github.io/origin-policy/#why-well-known And I guess I don't understand the objections?
|
I read your suggestion as being that setting headers is somewhat easy for application developers, while taking over the
The things you can do with
If the services live on separate origins, sure! An issue is that many don't.
I'm (potentially irrationally) worried about one origin asserting a policy which lives on another origin. I would prefer that the origin be completely responsible for its policy, both by serving the
I agree! But I think I would still prefer not to make that optional. :) (One thing I didn't note earlier is that a well-known location also mitigates the risk that user-generated content might be interpreted as a manifest. This, along with the MIME type check, seems valuable.) |
They're both hard for application developers! The fact that an application developer needs to go back to the server administrator to do work every single time they add a new resource type or domain to load resources from actively hinders CSP adoption. It adds extra steps, it complicates deployments, and it honestly adds like zero security in my experience. In my experience, this is what happens when there needs to be a change:
Well sure, you could set things up that way, but that would be a hugely messed up design. Here is how I would imagine it being setup, as in using nginx: location /maps {
add_header Origin-Policy "_include:https://google.com/.well-known/global-op.json _include:/maps/.well-known/op.json";
}
location /press {
add_header Origin-Policy "_include:https://google.com/.well-known/global-op.json _include:/press/.well-known/op.json";
} This way, maps' policy would only affect itself, press's policy would affect itself, etc. If the press team needed to include media.google.com in their img-src, they could change their JSON file and it would get picked up automatically, and it couldn't affect the rest of the origin. Plus, Google could set a global policy that could inherit (in some way) downward. It gives you a ton of flexibility, and speeds implementation.
Yes, I think you're more worried than I am. We do this stuff all the time:
Here I'm asserting a policy for who is allowed to send mail from my domain, but that policy lives on a completely different origin. Google changes the SPF record constantly; they could in theory completely ruin my ability to send mail, but it manages to work out great. If I wanted, I could manually manage all those Google mail servers (as like keeping everything in .well-known), but I don't. It's the same way with domain registration, DNS, etc.: I delegate control of my entire origin to a third party. It's a scary choice but in principal it works very well. Heck, HSTS has includeSubDomains, and one origin (aka google.com) can affect thousands or hundreds of thousands of other origins.
If you have to specify a URI for this file, though, it seems like you would put it in a place where user content can't be written, just like with .well-known. I think part of why _include is awkward is that Origin Policy attempts to solve two distinct problems:
I think we have the opportunity to come up with a solution that solves the two above problems, while also solving a couple extra problems:
While still allowing this flexibility:
I think if we can make an inheritance model work, we can come up with a solution that gives a ton of flexibility, makes it easier for application developers to update their policies, and lets organizations set global standards. For example (and there are many ways to do it):
Perhaps that Google Global Origin Policy could force HSTS for every possible origin that includes it, disables all content sniffing, allows fonts.google.com as a font-src for everybody, forbids evil.com as a script-src no matter what a subdomain wants to do, and sets 'upgrade-insecure-requests' on every origin. And then maps's Origin Policy file could add various CSP origins that it needs specifically for maps. My previous job was at a bank, and there are times where it would have been completely outstanding to have centralized control over things like X-Content-Type-Options instead of hoping that each individual team's web admins would follow policy and make sure that the header was added. |
Hey everyone! It's been 3+ years, and a lot has changed. I'll close this out, as it seems like a lot of the original issues have been answered, including via the new format. Please file new issues if there's something I missed! |
First of all, 馃檱 for opening this up. There are obviously lots of details to flesh out, but this is a great starting point. Some of my feedback might be off base, but here are some random thoughts I had while reading through it:
Security-Policy: "v1"
- Having an arbitrary version number feels funny, as it seems like it leaves room for error (updating the policy but forgetting to bump the version). Why not have the version be a hash of the json policy file? This would allow for trivial code to set the "version number" in headers (i.e. self updating) and would allow a nice belt and suspenders check on the client (you don't process a manifest unless it actually hashes to the same value provided in the header response).fallback-csp
(more broadly, fallbacks as a general feature), as we have run into this at GitHub. An early failure in normal request processing resulted in no CSP header getting set in the response. While we fixed the underlying issue, we also added a "fallback csp" on all our static error pages by setting a super strict policy via ameta
tag. That said, we would generally be fine if our fallback matched our regular policy. So, I wonder how often people will actually strongly prefer a different policy. It may be that it is generally not needed, so maybe thebaseline-csp
would be sufficient. Or, maybe this could be made optional (and apply to other directives). Fore eample, there could be afallback
attribute you can set for any (where it makes sense) of the top level keys in this config (ex. Settingfallback
for thereferrer
directive probably makes sense).baseline-csp
policy, what effect does returning aContent-Security-Policy
header have? Taking GitHub as an example, we would like to have a base policy that applies to the vast majority of requests, but we would like to override certain directives on certain pages. For example, we add on an additionalconnect-src
to our policy on our payment pages (to allow connection to a third party payment processor). We don't want that source in our base policy, as it is not needed for 99% of requests. The most trivial solution would seem to be to preferContent-Security-Policy
over the manifest to override things when needed. But, that isn't ideal, as we don't really want to have to deliver the entire policy via header given that part of the goal of the manifest is not having to send an ever growing policy via header responses. This issue may very well be unique to CSP, as a complete override via a header generally makes sense (since most headers are single purpose). But, I do wonder if CSP should evolve in coordination with this manifest to allow for more granular overrides. Using my payment example above, what we really want is some base policy, and then some way to do something likeContent-Security-Policy: append-connect-src 'https://api.braintreegateway.com'
to append a singleconnect-src
to the base policy for this single response. Most people probably use a static policy, but once you are addicted to CSP 馃槃, you see more and more places to prefer a granular directive set (generally in the form of a simple addition to a base policy).cors
stuff feels a bit out of place. While I see the benefit of it, and CORS does have some security consequences, it doesn't feel like a "security policy" to me in quite the same way as the others. The other headers were explicitly added for security, where as the CORS header was just a "necessary evil" to make cross origin sharing work at all. I wonder if the Web App Manifest is a better home (though if these manifests meld into one then it doesn't really matter).I'll add more comments if/when I think of things. Thanks again!
/cc
Team CC - @oreoshake @mastahyeti @gregose @brentjo
Twitter CC - @ericlaw1979 @ScottHelme @marumari
The text was updated successfully, but these errors were encountered: