Re: Proposal: A pinning mechanism for CSP?

Based on this conversation, I've relaxed the proposal to cover only those
cases where a `Content-Security-Policy` header is not present in a
response. That covers the majority of what I wanted in a pinning solution.

It wouldn't be difficult to change the behavior to an overlay rather than a
default, either from an implementation perspective or a spec perspective. I
suspect that the danger of policy-based suicide is limited, as the author
can always send a `max-age 0` to remove the bad policy. This is distinct
from the PKP case, where the pinned key actually prevents _connection_ to
the source which could expire the pinned policy.

I think it will be worth adding a `no-override` flag in the future, once we
hash out the threat model it defends against in a clear way.

For the moment, I think the drafted proposal solves a real gap in current
implementations, and does so in a pretty straightforward way.

Perhaps you folks at AppSec can chat today to see if there are fundamental
objections I haven't considered? If not, I'd like to republish the draft as
a WebAppSec product (rather than as a "collection of interesting ideas"
under Google's copyright), and see if we can agree to push it out as a FPWD.

Thanks!

-mike

--
Mike West <mkwst@google.com>, @mikewest

Google Germany GmbH, Dienerstrasse 12, 80331 München,
Germany, Registergericht und -nummer: Hamburg, HRB 86891, Sitz der
Gesellschaft: Hamburg, Geschäftsführer: Graham Law, Christine Elizabeth
Flores
(Sorry; I'm legally required to add this exciting detail to emails. Bleh.)

On Mon, Jan 26, 2015 at 7:26 AM, Brad Hill <hillbrad@gmail.com> wrote:

> I think that's a very interesting feature proposal.  I'm not sure it
> belongs in CSP, vs an extension to the HPKP grammar or a standalone
> header?  I can see it if I squint, but for reasons I've suggested, I think
> there are lots of sharp edges for pinning when applied to everything else
> CSP does.
>
>
> On Sun Jan 25 2015 at 7:57:01 PM Yan Zhu <yzhu@yahoo-inc.com> wrote:
>
>> The use case I had for non-overrideable pinning only makes sense if there
>> is a future CSP directive that says something like, "Do not load any
>> resources on this page except from a package signed by this key." Suppose
>> https://securedrop.my-news-site.com (a site where users can go to submit
>> encrypted messages to journalists) looks like this:
>>
>>
>> <html>
>> <head>
>> <link rel="package" href="/securedrop-app.pack" scope="/"
>> type="application/package">
>> </head>
>> ...
>> </html>
>>
>> where 'securedrop-app.pack' is of the format defined in
>> https://w3ctag.github.io/packaging-on-the-web/ and includes a digital
>> signature. The site operator delivers a CSP header that says, "do not load
>> any resources except from a package signed by [some signing key]" which is
>> pinned for 3 months.
>>
>> With this particular pinned header, the only bricking risk is if the site
>> loses control of its package signing key; in the analogous case for
>> installable apps/extensions, they're are out of luck too.
>>
>> The threat model here is that most users should be safe even if the
>> server delivering code updates is compromised.
>>
>> I realize this is a stretch since that threat scenario was never in scope
>> for CSP, but I just wanted to throw it out there since it's something that
>> multiple projects seem interested in.
>>
>> Thanks,
>> Yan
>>
>> On Friday, January 23, 2015 1:57 PM, Brad Hill <hillbrad@gmail.com>
>> wrote:
>>
>>
>>
>> There is a lot of tension here between preventing pin-suicide (as
>> cryptocat has already done with key pinning) and a somewhat dubious threat
>> model - attacker can inject arbitrary headers and code, but we think this
>> will somehow save users.
>>
>>
>> I'd like to see more exploration of the latter threat model to be
>> convinced it makes sense, and also to understand what kind of measures
>> would be needed to mitigate deployment risk.
>>
>> I too, started with a policy like you suggest for an experiment I'm
>> working on, then I needed ReCAPTCHA, then I found there were bugs in
>> Chrome's policy enforcement on iOS, and I needed to update my policies to
>> make things work.  I think that CSP in deployment for real apps tends to be
>> either static and report-only or very loose, or meaningfully strict to
>> offer serious preventative control and highly evolving.
>>
>> Chrome apps have a manifested policy that looks like a pin, but you can
>> update it by updating the app. How do you update the CSP pin for a webapp?
>>
>> On Fri Jan 23 2015 at 12:30:44 PM Yan Zhu <yzhu@yahoo-inc.com> wrote:
>>
>> On Friday, January 23, 2015 11:23 AM, Mike West <mkwst@google.com> wrote:
>> >
>> >
>> >>On Fri, Jan 23, 2015 at 7:29 PM, Brad Hill <hillbrad@gmail.com>
>> wrote:>>>The pinning model in the proposal uses the existing
>> >>>> combination logic for multiple headers: resources simply
>> >>>> need to pass all the policies applied to a protected resource.
>> >>>> I think overriding the pinned policy completely would undermine
>> >>>> its impact to some extent; I'd prefer to avoid doing that unless
>> >>>> there's a good reason to.
>> >>>
>> >>>
>> >>>
>> >
>> >>>I don't know about that.  I like the idea of "here's a backup policy
>> in case things go wrong and >>we forget to send one".  For example, if an
>> application ends up returning an error page before the >>logic that applies
>> the policy was reached.>
>> >
>> >> I hadn't thought about the problem this way; it's a compelling
>> alternative, mostly because it
>> >
>> >> reduces the deployment risk to (practically) nil.>
>> >
>> >> The overall concept, then, would be "Every page on my host(s) MUST
>> have a Content Security
>> >> Policy.", which is similar conceptually to HSTS's promise that every
>> page on a host will be
>> >> delivered over HTTPS. I think it's worth exploring (sorry, Jim; I
>> shouldn't have dismissed the
>> >> idea so quickly).>
>> >
>> >> I don't want to entirely give up the stricter "Every page on my
>> host(s) MUST have a CSP that's at > least this strict." variant. I think
>> Yan had some use cases that would benefit from that sort of
>> >> promise. Perhaps we can do both with something horrible like a
>> `no-override` directive?
>> >
>> >My main use case was web apps that are infrequently updated and need to
>> make especially strong security guarantees to users (like SecureDrop,
>> CryptoCat, Google/Yahoo's End to End project, etc.). These tend to be
>> implemented as browser extensions or installable packaged apps, partly due
>> to lack of something like CSP pinning [1].
>> >
>> >
>> >For instance, https://cryptomail.example.com (an encrypted webmail
>> service) might deliver the following non-overrideable CSP pin header:
>> >
>> >"Content-Security-Policy-Pin: default-src 'none'; script-src 'self';
>> style-src 'self'; max-age=31536000; includeSubDomains"
>> >
>> >because the developers want to ensure that if a cryptomail server is
>> temporarily compromised, the attacker will not be able to start loading
>> inline scripts or malicious third-party content by suddenly changing the
>> headers. (This doesn't stop them from loading malicious first-party
>> scripts, but I'm hoping to get code signing into SRI or the TAG's proposed
>> packaging format to deal with that.)
>> >
>> >The no-override directive doesn't sound like such a bad option to me. :)
>> >
>> >
>> >[1] Chrome extensions enforce a strict CSP policy by default and lets
>> developers "pin" policies in the extension manifest file:
>> https://developer.chrome.com/extensions/contentSecurityPolicy.
>> >
>> >
>> >
>> >> Also, if we allow overrides at all, I'd suggest that
>> `<meta>`-delivered policies shouldn't
>> >> override pinned policies. That seems like a bad idea.
>> >
>> >Agree!
>> >
>>
>

Received on Monday, 26 January 2015 13:32:34 UTC