| 
 | 
 
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册  
 
x
 
网上找到的源码,用django-simple-captcha 服务 
发现可以伪造个post请求,使用固定的hashkey和captcha 提交,过了验证的?有没优化的办法? 
 
 
 
django-simple-captcha的安装 
 
pip install django-simple-captcha 
 
 
在settings.py文件中注册captcha 
 
INSTALLED_APPS = [ 
    'captcha' 
] 
 
 
 
在settings.py文件中设置图形验证码的样式 
 
 
- #字母验证码
 
 - CAPTCHA_IMAGE_SIZE = (80, 45)   # 设置 captcha 图片大小
 
 - CAPTCHA_LENGTH = 4   # 字符个数
 
 - CAPTCHA_TIMEOUT = 1   # 超时(minutes)
 
 - #加减乘除验证码
 
 - CAPTCHA_OUTPUT_FORMAT = '%(image)s %(text_field)s %(hidden_field)s '
 
 - CAPTCHA_NOISE_FUNCTIONS = ('captcha.helpers.noise_null', 
 
 -      'captcha.helpers.noise_arcs', # 线
 
 -      'captcha.helpers.noise_dots', # 点
 
 - )
 
 - CAPTCHA_CHALLENGE_FUNCT = 'captcha.helpers.random_char_challenge'
 
 - CAPTCHA_CHALLENGE_FUNCT = 'captcha.helpers.math_challenge'
 
 - CAPTCHA_TIMEOUT = 1
 
 
  复制代码 
 
 
执行数据迁移,在数据表中生成captcha_captchastore表 
 
python manage.py migrate 
 
 
 
在urls.py中添加路由 
 
urlpatterns = [ 
    path('captcha/', include('captcha.urls')),       # 图片验证码 路由 
    path('refresh_captcha/', views.refresh_captcha),    # 刷新验证码,ajax 
] 
 
 
 
下面是源代码。  
 
urls.py文件 
 
- from django.urls import path
 
 - from django.conf.urls import include
 
 - from App.views import IndexView
 
 - from App import views
 
 - urlpatterns = [
 
 -     path('captcha/', include('captcha.urls')),
 
 -     path('refresh_captcha/',views.refresh_captcha),
 
 -     path('',IndexView.as_view()),
 
 - ]
 
 
  复制代码 
 
 
views.py文件 
 
- from django.shortcuts import render
 
 - from django.views.generic import View
 
 - from captcha.models import CaptchaStore
 
 - from captcha.helpers import  captcha_image_url
 
 - from django.http import HttpResponse
 
 - import json
 
 - # 创建验证码
 
 - def captcha():
 
 -     hashkey = CaptchaStore.generate_key()   #验证码答案
 
 -     image_url = captcha_image_url(hashkey)  #验证码地址
 
 -     captcha = {'hashkey': hashkey, 'image_url': image_url}
 
 -     return captcha
 
 - #刷新验证码
 
 - def refresh_captcha(request):
 
 -     return HttpResponse(json.dumps(captcha()), content_type='application/json')
 
 - # 验证验证码
 
 - def jarge_captcha(captchaStr, captchaHashkey):
 
 -     if captchaStr and captchaHashkey:
 
 -         try:
 
 -             # 获取根据hashkey获取数据库中的response值
 
 -             get_captcha = CaptchaStore.objects.get(hashkey=captchaHashkey)
 
 -             if get_captcha.response == captchaStr.lower():     # 如果验证码匹配
 
 -                 return True
 
 -         except:
 
 -             return False
 
 -     else:
 
 -         return False
 
 - class IndexView(View):
 
 -     def get(self, request):
 
 -         hashkey = CaptchaStore.generate_key()  # 验证码答案
 
 -         image_url = captcha_image_url(hashkey)  # 验证码地址
 
 -         captcha = {'hashkey': hashkey, 'image_url': image_url}
 
 -         return render(request, "login.html", locals())
 
 -     def post(self,request):
 
 -         capt=request.POST.get("captcha",None)         #用户提交的验证码
 
 -         key=request.POST.get("hashkey",None)          #验证码答案
 
 -         if jarge_captcha(capt,key):
 
 -             return  HttpResponse("验证码正确")
 
 -         else:
 
 -             return HttpResponse("验证码错误")
 
 
  复制代码 
   
 
