3

So I saw a code snippet today and was horrified:

<p style='background-image: url("javascript:alert(&apos;foo&apos;);");'>Hello</p>
  • Is it possible to execute javascript from within CSS this way? (It didn’t work when I tested it on a clean Firefox profile, but maybe I made some stupid mistake here, but the concept works.)
  • If so, what means are there to prevent this, either with an HTTP header or by declarations made by the HTML itself (e.g. when sourcing CSS files from another server)?
  • If not, was this never possible or has this changed?
Jonas Schäfer
  • 20,140
  • 5
  • 55
  • 69

4 Answers4

1

The current CSS spec says only "valid image formats" can be used in a background-image:

In some cases, an image is invalid, such as a ‘<url>’ pointing to a resource that is not a valid image format. An invalid image is rendered as a solid-color ‘transparent’ image with no intrinsic dimensions. [...] If the UA cannot download, parse, or otherwise successfully display the contents at the URL as an image, it must be treated as an invalid image.

The spec is silent on whether or not a javascript: url that returns valid image data would work -- it'd be an interesting exercise to try to construct one! -- but I'd be pretty darn surprised if it did.

User agents may vary in how they handle invalid URIs or URIs that designate unavailable or inapplicable resources.

(As @Kaiido points out below, scripts within SVG will not run in this situation either, so I'd expect the whole javascript: protocol to be treated as an "inapplicable resource".)

Daniel Beck
  • 20,653
  • 5
  • 38
  • 53
  • 1
    And one should note that even scripts in valid image formats accepting scripting (e.g svg) won't execute either (just like in `` by the way). – Kaiido Oct 12 '17 at 13:48
  • Thanks for this answer. In fact, the original snippet tried some ``new Image()...`` voodoo to create a valid image, so that should’ve worked. However, (mumble mumble Halting Problem mumble), the actual code in the ``javascript:`` URI should not matter for the decision whether it’s executed or not. So while the resource generated by it may or may not be valid, the UA would have to execute the code to find out. – Jonas Schäfer Oct 13 '17 at 06:28
  • 1
    That pesky halting problem, always in the way – Daniel Beck Oct 13 '17 at 11:27
0

IE supports CSS expressions:

width:expression(document.body.clientWidth > 955 ? "955px": "100%" );

but they are not standard and are not portable across browsers. Avoid them if possible. They are deprecated since IE8.

Gothiquo
  • 841
  • 1
  • 8
  • 31
0

Yes, in the past this attack vector worked (older browsers like IE6). I believe most modern browsers should protect against this kind of attack. That said, there can always be more complicated attacks that may get around current protections. If you are including any user-generated content anywhere, it is best to sanitize it before injecting it into your site.

Useless Code
  • 12,123
  • 5
  • 35
  • 40
-5

It's possible to execute JavaScript where a URI is expected by prefixing it with javascript:. This is, in fact, how bookmarklets work. I don't think however that this would work with css url(), but it does with href or window.location.

<a href="javascript:alert('foo');void(0);">say foo</a>

I think whoever wrote that bit of code was confused about it.

Andrei Nemes
  • 3,062
  • 1
  • 16
  • 22
  • I am aware that this is possible in ``@href``. I am asking specifically about CSS, because I considered CSS to be rather safe regarding code-execution and was astonished by this snippet. – Jonas Schäfer Oct 12 '17 at 13:32
  • It's not possible to run JavaScript from CSS. I'm merely pointing out the author of your code snippet though it would also apply to css URIs. – Andrei Nemes Oct 12 '17 at 13:39