(10)Django框架学习-Templates进阶用法--中

HTML代码自动转义(auto-escaping)

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





你可能感兴趣的:(template)