login.html文件,这里使用 js 动态刷新图形验证码用到了jquery和bootstrap的js,所以,我们提前将jquery和bootstrap放在了static文件夹下。关于如何加载静态文件​ 
 
- {% load static %}
 
 - <!DOCTYPE html>
 
 - <html lang="en">
 
 - <head>
 
 -     <meta charset="UTF-8">
 
 -     <title>Title</title>
 
 -     <script src="{% static 'bower_components/jquery/dist/jquery.min.js' %}"></script>
 
 -     <script src="{% static 'bower_components/bootstrap/dist/js/bootstrap.min.js'%}"></script>
 
 - </head>
 
 - <body>
 
 -     <form action="/" method="post">
 
 -         <a href="#" class="captcha">
 
 -             <img src="{{ captcha.image_url }}" alt="点击切换" id="id_captcha" >
 
 -         </a> <br>
 
 -         <input type="text" name="captcha" placeholder="验证码"> <br>
 
 -         <input value="{{ captcha.hashkey }}" name="hashkey" type="hidden" id="id_captcha_0">
 
 -         <button type="submit" class="btn btn-primary btn-block ">提交</button>
 
 -     </form>
 
 - <script>
 
 -         <!-- 动态刷新验证码js -->
 
 -         $(document).ready(function(){
 
 -             $('.captcha').click(function () {
 
 -                 $.getJSON("refresh_captcha/", function (result) {
 
 -                     $('#id_captcha').attr('src', result['image_url']);
 
 -                     $('#id_captcha_0').val(result['hashkey'])
 
 -                 });
 
 -             });
 
 -         });
 
 - </script>
 
 - </body>
 
 - </html>
 
 
  复制代码 
从你的描述中,我了解到你发现了使用固定的hashkey和captcha可以通过伪造POST请求绕过验证码验证。这个问题是由于验证码在后端验证时,固定的hashkey和captcha能够匹配,导致验证通过。为了解决这个问题,你可以在验证时增加一些额外的安全措施。 
 
一个简单的解决方案是对每次请求使用不同的hashkey。这样,即使攻击者获得了一个有效的hashkey和captcha组合,他们也不能绕过验证码验证,因为每次请求的hashkey都不同。这可以通过在视图中实现一个新的功能来完成。例如,你可以在刷新验证码时生成一个新的hashkey,并将其存储在session中。 
 
1. 在 `refresh_captcha` 函数中,将新生成的 hashkey 保存在 session 中: 
 
- def refresh_captcha(request):
 
 -     new_captcha = captcha()
 
 -     request.session['captcha_hashkey'] = new_captcha['hashkey']
 
 -     return HttpResponse(json.dumps(new_captcha), content_type='application/json')
 
 
  复制代码 
 
2. 在 `jarge_captcha` 函数中,检查传入的 hashkey 是否与 session 中存储的相同。如果不同,则表示用户可能伪造了 POST 请求: 
 
- def jarge_captcha(request, captchaStr, captchaHashkey):
 
 -     if captchaStr and captchaHashkey:
 
 -         try:
 
 -             if request.session.get('captcha_hashkey', '') != captchaHashkey:
 
 -                 return False
 
 -             
 
 -             # 获取根据hashkey获取数据库中的response值
 
 -             get_captcha = CaptchaStore.objects.get(hashkey=captchaHashkey)
 
 -             if get_captcha.response == captchaStr.lower():     # 如果验证码匹配
 
 -                 return True
 
 -         except:
 
 -             return False
 
 -     else:
 
 -         return False
 
 
  复制代码 
 
注意,在调用 `jarge_captcha` 函数时,需要传入 `request` 参数: 
 
- class IndexView(View):
 
 -     # ...
 
 -     def post(self, request):
 
 -         capt = request.POST.get("captcha", None)  # 用户提交的验证码
 
 -         key = request.POST.get("hashkey", None)  # 验证码答案
 
 -         if jarge_captcha(request, capt, key):
 
 -             return HttpResponse("验证码正确")
 
 -         else:
 
 -             return HttpResponse("验证码错误")
 
 
  复制代码 
 
通过这种方法,你可以确保每次请求的hashkey都是不同的,从而提高安全性。希望这个解决方案对你有帮助! 
 
 
 |   
 
 
 
 |