
Neatly Bypassing Content Security Policy - wlrm
https://lab.wallarm.com/how-to-trick-csp-in-letting-you-run-whatever-you-want-73cb5ff428aa
======
minitech
I’m confused. If you already have script injection on a website with script-
src 'unsafe-inline' (!!!), what do you need to bypass? I guess for some very
unusual types of websites it could be hard to get information out, but you’re
otherwise free to perform any action within the site as the user.

~~~
alxlu
You would need to bypass connect-src in order to exfiltrate data. Even if you
are able to call fetch() on your endpoint through XSS, CSP would block the
network request. So the iframe and webrtc methods in the article are geared
towards bypassing that since connect-src would fallback to default-src in this
case.

------
nebulous1
It's almost like there's a clue in the name 'unsafe-inline'

------
dnag
Just adding the sandbox attribute is enough to severely lock down an iframe.

<iframe sandbox
src="[http://example.com"></iframe>](http://example.com"></iframe>)

~~~
mattbierner
Just to add some context: 'sandbox' will make the iframe load in a unique
origin and also disable scripts (along with disabling bunch of other things).
This will prevent these attacks.

There's also ' frame-src' for content security policies, which lets you
control what is allowed in the iframe's src. Even with these guards in place,
you generally should not let user content drive an iframe's src

------
dvirsky
Oh, not CSP as in concurrency. Makes more sense now.

~~~
sullyj3
I assumed Constraint Satisfaction Problem

~~~
xenonite
I had the same thought. It would be good to adjust the headline accordingly.

------
Someone1234
Great article.

Why is CSP so under-utilized? Less than 0.2% of the top 1m sites[0]. Although
only 9% use basic features like secure cookies, and 6% HSTS.

[0] [https://blog.mozilla.org/security/2018/02/28/analysis-
alexa-...](https://blog.mozilla.org/security/2018/02/28/analysis-alexa-
top-1m-sites-2/#alexa-02-2018-footnotes)

~~~
throwawayjava
_> Why is CSP so under-utilized?_

I think a few reasons:

1\. It's not a sufficient replacement for sanitizing input. You need to
sanitize; CSP is just an extra layer of protection.

2\. relative new.

3\. many popular frameworks don't support it out of the box.

~~~
iancarroll
The deployment difficulty is also high, especially for what it offers.
Deploying CSP on anything non-trivial involves a lot of coordination with
basically anyone who runs code on your site.

~~~
ubernostrum
This is the big one.

Lots of sites have marketing departments which like to switch out their
advertising, engagement, A/B testing, etc. code on a regular basis. Which in
turn requires either changing the CSP frequently to accommodate, or else
opening holes in the CSP to allow marketing to just copy/paste inline JS and
other badness. At which point it's hard to justify CSP.

~~~
Jach
This has been my feature work for the past couple months (I work on an
enterprise site builder, basically, with some users doing what you describe --
we need to support that but hopefully with a smaller/harder to misfire
footgun). There's a lot of feature complexity even after you've simplified it
down, and it's kind of maddening how much effort it is to just send an extra
(correct for the context) string in the response headers.

The spec versions are interesting to read too, as well as browser
compatibility. Differences in interpretation of the spec lead to github issues
which lead to browsers fixing things in the past few months that have been
part of the spec for much longer. (And if you have a big chunk of IE11 users,
"what's the point" is valid.) An example of a spec issue is that I'm working
on adding an endpoint for the report-uri directive so we can log some metrics
but the first thing you see when reading about report-uri is that it's been
deprecated in favor of report-to, but literally no stable browser release
supports report-to yet.

It's also not really enough. [https://github.com/tc39/proposal-frozen-
realms](https://github.com/tc39/proposal-frozen-realms) is a useful extension,
since it would allow frameworks to do what they need to set up everything but
then lock down objects from further extension/abuse...

------
Jach
TLDR: don't use 'unsafe-inline'. Good article though.

~~~
zinckiwi
The clue is in the name, I'd have thought.

------
nailer
What if they use unsafe-inline but still lock down frames via frame-src?

~~~
alxlu
In this example it would still work since frame-src will fallback to default-
src if not specified.

~~~
nailer
I don't think you're reading my question properly - I'm asking about when
frame-src IS specified - but just in case it's me that's missing something.
I'll reword my question.

What happens if a site:

\- allows 'unsafe-inline' as a script-src

\- does not allow untrusted domains in frame-src

?

~~~
alxlu
In the example they have default-src set to ‘self’ ‘unsafe-inline’

That essentially means frame-src is set to that same thing since it’s not
specified. So the bypass in the example would still work since it’s iframing
the same (trusted) domain even if they explicitly specify frame-src.

~~~
nailer
i don't understand. If they set frame-src to an explicit list of domains they
trust surely default-src becomes irrelevant and the exploit doesn't work? I'm
testing it now and creating an iframe won't work.

~~~
alxlu
Yeah if you set frame-src to something that doesn’t include the current domain
then it should prevent loading an iframe from the same origin

That being said, this technique might still work in theory on whatever domains
you have specified in frame-src if it doesn’t include ‘self’.

So if you’re foo.com and frame-src only allows bar.com. If you managed to get
script into foo.com maybe you could put an iframe pointing to
bar.com/reallylongorinvalid

That being said I haven’t had a chance to try this out on my machine yet so I
could be missing something

Also it looks like their demo includes sandbox allow-same-origin and allow-
scripts in its CSP.

~~~
alxlu
Following up on this. It looks I spoke too soon about the separate domain
iframe, since that would be blocked by the iframe's cross domain policy.

So if the domain you are currently on listed in frame-src it looks like you
would be safe from this. But if you explicitly set frame-src to include either
'self' or the domain itself then you would still be vulnerable to this.

~~~
nailer
Thanks for replying. Yeah I get this / agree with you now.

> But if you explicitly set frame-src to include either 'self' or the domain
> itself then you would still be vulnerable to this.

Exactly.

\- There is a site foo.com, which has a CSP, but allows iframes from self or
foo.com

\- A user is able to inject some XSS to open an iframe to foo.com/50x.html, an
nginx page with no CSP. Since CSP allows our own site to be used in iframes,
this is allowed.

\- In that page, further JS is injected to extract secrets from the foo.com
parent page and connect them to remote networks. Since foo.com/50x.html has no
CSP, this is allowed.

------
zupa-hu
TLDR: CSP can by bypassed if you don't use it on all responses, like error
pages.

This is of course not bypassing CSP.

------
jey
Mods, can you please update title to clarify that "CSP" means "Content
Security Policy" here?

~~~
sctb
Sure thing!

