>백엔드 개발 >파이썬 튜토리얼 >XSS 및 CSRF에 대한 자세한 소개

XSS 및 CSRF에 대한 자세한 소개

零下一度
零下一度원래의
2017-06-29 10:40:252735검색

1. XSS

크로스 사이트 스크립팅(Cross Site Scripting)은 CSS(Cascading Style Sheets)의 약어와 혼동하지 않도록 하여 크로스 사이트 스크립팅 공격을 XSS라고 약칭합니다. 악의적인 공격자는 웹 페이지에 악성 스크립트 코드를 삽입하여 사용자가 페이지를 탐색할 때 웹 페이지에 포함된 스크립트 코드가 실행되어 사용자를 악의적으로 공격하려는 목적을 달성합니다.

1. 작업흐름

a. 악의적인 사용자가 일부 공개 영역(예: 제안 제출 양식 또는 메시지 공개 게시판의 입력 양식)에 일부 텍스트를 입력하지만 이러한 텍스트는 다른 사용자에게 표시되지 않습니다. 입력할 텍스트뿐 아니라 클라이언트 측에서 실행할 수 있는 일부 스크립트도 포함됩니다. 예:

<script>'Not Safe'</script>

b. 이 양식을 악의적으로 제출하세요.

c. 다른 사용자는 악성 스크립트가 포함된 이 페이지를 보고 이를 실행하여 사용자의 쿠키 및 기타 민감한 정보를 얻습니다.

2. 예 - XSS 공격을 방지하지 않음

 1 pinglu = []     # 评论列表 2  3 #提交表单 4 def commit(request): 5     if request.method == 'GET': 6         return render(request, 'commit.html') 7     else: 8         com = request.POST.get('commit') 9         pinglu.append(com)10         return redirect('/index.html/')11 12 13 #查看评论页面14 def index(request):15     return render(request, 'index.html', {'commit': pinglu})
view.py
 1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4     <meta charset="UTF-8"> 5     <title>Title</title> 6 </head> 7 <body> 8 <h1>评论</h1> 9 <form action="/commit.html/" method="post">10     <input type="text" name="commit">11     <input type="submit" value="sumbit"> {{ error }}12 </form>13 </body>14 </html>
