4

Can XSS be prevented 100% by setting the content security policy as default-src 'self'? Is there any way XSS can happen in that case? One possibility I can think of is injecting user input into one of your scripts dynamically at the server-side, do you agree? Are there any other vulnerabilities you can think of?

  • if you inject something "server-side", it's not XSS, it's just S... – dandavis Aug 17 '16 at 22:10
  • @dandavis I think he is referring to stored XSS. – Arminius Aug 19 '16 at 0:32
3

CSP in such a configuration should enable the following security measures:

  • Disable inline scripts
  • Disable inline styles
  • Disable all use of dangerous JavaScript functions (e.g. eval)
  • Force all content to be loaded only from the existing domain. This applies to:
    • JavaScript
    • CSS
    • Fonts (e.g. WOFF)
    • Ajax (XmlHttpRequest and similar)
    • WebSockets
    • Video
    • Objects (e.g. Flash, Java applets)
    • SVGs
    • WebGL assets
    • Frames
    • Images
    • Probably some other things I forgot...

As such, XSS should be possible only in cases where resources on the domain can be controlled by an attacker, as you mentioned.

You can lock CSP down further by setting default-src 'none', then explicitly enabling only content types which you are expecting to use on the site. This helps lower your attack surface further by disabling content types like Flash, Java applets, SVGs, canvas, etc. when you're not using them.

One additional vector you may not have considered is Path-Relative Stylesheet Overrides (PRSSI), otherwise known as Relative Path Overwrite (RPO) vulnerabilities. These work by exploiting URL handling behaviour in some CMS software, whereby path characters appear after a script are taken as parameters (e.g. example.com/wiki/index.php/Something shows the Something page). When a path-relative stylesheet is included (e.g. main.css rather than /main.css) this can be sometimes abused. In our example, because main.css is imported relative to the current path, an inclusion in the example URL above would cause the browser to try to load example.com/wiki/index.php/main.css as a stylesheet. If you can create a wiki page called main.css, this would allow you to control the content of that stylesheet, and potentially load malicious CSS (e.g. with the expression directive). You can do the same thing with path relative JavaScript imports. The fix here is to always reference content by its full canonical path.

  • there's no need to worry about "malicious CSS" executing code anymore, and JS is imported relative to the document, not the importing file. – dandavis Aug 17 '16 at 20:48
  • "there's no need to worry about malicious CSS executing code anymore" - got a citation on that? – Polynomial Aug 17 '16 at 21:37
  • And as for "and JS is imported relative to the document, not the importing file", that's the problem. The browser thinks the document is in a deeper path than it really is. – Polynomial Aug 17 '16 at 21:38
  • AFAIK all css execution vectors are at least 5 years outmoded: dec 2011 for expressions, IE9 for behaviors, firefox4 for -moz-binding ... did I miss anything? looking at the % usage of vulnerable browsers suggest it's not worth worrying about anymore; time would be better spent crafting CSPs – dandavis Aug 17 '16 at 22:01
  • i should point out that it might be possible to use CSS alone to fool users into doing something dumb, like baiting them to type in a non-clickable url by showing an "error message", but that's not XSS... – dandavis Aug 17 '16 at 22:08
0

default-src 'self' allows XSS via JSONP and content-type sniffing attacks:

Of particular note is our lack of self in our source list. While sourcing JavaScript from self seems relatively safe (and extremely common), it should be avoided when possible.

There are edge cases that any developer must concern themselves with when allowing self as a source for scripts. There may be a forgotten JSONP endpoint that doesn’t sanitize the callback function name. Or, another endpoint that serves user-influenced content with a content-type that could be sniffed by browsers as JavaScript. GitHub has several such endpoints. For example, we return commit diffs as text/plain.

http://githubengineering.com/githubs-csp-journey/

  • CORS has eliminated the need for JSONP, and ALL user input needs sanitized... – dandavis Aug 18 '16 at 19:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.