rec*_*gle 5 javascript python security django xss
我希望能够使用Django的模板语言来模板化一些JavaScript变量。我foo遇到的情况是这样的,其中有一个用户定义数据的Python字符串(读取不受信任的数据),我想将其转换为JavaScript字符串。
<!doctype html>
<html>
<head>
<script>
bar = '{{ foo|escapejs }}';
</script>
</head>
<body>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
如果我正确阅读了Django的文档,则escapejs像这样使用容易受到XSS攻击。
我想到了使用这样的HTML5 data-*属性的潜在解决方案。
<!doctype html>
<html>
<head>
<script>
window.onload = function () {
bar = document.getElementById('data').getAttribute('data-bar');
};
</script>
</head>
<body>
<div id="data" style="display:none;" data-bar="{{ foo }}"></div>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
但是,我想知道是否有一个不太麻烦/标准的方法。
的输出escapejs 可安全用于JS-inside-HTML-text或JS-inside-HTML-quoted-attribute-value的嵌套上下文中。在JS-inside-HTML-unquoted-attribute-value中使用它并不安全(但是escape对于未引用HTML属性,则两者都不安全,因此无论如何都应引用)。
这是可以的,因为它碰巧将所有HTML特殊字符\u转义为不包含HTML特殊字符的JavaScript字符串文字转义。参见_base_js_escapes中django.utils.html。它还将输出标记为“安全”,因此您希望这不是谎言。
无论是应该是OK,以及是否是保证留 OK在未来的Django版本不清,给你指出的文档。可能只是想说这是对纯HTML进行转义的错误形式:虽然(对于当前的实现而言)对纯HTML进行转义是不安全的,但事实并非如此,您肯定会在错误的输出中加上不必要的反斜杠它。你感到幸运吗?
我已经考虑过使用HTML5的data- *属性这样的潜在解决方案。
无论如何,我总是会这样做。模板化为JS很容易出错,而内联JS则有点混乱,并且会阻止您将来部署Content-Security-Policy。
最好将所有页面数据置于HTML属性中,并始终使用相同的已知良好HTML自动转义,并让JS从DOM检索它。当然,当您要包括结构化数据而不只是字符串时,您可以对其进行JSON编码。
(不过,我不会为手动的不可见div烦恼...您可以将属性附加<body>到相关数据,或将任何其他元素连接到相关数据。)