Django之XSS攻击

################# XSS攻击:
    XSS(Cross Site Script)攻击又叫做跨站脚本攻击。他的原理是用户在使用具有XSS漏洞的网站的时候,向这个网站提交一些恶意的代码,
    当用户在访问这个网站的某个页面的时候,这个恶意的代码就会被执行,从而来破坏网页的结构,获取用户的隐私信息等。
### XSS攻击场景:
    比如A网站有一个发布帖子的入口,如果用户在提交数据的时候,提交了一段js代码比如:<script>alert("hello world");</script>,
    然后A网站在渲染这个帖子的时候,直接把这个代码渲染了,那么这个代码就会执行,会在浏览器的窗口中弹出一个模态对话框来显示hello world!
    如果攻击者能成功的运行以上这么一段js代码,那他能做的事情就有很多很多了!
### XSS攻击防御:
    1.如果不需要显示一些富文本,那么在渲染用户提交的数据的时候,直接进行转义就可以了。在Django的模板中默认就是转义的。
      也可以把数据在存储到数据库之前,就转义再存储进去,这样以后在渲染的时候,即使不转义也不会有安全问题,示例代码如下:
         from django.template.defaultfilters import escape
         from .models import Comment
         from django.http import HttpResponse
         def comment(request):
             content = request.POST.get("content")
             escaped_content = escape(content)     # 转义
             Comment.objects.create(content=escaped_content)
             return HttpResponse('success')         
        
    2.如果对于用户提交上来的数据包含了一些富文本(比如:给字体换色,字体加粗等),那么这时候我们在渲染的时候也要以富文本的形式进行渲染,
      也即需要使用safe过滤器将其标记为安全的,这样才能显示出富文本样式。但是这样又会存在一个问题,如果用户提交上来的数据存在攻击的代码呢,
      那将其标记为安全的肯定是有问题的。示例代码如下:
         # views.py
         def index(request):
             message = "<span style='color:red;'>红色字体</span><script>alert('hello world');</script>";
             return render_template(request,'index.html',context={"message":message})
        # index.html:{{message:safe}}
                <!DOCTYPE html>
                <html lang="en">
                <head>
                    <meta charset="UTF-8">
                    <title>首页</title>
                </head>
                <body>
                    <ul>
                        {% for comment in comments %}
                            <li>{{ comment.content|safe }}</li>
                        {% endfor %}
                    </ul>
                    <form action="{% url 'comment' %}" method="post">
                        {% csrf_token %}
                        <textarea name="content" id="" cols="30" rows="3"></textarea>
                        <p>
                            <input type="submit" value="提交">
                        </p>
                    </form>
                </body>
                </html>
    那么这时候该怎么办呢?这时候我们可以指定某些标签我们是需要的(比如:span标签),
    而某些标签我们是不需要的(比如:script)那么我们在服务器处理数据的时候,就可以将这些需要的标签保留下来,把那些不需要的标签进行转义,
    或者干脆移除掉,这样就可以解决我们的问题了。这个方法是可行的,包括很多线上网站也是这样做的,在Python中,有一个库可以专门用来处理这个事情,
    那就是sanitizer。接下来讲下这个库的使用。
原文地址:https://www.cnblogs.com/lpzpp/p/12721627.html