fix(xml): remove recursive sublanguage references to prevent ReDoS#4361
Open
petejm wants to merge 1 commit intohighlightjs:mainfrom
Open
fix(xml): remove recursive sublanguage references to prevent ReDoS#4361petejm wants to merge 1 commit intohighlightjs:mainfrom
petejm wants to merge 1 commit intohighlightjs:mainfrom
Conversation
Remove `xml` from the sublanguage fallback arrays in `<style>` and `<script>` tag handling. Also remove `handlebars` from `<script>` since handlebars itself uses xml as its base sublanguage, creating an indirect recursion path (xml -> handlebars -> xml). The recursive sublanguage references allow crafted input with many unclosed `<script>` tags to cause exponential backtracking, leading to resource exhaustion (denial of service). Fixes highlightjs#4261 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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.
Summary
xmlfrom<style>sublanguage array (was['css', 'xml'], now'css')xmlandhandlebarsfrom<script>sublanguage array (was['javascript', 'handlebars', 'xml'], now'javascript')sublanguage_no_relevancytest expectations to match new behaviorProblem
Crafted HTML input with many unclosed
<script>tags causes exponential backtracking because:xmllisted as a sublanguage of itself in<script>/<style>tagshandlebarsusesxmlas its base sublanguage, creatingxml -> <script> -> handlebars -> xml -> ...The highlight.js engine has no sublanguage recursion depth limit, so this causes resource exhaustion (denial of service). The PoC from #4261 hangs the browser; after this fix it completes in ~9ms.
This is consistent with the approach taken on the
main_12branch (commitsca21a19and18d4182), backported to v11.Fixes #4261
Behavioral changes
Removing
xmlfrom<style>and<script>: No practical impact. Thexmlfallback only activated when CSS/JS parsing failed, in which case the content isn't XML either — it would just produce misleading highlighting.Removing
handlebarsfrom<script>: This is a minor behavior change. Previously,<script>content was auto-detected between JavaScript and Handlebars by relevance. Now it always highlights as JavaScript. In practice this is low-impact because:<script type="text/x-handlebars-template">) are better served by specifyinglanguage="handlebars"directly, which uses the dedicatedhandlebars.jsgrammar with full XML + Handlebars supportTest plan
npm test)sublanguage_no_relevancy.expect.txtfor new<script>behavior (content now wrapped inlanguage-javascriptspan since sublanguage is a string, not array)🤖 Generated with Claude Code