On Monday, May 23, 2016, Tyler Romeo <tylerromeo(a)gmail.com> wrote:
First, as I expected, this proposal is to use CSP wit
the "unsafe-eval"
option enabled for both style-src and script-src. This means the
JavaScript
eval() function can be used freely, and inline CSS via
the style attribute
can still be used. Combined with the "default-src *" policy, which I
mention later in this email, this means an attacker can just use XHR to
download an external script and eval() it, thus defeating the entire point
of CSP: to prevent XSS attacks.
I understand the reason behind this is because we store scripts in
localStorage as cache and eval() them upon page load (which is perhaps the
worst abuse of browser technology I have ever seen). Not allowing both
inline scripts and styles and eval()ed code is one half of the two-sided
CSP coin, and eliminating it keeps open a pretty large attack vector. I
don't believe it's appropriate to sacrifice security for a quick kludge
that is used to improve the performance hole opened by the large
fragmentation of our JavaScript codebase.
Yes, unsafe-eval in scripts is for the localStorage hack. Unsafe-eval in
styles is because there is a limit to how much of the world i can
reasonably expect to break (I suppose for style we could in theory
dynamically gather all the inline styles up, put them in a rl module and
make them non-inline. Sounds kind of complex though. Maybe something to
think about later down the line).
In regards to the XHR attack - my understanding is, if the user already has
the ability to execute javascript, all is pretty much lost. Even if
script-src is super restricted, (which is pretty unfeasible if we still
want to allow user scripts) provided the script can load user controlled
data, presumably the attacker could just reimplement a js interpreter in
js. The only situation i see it helping is if the attack vector is length
limitted.
The way I see it - the main benefit of not allowing eval would be to
prevent users doing silly things with it (or for that matter prevent
libraries like jquery.ui.datepicker from doing silly things)
For unsafe-inline in style - i was under the impression (which may be
wrong) that the main benefits for banning were to:
* prevent data exfiltration (via background-image: etc, unclosed stuff in
<style>, etc)
*prevent manipulating the ui in confusing ways as part of a phising
there are other ways an attacker can do the former, and the latter can
partially already be accomplished in wikitext.
So Its a non-ideal compromise. But i think the benefits of restricting this
do not match the costs, especially at this point. I would rather get the
main gist of csp implemented and then revisit this.
Second, the proposal is to use the nonce-$RANDOM
attribute for inline
scripts, but to cache the nonce for non-logged-in users. Does this mean
that the same nonce will be delivered to multiple pages and/or users?
Because that is a violation of the CSP spec, which says "If a server
delivers a nonce-source expression as part of a police, the server MUST
generate a unique value each time it transmits a policy." [0] Thus we
cannot use nonces in this way. Are these scripts whose contents we know
beforehand? Because then we can just use the hash-source policy.
Yes. Some anons will get cached CSP nonce's. This is obviously non ideal
(and a technical violation of the spec). The justification for this:
* logged in users are more valuable targets then logged out, so it fits to
give them better protection
* the benefit of restricting inline event handlers still applies (a
surprising portion of xss attacks we see dont allow for html, but just
unsafe attributes)
* Most XSS attacks we see are stored xss. Anytime the page is edited the
nonce changes. So now the attacker is left only with DOM xss. For DOM XSS
quite often (not always) they end up involving inserting some inline event
handler with innerHTML, so this might still break many of the vulnerable
scripts anyways.
The reason i didnt propose nonce-hash is the (already bordering on too
long) header, really becomes unreasonably long. I feel like it would be a
very hard sell to propose such a long header.
Again this is non-ideal, in fact much more so then the first paragraph. Its
a compromise to make the main gist of of CSP work in the context of the way
MW is built.
(Not to mention that nonce-source and hash-source
policies are part of CSP
2, which is not supported in the latest IE, Safari, or Opera Mini. What is
the plan to support these browsers? Fall back to unsafe-inline? Possibly
use a solution similar to what Dropbox used for their CSP deployment [1].)
Yeah, these browsers sadly dont get protection.
The meta hack is a cool idea (also might be helpful in the anon user case
mentioned above with shared nonces)
Finally, as stage 1 hints at and as I mentioned above,
there are a lot
more
than just style-src and script-src, such as font-src,
media-src,
frame-src,
manifest-src, etc. Why are these not addressed, and
instead just left to
the default policy of "default-src *"? Do we allow iframes on Wikipedia
pointing at arbitrary domains? At the very least, a scheme-source policy
can be used to enforce HTTPS.
I talk a little about that near the end of the document. I agree its useful
to prevent privacy violations/data exfiltration.
Thanks,
--bawolff