Skip to content

Commit 5e36a2e

Browse files
committed
[css-variables-1] Specify a required defense against the "billion laughs" attack. Fixes w3c#3733
1 parent bf6a156 commit 5e36a2e

1 file changed

Lines changed: 50 additions & 1 deletion

File tree

css-variables-1/Overview.bs

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -635,6 +635,51 @@ Variables in Shorthand Properties</h3>
635635
if any of the longhand subproperties for that shorthand have <a>pending-substitution values</a>
636636
then the serialized value of the shorthand must be the empty string.
637637

638+
<h3 id=long-variables>
639+
Safely Handling Overly-Long Variables</h3>
640+
641+
Naively implemented,
642+
''var()'' functions can be used in a variation of the "billion laughs attack":
643+
644+
<div class=example>
645+
<pre lang=css>
646+
.foo {
647+
--prop1: lol;
648+
--prop2: var(--prop1) var(--prop1);
649+
--prop3: var(--prop2) var(--prop2);
650+
--prop4: var(--prop3) var(--prop3);
651+
/* etc */
652+
}
653+
</pre>
654+
655+
In this short example, ''--prop4''’s computed value is ''lol lol lol lol lol lol lol lol'',
656+
containing 8 copies of the original ''lol''.
657+
Every additional level added to this doubles the number of identifiers;
658+
extending it to a mere 30 levels,
659+
the work of a few minutes by hand,
660+
would make ''--prop30'' contain <em>nearly a billion instances</em> of the identifier.
661+
</div>
662+
663+
To avoid this sort of attack,
664+
UAs must impose a UA-defined limit on the allowed length of the token stream
665+
that a ''var()'' function expands into.
666+
If a ''var()'' would expand into a longer token stream than this limit,
667+
it instead makes the property it's expanding into
668+
[=invalid at computed-value time=].
669+
670+
This specification does not define what size limit should be imposed.
671+
However, since there are valid use-cases for custom properties that contain a kilobyte or more of text,
672+
it's recommended that the limit be set relatively high.
673+
674+
Note: The general principle that UAs are allowed to violate standards due to resource constraints
675+
is still generally true here;
676+
a UA might, separately, have limits on how long of a custom property they can support,
677+
or how large of an identifier they can support.
678+
This section calls out this attack specifically
679+
because of its long history,
680+
and the fact that it can be done without any of the pieces
681+
<em>seeming</em> to be too large on first inspection.
682+
638683

639684

640685
<!--
@@ -706,5 +751,9 @@ Privacy and Security Considerations {#priv-sec}
706751
===============================================
707752

708753
This specification defines a purely author-level mechanism for passing styling information around within a page they control.
754+
As such, there are no new privacy considerations.
709755

710-
As such, there are no new privacy or security considerations.
756+
[[#long-variables]] calls out a long-standing Denial-of-Service attack
757+
that can be mounted against "macro-expansion"-like mechanisms,
758+
such as the ''var()'' function,
759+
and mandates a defense against that attack.

0 commit comments

Comments
 (0)