commit.html
 1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4     <meta charset="UTF-8"> 5     <title>Title</title> 6 </head> 7 <body> 8 <h1>评论</h1> 9 {% for item in commit %}10     <div>{{ item|safe }}</div>11 {#    item后加safe,默认数据安全,django不会做特殊处理#}12 {% endfor %}13 </body>14 </html>
index.html

위의 예에서 commit.html 페이지에 다음 내용을 입력하고

<script> alert('恶意脚本') </script>

을 제출하면 이 코드 줄이 인덱스 페이지에서 실행되고 경고 상자가 나타납니다. (악성코드가 포함되어 있으면 실행됩니다)

3. XSS 공격을 예방하는 가장 직접적인 방법

  • HTML 페이지에서 제어할 수 없는 입력을 위해 safe를 사용하지 않는 것입니다

{#    <div>{{ item|safe }}</div>#}<div>{{ item }}</div>
  • 특수 문자가 데이터베이스나 웹 페이지에 제출되는 것을 방지하기 위해 보기를 필터링할 수도 있습니다.

def commit(request):if request.method == 'GET':return render(request, 'commit.html')else:
        com = request.POST.get('commit')if '<script>' in com:    # 过滤“<script>”关键字,防止恶意代码的提交return render(request, 'commit.html', {'error': '此条评论有毒,已被和谐'})else:
            pinglu.append(com)return redirect('/index.html/')

2. CSRF

CSRF(교차 사이트 요청 위조) "원클릭 공격"이라고도 알려진 크로스 사이트 요청 위조 또는 CSRF 또는 XSRF로 약칭되는 세션 라이딩은 웹사이트를 악의적으로 이용하는 행위입니다. XSS(교차 사이트 스크립팅)처럼 들리지만 사이트 내의 신뢰할 수 있는 사용자를 이용하는 XSS와는 매우 다릅니다. 반면 CSRF는 신뢰할 수 있는 사용자의 요청을 위장하여 신뢰할 수 있는 웹 사이트를 이용합니다. XSS 공격과 비교할 때 CSRF 공격은 인기가 덜하고(따라서 이를 방지할 리소스도 매우 부족함) 예방하기 어려운 경향이 있으므로 XSS보다 더 위험한 것으로 간주됩니다.

1. 작업 흐름

공격은 승인된 사용자가 액세스하는 페이지에 링크나 스크립트를 포함하여 작동합니다.

2. 사용자의 사이트 간 요청 위조를 방지하기 위해 django에서

django를 방지하는 방법 기능은 다음과 같습니다. 미들웨어 django.middleware.csrf.CsrfViewMiddleware를 통해 완료됩니다. Django의 크로스 사이트 요청 위조 방지 기능은 글로벌과 로컬로 구분됩니다.

전역:

  • 미들웨어 활성화 django.middleware.csrf.CsrfViewMiddleware

부분:

from django.views.decorators.csrf import csrf_exempt,csrf_protect
  • @csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件

  • @csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。

 3. django中的具体应用方法

  • form表单中添加{csrf_token %}

若form表单中未添加{csrf_token %},则会报403错误。

#settings.py中打开MIDDLEWARE设置'django.middleware.csrf.CsrfViewMiddleware',
1 from django.shortcuts import render, HttpResponse, redirect2 3 def csrf_test(request):4     if request.method == 'GET':5         return render(request, 'csrf_test.html')6     else:7         return HttpResponse('ok')
views.py
 1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4     <meta charset="UTF-8"> 5     <title>csef_test</title> 6 </head> 7 <body> 8 <form action="/csrf_test.html/" method="post"> 9     <input type="text" name="user" id="user">10     <input type="submit" value="submit">11 </form>12 13 </body>14 </html>
csef_test.html

修改csef_test.html:

 1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4     <meta charset="UTF-8"> 5     <title>csef_test</title> 6 </head> 7 <body> 8 <form action="/csrf_test.html/" method="post"> 9     {% csrf_token %}10     <input type="text" name="user" id="user">11     <input type="submit" value="submit">12 </form>13 14 </body>15 </html>
form表单中添加{% csrf_token %}

  • 全站禁用,即将settings.py中的 'django.middleware.csrf.CsrfViewMiddleware' 注释掉即可

  • 基于FBV视图的局部禁用和使用

 1 #settings.py 2 #启用 'django.middleware.csrf.CsrfViewMiddleware', 3  4  5 from django.views.decorators.csrf import csrf_exempt 6  7  8 @csrf_exempt 9 def csrf_test(request):10     if request.method == 'GET':11         return render(request, 'csrf_test.html')12     else:13         return HttpResponse('ok')
局部禁用
 1 #settings.py 2 #禁用 #'django.middleware.csrf.CsrfViewMiddleware', 3  4  5 from django.views.decorators.csrf import csrf_protect 6  7  8 @csrf_protect 9 def csrf_test(request):10     if request.method == 'GET':11         return render(request, 'csrf_test.html')12     else:13         return HttpResponse('ok')
局部使用
  •  基于CBV视图的(只能局部使用或禁用类,不能在类方法里局部使用或禁用

 1 #settings.py 2 #禁用    'django.middleware.csrf.CsrfViewMiddleware', 3  4  5 from django.views import View 6 from django.views.decorators.csrf import csrf_protect 7 from django.utils.decorators import method_decorator 8  9 10 @method_decorator(csrf_protect, name='dispatch')11 class Foo(View):12     def get(self, request):13         pass14 15     def post(self, request):16         pass
局部使用
 1 #settings.py 2 #启用    'django.middleware.csrf.CsrfViewMiddleware', 3  4  5 from django.views import View 6 from django.views.decorators.csrf import csrf_exempt 7 from django.utils.decorators import method_decorator 8  9 10 @method_decorator(csrf_exempt, name='dispatch')11 class Foo(View):12     def get(self, request):13         pass14 15     def post(self, request):16         pass
局部禁用
  • Ajax提交数据时,携带CSRF

 1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4     <meta charset="UTF-8"> 5     <title>csef_test</title> 6 </head> 7 <body> 8 <form action="/csrf_test.html/" method="post"> 9     {% csrf_token %}10     <input type="text" name="user" id="user">11 {#    <input type="submit" value="submit">#}12     <a onclick="submitForm();">Ajax提交表单</a>13 </form>14 15 <script src="/static/jquery-3.2.1.js"></script>16 <script>17     function submitForm() {18             var csrf = $("input[name='csrfmiddlewaretoken']").val()19             var user = $("#user").val()20             $.ajax({21                 url: '/csrf_test.html/',22                     type: 'POST',23                     data: {"user": user, "csrfmiddlewaretoken": csrf},24                     success: function (arg) {25                             console.log(arg);26           }27             })28   }29 </script>30 </body>31 </html>
Ajax重写csrf_test,html,csrf数据存放于data中
 1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4     <meta charset="UTF-8"> 5     <title>csef_test</title> 6 </head> 7 <body> 8 <form action="/csrf_test.html/" method="post"> 9     {% csrf_token %}10     <input type="text" name="user" id="user">11 {#    <input type="submit" value="submit">#}12     <a onclick="submitForm();">Ajax提交表单</a>13 </form>14 15 <script src="/static/jquery-3.2.1.js"></script>16 {#专门处理cookie的插件,提取cookie字符串#}17 <script src="/static/jquery.cookie.js"></script>18 19 {#csrf数据放于data中#}20 {#<script>#}21 {#    function submitForm() {#}22 {#            var csrf = $("input[name='csrfmiddlewaretoken']").val();#}23 {#            var user = $("#user").val();#}24 {#            $.ajax({#}25 {#                url: '/csrf_test.html/',#}26 {#                    type: 'POST',#}27 {#                    data: {"user": user, "csrfmiddlewaretoken": csrf},#}28 {#                    success: function (arg) {#}29 {#                            console.log(arg);#}30 {#          }#}31 {#            })#}32 {#  }#}33 {#</script>#}34 35 {#csrf数据放于请求头中#}36 <script>37     function submitForm() {38             var csrf = $.cookie('csrftoken');39             var user = $("#user").val();40             $.ajax({41                 url: '/csrf_test.html/',42                     type: 'POST',43                     headers: {'X-CSRFToken': csrf},44                     data: {"user": user},45                     success: function (arg) {46                             console.log(arg);47           }48             })49   }50 </script>51 52 53 54 </body>55 </html>
Ajax重写csrf_test.html,csrf数据存放于headers中

注意:{csrf_token %}和cookie中的csrftoken值不一样。

form表单中的隐藏csrf_token

 cookie中

 

위 내용은 XSS 및 CSRF에 대한 자세한 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.