Page MenuHomePhabricator

New CSS syntax for attr() allows web bugs
Closed, ResolvedPublic

Description

The sanitizer rejects any inline CSS with "url(" to prevent web bugs. [1] has a proposed update to attr() which would allow to circumvent this check:

<div title="https://example.org/image.png" style="background-image: attr(title url);"></div>

creates a span with an URL as title. The inline CSS then adds an background image defined by that title interpreted as URL, i.e. shows an image from any domain.

According to [2] no browser currently implements this syntax ([3] claims it is implemented in IE9, which I could not reproduce, and is wrong according to [4]). But once this syntax gets implemented by some browser, the sanitizer should reject /attr\s*\([^),]+url/ (I'm not entirely sure about this regexp, but something like that should do the job).

[1]: https://www.w3.org/TR/css3-values/#attr-notation
[2]: https://developer.mozilla.org/en/docs/Web/CSS/attr#Browser_Compatibility
[3]: https://bugzilla.mozilla.org/show_bug.cgi?id=435426#c2
[4]: http://msdn.microsoft.com/en-us/library/ie/ms537660%28v=vs.85%29.aspx#attr


Version: unspecified
Severity: normal

Event Timeline

bzimport raised the priority of this task from to Needs Triage.Nov 22 2014, 3:13 AM
bzimport added a project: Security-Core.
bzimport set Reference to bz66404.
bzimport changed Security from none to Software security bug.
Restricted Application changed the visibility from "Public (No Login Required)" to "acl*security (Project)". · View Herald TranscriptNov 22 2014, 3:13 AM
Restricted Application changed the edit policy from "All Users" to "acl*security (Project)". · View Herald Transcript

Thanks for noticing that Michael. I don't think it would hurt to add a blacklist for that, and if support is dropped in the final spec, we can always take it out. I'll make a patch for that today.

I'm still trying to verify that no browsers currently support it. If that's the case, then we can do the change publicly. If not we'll do this a security patch.

(In reply to Michael M. from comment #0)

According to [2] no browser currently implements this syntax ([3] claims it
is implemented in IE9, which I could not reproduce, and is wrong according
to [4]). But once this syntax gets implemented by some browser, the
sanitizer should reject /attr\s*\([^),]+url/ (I'm not entirely sure about
this regexp, but something like that should do the job).

I'm not seeing definitive, formal definition of syntax, so it seems little ambiguous if a comma can separate the first and second parameter to the function. The functional notation says, "If a function takes a list of arguments, the arguments are separated by a comma (‘,’) with optional whitespace before and after the comma." But the definition of attr() and all the given examples use the comma to indicate the fallback. Off the top of my head, I can't think of another attribute with an optional second parameter to check of most browsers implemented it right.

So to be safer, I think I'll do, /attr\s*\([^)]+[\s,]+url/. That would match a fallback to the string "url", or an attr-name of "url" if proceeded by 2 or more whitespace chars. I'd rather err on the side of being conservative and protect against browsers not quite implementing the spec right.

I'm still investigating if any popular browsers implement this yet.

Created attachment 15633
Add blacklist for attr() with url

Adding a patch here, in case we find any browsers implementing this and need to patch the cluster.

Attached:

Restricted Application changed the visibility from "acl*security (Project)" to "Custom Policy". · View Herald TranscriptNov 24 2014, 9:27 PM
Restricted Application changed the edit policy from "acl*security (Project)" to "Custom Policy". · View Herald Transcript
Restricted Application changed the visibility from "Custom Policy" to "Custom Policy". · View Herald TranscriptNov 27 2014, 11:07 PM
Restricted Application changed the edit policy from "Custom Policy" to "Custom Policy". · View Herald Transcript
dpatrick triaged this task as Low priority.

Given nobody supports this syntax yet [1], and probably nobody will in the super-near future, I think we should maybe just submit this to gerrit like an ordinary patch.

Anyone opposed to me publicly submitting csteipp's patch to gerrit like a non-security bug?

One thing to note, is that the CSS2 version of attr, is really only useful with :before and :after pseudo-elements (which can't be used with inline styles), so it might even be safe to ban attr() outright

[1] http://caniuse.com/#search=attr

Bawolff changed the visibility from "Custom Policy" to "Public (No Login Required)".Sep 13 2016, 9:45 AM
Bawolff changed the edit policy from "Custom Policy" to "All Users".
Bawolff changed Security from Software security bug to None.

Change 310257 had a related patch set uploaded (by Brian Wolff):
Disallow css attr() with url type

https://gerrit.wikimedia.org/r/310257

Change 310257 merged by jenkins-bot:
Disallow css attr() with url type

https://gerrit.wikimedia.org/r/310257

Change 316618 had a related patch set uploaded (by Brian Wolff):
Disallow css attr() with url type

https://gerrit.wikimedia.org/r/316618

Change 316621 had a related patch set uploaded (by Brian Wolff):
Disallow css attr() with url type

https://gerrit.wikimedia.org/r/316621

Change 316714 had a related patch set uploaded (by Brian Wolff):
Disallow css attr() with url type

https://gerrit.wikimedia.org/r/316714

Patch merged, and backported to all maintained branches

Change 316714 merged by jenkins-bot:
Disallow css attr() with url type

https://gerrit.wikimedia.org/r/316714

Change 316618 merged by jenkins-bot:
Disallow css attr() with url type

https://gerrit.wikimedia.org/r/316618

Change 316621 merged by Umherirrender:
Disallow css attr() with url type

https://gerrit.wikimedia.org/r/316621

We should CVE this one too as a matter of course in T160876

Or has this disappeared from the spec?

I see attr(src url) but no title url...

It's still there, they just changed the anchor. Note that the actual attribute name doesn't matter, it could as easily be data-foobar.

Since @Reedy asked,

Flaw: MediaWiki's anti-web-bug CSS sanitization does not remove attr(foo url).

Exploit: The extensions proposed to the CSS attr() function in the CSS Values and Units Module Level 3, specifically the 'url' type, could be used to insert a web bug in a wiki page.

This is mitigated by the fact that no major browser currently implements these extensions (according to http://caniuse.com/#feat=css3-attr).