Skip to content

[rejected AI] tojson: escape U+2028 and U+2029 (JavaScript line/paragraph separators) - #2266

Closed
IMGillusion wants to merge 2 commits into
pallets:mainfrom
IMGillusion:fix-1882-tojson-line-separators
Closed

[rejected AI] tojson: escape U+2028 and U+2029 (JavaScript line/paragraph separators)#2266
IMGillusion wants to merge 2 commits into
pallets:mainfrom
IMGillusion:fix-1882-tojson-line-separators

Conversation

@IMGillusion

Copy link
Copy Markdown

Problem

htmlsafe_json_dumps (the |tojson filter) escapes <, >, & and ' so its output is safe to embed in HTML and <script> tags. It does not escape the Unicode line separator U+2028 and paragraph separator U+2029.

JavaScript treats those two characters as line terminators, exactly like \n. When json.dumps is told to emit raw Unicode (ensure_ascii=False, a very common config), the separators are emitted unescaped, so a crafted string can break out of a <script> block:

env.policies['json.dumps_kwargs'] = {'ensure_ascii': False}
template = "{{ x|tojson }}"
# x = '""; alert(1); //\u2028document.location = \"http://evil\"'

Fix

Escape U+2028 / U+2029 to \\u2028 / \\u2029, matching what Django's json_script filter does. On the default path (ensure_ascii=True) json.dumps already escapes them as non-ASCII, so the new .replace() calls are harmless no-ops there.

Closes #1882

IMGillusion added 2 commits September 6, 2026 05:32
JavaScript treats U+2028 (LINE SEPARATOR) and U+2029 (PARAGRAPH
SEPARATOR) as line terminators. When json.dumps is called with
ensure_ascii=False (the common config) the raw separators are emitted
and a string could break out of a <script> block. Escape them the same
way Django's json_script does. The default (ensure_ascii=True) path is
unaffected: json.dumps already escapes these non-ASCII characters, so
the new .replace() calls are no-ops there.

Closes pallets#1882
@davidism

davidism commented Sep 6, 2026

Copy link
Copy Markdown
Member

@davidism davidism closed this Sep 6, 2026
@davidism davidism changed the title tojson: escape U+2028 and U+2029 (JavaScript line/paragraph separators) [rejected AI] tojson: escape U+2028 and U+2029 (JavaScript line/paragraph separators) Sep 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Escape newlines for tojson filter as Django

2 participants