Open simonw opened 3 years ago
I'm going to add the "X-Content-Type-Options": "nosniff"
header to the CSS output.
That content sniffing vulnerability isn't necessarily limited to pages that use ?_raw=
- if a browser decides to render the dynamically generated CSS as HTML it's probably possible to construct an evil string which could be executed even with CSS string quoting rules applied to it.
Version 0.2
now sets that header, and is deployed to the demo.
If this does turn out to be a problem one potential solution would be to allow plugin authors to configure a subdomain to be used for this output, which they could then point at their Datasette as an additional DNS CNAME. Imagine configuring Datasette so the .css
output format is always rendered on https://my-safe-domain.net/
where the rest of your instance renders content on https://my-regular-site.com
.
I considered this previously for the .blob
mechanism in https://github.com/simonw/datasette/issues/1036
Tweeted about this issue here: https://twitter.com/simonw/status/1347287093660184576 - also wrote about it in https://simonwillison.net/2021/Jan/7/css-apis-no-javascript/
You can also leak data by injecting into CSS, e.g. input[value^="a"] { background-image: url(...) }
, so make sure it's not possible to specify the _raw argument via the HTML pages themselves.
I think of things like that more as being self-inflicted XSS holes: if you as a page author chose to link to <link href="stylesheet" href="https://datasette-.../?sql=evil-css-to-run-on-your-page">
there's not much I can do to protect you.
My big concern here is any attacks which mean that just running datasette install dataasette-css-properties
will open up an XSS hole in your own (potentially authentication-protected) Datasette instance - because an attacker could send you a link to http://your-datasette/...?sql=evil
and following that link would execute JavaScript with access to your cookies and browser page session.
Yep, and it's a fairly fiddly attack mechanism. But this feature is at its heart CSS injection so probably deserves a hazmat label. Any column specified with ?_raw=
must be trusted.
The
?_raw=column
mechanism makes me a little nervous. It feels like it could be used for XSS, since it allows attackers to inject exact values into a page that is served by Datasette - e.g. https://latest-with-plugins.datasette.io/fixtures.css?sql=select+%27%3Cscript%3Ealert(%22evil%2C+perhaps%22)%3C%2Fscript%3E%27+as+evil%3B&_raw=evilBut that page is served with the
text/css
content-type - it's not HTML.Could a browser be tricked into rendering it as HTML, in which case it would open up a XSS hole in the hosting Datasette instance?