HTML代码自动转义(auto-escaping)
当使用模板生成HTML代码时,如果变量内容是一些影响HTML结果的字符时,那就挺危险的。
例如,模板内容如下:
Hello {{ name }}
当name的值为:
渲染后的HTML结果就是:
Hello
以上的代码运行的结果就是会让浏览器弹出一个Javascript的警告窗口。
同理,如果name的值为hanks,那么结果中Hello以后的所有内容就会被字体加粗,因为
没有写结束标记。
这种攻击方式被称为跨站脚本攻击(Cross Site Scripting,CSS或者XSS),是一种站点应
用程序的安全漏洞攻击,是代码注入的一种。它允许恶意用户将代码注入到网页上,其他用户在
观看网页时就会受到影响。这类攻击通常包含了HTML以及用户端脚本语言。
以上定义来自Wiki:
http://zh.wikipedia.org/wiki/%E8%B7%A8%E7%B6%B2%E7%AB%99%E6%8C%87%E4%BB%A4%E7%A2%BC
很显然,任何时候都不要相信用户输入的数据,都要使用防御性编程,为了避免上面的问题,你有两个选择:
1. 使用模板中的filter功能,Django有提供一个escape filter,可以用来过滤掉所有你不信任的变量,不过
需要在每一个变量后使用,这样很容易会漏掉对某个变量使用escape.
2. 使用Django的模板自动转义功能。其实是默认开启的
Django默认转义每一个变量的内容,尤其是下面5个字符:
- <被转义成 <
- > 被转义成 >
- &#39; 被转义成 &#39;
- " 被转义成 "
- & 被转义成 &
上面中的分号也是转义后的一部分。
例如网页内容&#xff1a;
页面源代码为&#xff1a;
可以看到&#xff0c;转义只对变量的内容进行使用&#xff0c;模板本身的HTML代码不会被转义。
如何关闭这个功能&#xff1f;
为什么呢&#xff0c;有可能你有时就是想让变量的内容渲染成原始的HTML代码&#xff0c;所以不想被转义。
比如你想让template系统产生文本内容而不是HTML&#xff0c;就像email信息一样。
Django提供了三种方式关闭自动转义&#xff1a;变量级别&#xff0c;模板级别和站点级别。
1. 变量级别
使用safe这个过滤器对每一个变量进行禁用自动转义
This will be escaped: {{ data }}
This will not be escaped: {{ data|safe }}
效果如下&#xff1a;
网页内容
页面源代码
上面之所以没有显示出来&#xff0c;是HTML语法错误&#xff0c;这就是不转义的下场。。。
2. 模板级别
在模板中使用autoescape标签来控制&#xff0c;可以嵌套使用
Auto-escaping is on by default. Hello {{ name }}
{% autoescape off %}
This will not be auto-escaped: {{ data }}.
Nor this: {{ other_data }}
{% autoescape on %}
Auto-escaping applies again: {{ name }}
{% endautoescape %}
{% endautoescape %}
同时&#xff0c;autoescape标签的影响具有继承性&#xff0c;可以从父模板影响到子模板。
# base.html
{% autoescape off %}
{% block title %}{% endblock %}
{% block content %}
{% endblock %}
{% endautoescape %}
# child.html
{% extends "base.html" %}
{% block title %}This & that{% endblock %}
{% block content %}{{ greeting }}{% endblock %}
继承之后的子模板&#xff0c;也都禁用了自动转义功能。如果greeting变量含有&#xff0c;
将不会被转义。
需要注意的是&#xff0c;模板的作者不用去担心自动转义的使用。更多的python端的
开发人员需要考虑哪些数据需要去转义&#xff0c;合理去使用这些数据。
如果你创建了一个模板&#xff0c;而且不太清楚所应用的环境是否开启了自动转义功能。那就在所有
的变量上加上escape过滤器&#xff0c;escape过滤器不会对已经escape的内容产生影响。
对于filter过滤器中参数的自动转义
Django中的自动转义功能不会对filter中的参数已作用&#xff0c;也就是说&#xff0c;最好在filter的参数中&#xff0c;自己
写成转义后的代码&#xff0c;比如这种情况你应该手写成
{{ data|default:"3 <2" }}
而不是
{{ data|default:"3 <2" }}
这是为了安全起见。
通过 为知笔记 发布