Skip to content

Commit 03f9c2e

Browse files
Spomkynicolas-grekas
authored andcommitted
[HtmlSanitizer] Remove srcdoc from allowed attributes
The `srcdoc` attribute is unlisted from the standard attributes to prevent potential misconfiguration. It must now be explicitly enabled, and it is STRONGLY advised to `->forceAttribute('iframe', 'sandbox', '')` when doing so. A new test ensures that `<iframe>` elements with unsafe attributes, including `srcdoc`, are sanitized correctly.
1 parent e080770 commit 03f9c2e

File tree

4 files changed

+19
-3
lines changed

4 files changed

+19
-3
lines changed

Reference/W3CReference.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ final class W3CReference
368368
'span' => true,
369369
'spellcheck' => true,
370370
'src' => true,
371-
'srcdoc' => true,
371+
// 'srcdoc' => false, // XSS vector if not properly sandboxed, should be enabled explicitly with ->allowAttribute('srcdoc', 'iframe')->forceAttribute('iframe', 'sandbox', '')
372372
'srclang' => true,
373373
'srcset' => true,
374374
'standby' => true,

Tests/Fixtures/baseline-attribute-allow-list.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,6 @@
182182
"span",
183183
"spellcheck",
184184
"src",
185-
"srcdoc",
186185
"srclang",
187186
"srcset",
188187
"standby",

Tests/HtmlSanitizerAllTest.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,23 @@ public static function provideSanitizeBody()
568568
}
569569
}
570570

571+
public function testIFrameDefaultsAreSafe()
572+
{
573+
$sanitizer = new HtmlSanitizer((new HtmlSanitizerConfig())
574+
->allowElement('iframe', '*')
575+
);
576+
$input = '<iframe src="javascript:alert()" onload="alert()" srcdoc="<script>alert()</script>">XSS</iframe>';
577+
$this->assertSame('<iframe>XSS</iframe>', $sanitizer->sanitize($input));
578+
579+
$sanitizer = new HtmlSanitizer((new HtmlSanitizerConfig())
580+
->allowElement('iframe', '*')
581+
->allowAttribute('srcdoc', 'iframe')
582+
->forceAttribute('iframe', 'sandbox', '')
583+
);
584+
$input = '<iframe src="javascript:alert()" onload="alert()" srcdoc="<script>alert()</script>">XSS-prevented by sandbox</iframe>';
585+
$this->assertSame('<iframe srcdoc="&lt;script&gt;alert()&lt;/script&gt;" sandbox>XSS-prevented by sandbox</iframe>', $sanitizer->sanitize($input));
586+
}
587+
571588
public function testUnlimitedLength()
572589
{
573590
$sanitizer = new HtmlSanitizer((new HtmlSanitizerConfig())->withMaxInputLength(-1));

Tests/HtmlSanitizerConfigTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ public function testAllowElementStandardAttributes()
109109
$config = new HtmlSanitizerConfig();
110110
$config = $config->allowElement('div', '*');
111111
$this->assertSame(['div'], array_keys($config->getAllowedElements()));
112-
$this->assertCount(211, $config->getAllowedElements()['div']);
112+
$this->assertCount(210, $config->getAllowedElements()['div']);
113113
$this->assertSame([], $config->getBlockedElements());
114114
}
115115

0 commit comments

Comments
 (0)