自动转义到底保护了什么、没保护什么?哪些文件名不会转义?为什么不带引号的属性、javascript: 链接、script 标签里的变量还是会出问题?把输入拼进模板字符串有多危险?这篇每个都实测一遍。
page.html → 转义 <p><b id="a" onclick='x()'>&
page.htm → 转义 <p><b id="a" onclick='x()'>&
page.xml → 转义 <a><b id="a" onclick='x()'>&
page.xhtml → 转义 <p><b id="a" onclick='x()'>&
page.svg → 转义 <text><b id="a" onclick='x()'&g
page.txt → 不转义 text: <b id="a" onclick='x()'>&</b>
page.js → 不转义 var a = "<b id="a" onclick='x()'>&</b>";
page.json → 不转义 {"a": "<b id="a" onclick='x()'>&</b>"}
page.html.j2 → 不转义 <p><b id="a" onclick='x()'>&</b></p>
page.jinja → 不转义 <p><b id="a" onclick='x()'>&</b></p>
noext → 不转义 <p><b id="a" onclick='x()'>&</b></p>
render_template_string → 转义 <b id="a" onclick='x()'>&</b>
Flask 的规则:扩展名是 .html .htm .xml .xhtml .svg 之一就开启(render_template_string 总是开启)上一篇:自定义 Template Test;下一篇:Markup 与 safe。XSS 防护专题:XSS 防护。
输入 <>&'"/\` → <>&'"/\`
text 输入 '<script>alert(1)</script>' → <p><script>alert(1)</script></p>
带引号的属性 输入 '" onfocus="alert(1)' → <input value="" onfocus="alert(1)">
不带引号的属性 输入 'a onfocus=alert(1)' → <input value=a onfocus=alert(1)>
href(javascript:) 输入 'javascript:alert(1)' → <a href="javascript:alert(1)">link</a>
<script> 里的字符串 输入 '";alert(1);//' → <script>var a = "";alert(1);//";</script>
<script> 里的 tojson 输入 '";alert(1);//' → <script>var a = "\";alert(1);//";</script>
<style> 里 输入 'red;} body{display:none' → <style>p {color: red;} body{display:none}</style>
单引号属性且值含单引号 输入 "' onfocus='alert(1)" → <input value='' onfocus='alert(1)'>
观察:引号被转义的属性(带引号)是安全的;不带引号的属性、href 里的 javascript: 协议、<script> 里的字符串都没有被「HTML 转义」拯救。 错误写法 name=Ann → <h1>你好 Ann</h1>
错误写法 name={{ 7*7 }} → <h1>你好 49</h1>
错误写法 name={{ config.SECRET_KEY }} → <h1>你好 lab-secret</h1>
正确写法 name=Ann → <h1>你好 Ann</h1>
正确写法 name={{ 7*7 }} → <h1>你好 {{ 7*7 }}</h1>
正确写法 name={{ config.SECRET_KEY }} → <h1>你好 {{ config.SECRET_KEY }}</h1> {{ x|safe }}: <b>bold</b>
{% autoescape false %}…{% endautoescape %}: <b>bold</b>
{% autoescape true %}(在 .txt 里开启): <b>bold</b> {"a": "\u003c/script\u003e\u003cscript\u003ealert(1)\u003c/script\u003e", "q": "it\u0027s \u0026 \u003cb\u003e"}
tojson 返回值的类型: Markup (Markup = 已标记为安全,不会再被转义)