> <i>get_data_from_data_attribute({{ data|to_json }});</i><p>This constitutes an injection vulnerability that can be demonstrated with string "</script><script>alert(1<2)</script><script>".<p>If you want to inject arbitrary strings into a script tag, you need to reach for some more exotic escapes, starting with things like </script> → <\/script> or \u003c/script>. But I’m not going to give you a complete solution because I don’t want you to think this is a good idea. (But if you really want to know: look at the <i>script data state</i> in the HTML spec, and follow the parser. All up, you could do it two different ways, one requiring three things and the other two, though one of the two/three is impossible after JSON encoding.)<p>People often treat auto-escaping template languages as safe to do anything in, but they’re just <i>not</i> if you use HTML syntax—there are quite a few hazards to be aware of. Here you disabled auto-escaping (mark_safe in the to_json body) because the auto-escaping broke things in one way, but it introduced another vulnerability. For sanity in this context, you need to use XML syntax (by serving with the MIME type application/xhtml+xml), though some JavaScript libraries might misbehave due to side-effects if they make bad assumptions, and third-party templates might not be designed for XML syntax. (All up, I don’t generally recommend using XML syntax, though it’s a close thing.)<p>Fun fact: you <i>can</i> actually use entity encoding in JavaScript in the HTML syntax… by using the <i>SVG</i> script tag instead of the HTML one:<p><pre><code> <svg><script>alert(1&lt;2)</script></svg></code></pre>