Skip to content

Commit 3a39347

Browse files
committed
Use html_attr_relaxed for attribute name escaping
1 parent 5e8200e commit 3a39347

File tree

4 files changed

+12
-17
lines changed

4 files changed

+12
-17
lines changed

doc/functions/html_attr.rst

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,14 @@
77

88
The ``html_attr`` function was added in Twig 3.24.
99

10-
The ``html_attr`` function renders HTML attributes from one or more mappings.
11-
The mappings contain the names of HTML attributes as keys, and the corresponding
12-
values represent the attributes' values. Escaping is applied for the attribute
10+
The ``html_attr`` function renders HTML attributes from one or more mappings,
11+
taking care of proper escaping. The mappings contain the names of HTML
12+
attributes as keys, and the corresponding values represent the attributes'
1313
values.
1414

1515
.. note::
1616

17-
Attribute names are **not** escaped, to allow using names ``v-bind:href``
18-
or ``@click`` required by some front-end frameworks that would be escaped
19-
by the ``html_attr`` strategy. Avoid using attribute names from user input
20-
or untrusted sources, or apply escaping with ``|e('html_attr')`` _before_
21-
using such data for attribute names.
17+
Attribute names are escaped using the ``html_attr_relaxed`` strategy.
2218

2319
.. code-block:: html+twig
2420

extra/html-extra/HtmlExtension.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ public static function htmlAttr(Environment $env, iterable|string|false|null ...
248248
continue;
249249
}
250250

251-
$result .= $name.'="'.$runtime->escape($value).'" ';
251+
$result .= $runtime->escape($name, 'html_attr_relaxed').'="'.$runtime->escape($value).'" ';
252252
}
253253

254254
return trim($result);

extra/html-extra/Tests/Fixtures/html_attr.test

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@
22
"html_attr" function
33
--TEMPLATE--
44
Simple attributes: <tag {{ html_attr({ foo: 'bar' }, { bar: 'baz' }) }}/>
5-
{% set untrusted_input = 'unsafe="yes" usage' %}
6-
Escaping of the value only: <tag {{ html_attr({ (untrusted_input): '<>&\'"' }) }}/>
7-
Properly escaped attribute name: <tag {{ html_attr({ (untrusted_input|e('html_attr')): '<>&\'"' }) }}/>
5+
Relaxed attribute name escaping: <tag {{ html_attr({ 'v-bind:href': 'url', ':[key]': 'url', '@click': 'doSomething' }) }} />
6+
Appropriate escaping: <tag {{ html_attr({ 'untrusted name': '<>&\'"' }) }}/>
87
Empty attribute list: <tag {{ html_attr([], {}, null) }}/>
98
Using a short ternary: <tag {{ html_attr({foo: 'bar'}, false ? {bar: 'baz'}) }}/>
109
boolean true attribute: <tag {{ html_attr({ checked: true}) }}/>
@@ -23,8 +22,8 @@ merging a "comma separated token list" value with more array values: <img {{ htm
2322
return []
2423
--EXPECT--
2524
Simple attributes: <tag foo="bar" bar="baz"/>
26-
Escaping of the value only: <tag unsafe="yes" usage="&lt;&gt;&amp;&#039;&quot;"/>
27-
Properly escaped attribute name: <tag unsafe&#x3D;&quot;yes&quot;&#x20;usage="&lt;&gt;&amp;&#039;&quot;"/>
25+
Relaxed attribute name escaping: <tag v-bind:href="url" @[key]="url" @click="doSomething" />
26+
Appropriate escaping: <tag untrusted&#x20;name="&lt;&gt;&amp;&#039;&quot;"/>
2827
Empty attribute list: <tag />
2928
Using a short ternary: <tag foo="bar"/>
3029
boolean true attribute: <tag checked=""/>

extra/html-extra/Tests/HtmlAttrTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -141,10 +141,10 @@ public static function htmlAttrProvider(): \Generator
141141
];
142142

143143
// Escaping
144-
yield 'attribute name is _not_ escaped' => [
145-
'this is dangerous: fail @ xss="123"',
144+
yield 'attribute name is escaped' => [
145+
'data-user&#x20;id="123"',
146146
[
147-
['this is dangerous: fail @ xss' => '123'],
147+
['data-user id' => '123'],
148148
],
149149
];
150150

0 commit comments

Comments
 (0)