Repository navigation
Sanitize attribute names in fenced_code and legacy_attrs - #1663
Merged
Merged
Conversation
An attribute name supplied through the attr_list {attrs} syntax on a fenced
code block, or through the legacy_attrs {@name=value} syntax, was written to
the output without sanitization. The attr_list scanner permits a name of
[^ =}]+ and legacy_attrs permits [^}]*, both of which allow >, <, / and
quotes, so a name such as x><svg/onload=alert(1) closed the enclosing tag and
injected a live element. Reuse attr_list.sanitize_name, which the element path
already applies, at both sites. Valid names are unchanged.
waylan
approved these changes
Oct 19, 2026
waylan
left a comment
Member
There was a problem hiding this comment.
Good catch. As this change only adds sanitation in the 2 places it was getting missed, this is an acceptable fix. Thanks for the work on this.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
fenced_code(the non-Pygments path, withattr_listenabled) andlegacy_attrswrite a user-supplied attribute name into the output without sanitizing it. Infenced_codethe key of akey=valuepair in a fence's{...}is emitted asf' {k}="..."'with only the value escaped. Inlegacy_attrsthe name from{@name=value}is set straight onto the element withel.set(match.group(1), ...)and the serializer writes attribute names verbatim. Theattr_listscanner allows a name of[^ =}]+andlegacy_attrsallows[^}]*, both of which permit>,<,/and quotes, so a name likex><svg/onload=alert(1)closes the<code>tag (or the surrounding element) and injects a live element.attr_listalready guards the element path withsanitize_name(NAME_RE.sub('_', name)), which is where a name like this belongs. This moves that helper to module scope and applies it at the two sites that skipped it, so a name is reduced to a valid XML name before it reaches the output. Valid names (letters, digits,-,.,_,:) are unchanged, so existing attribute lists render the same.Reproduction before the change:
In both cases the
>in the name closes the enclosing tag and a live<svg onload=...>element follows. After the change the name becomesx_svg_onload, so it stays inside the intended tag.Added regression tests for both extensions and a changelog entry.
AI Assistance Disclosure
Checklist