文章总结: 本文详细介绍了安全运营平台登录模块的安全设计与实现,重点阐述了验证码防自动化攻击、密码哈希存储、Session生命周期管理、登录拦截装饰器等核心安全机制。文章提供了具体的Django代码示例和可操作的安全开发建议,强调登录模块作为第一道防火墙的重要性,并预告了下期权限模型实战内容。 综合评分: 85 文章分类: 安全开发,应用安全,安全建设,安全运营,WEB安全
【Atract:安全运营平台】 01:登录模块安全自查清单:你中了几个?
原创
cjstang cjstang
新安集
2026年5月9日 09:30 上海
在小说阅读器读本章
去阅读
友情提醒
本文阅读时间推荐:5 min
如想讨论
以下内容
▼
欢迎关注公众号联系我哟
▼
*CISP-TRS(威胁响应专家 – 备考中)*
*OSCP+备考经验(已通过认证)*
CISSP备考经验(已通过认证)
CCSK(云安全)(已通过认证)
ISO/IEC 27001 Foundation(已通过认证)
序
写在前面
| 一个安全运营平台,如果连登录都不可信,后面的一切都是假的。
如前面文章所说,历史小半年,从零开发了一套内部安全运营平台,边写边踩坑,边踩边思考:每一行代码,在攻击者眼里意味着什么?
在开源出来之前,我想记录一下每个功能的设计,索性记录成一个系列以供大家交流,这个系列不讲大道理,我会直接贴代码 + 讲安全设计,希望能向各位专职开发或者做安全开发的前辈取取经。
{一、一个登录模块,需要防什么?}
很多人觉得登录就是:输入账号密码 → 验证 → 跳转。
但在安全场景下,你需要面对:
| 攻击方式 | 真实威胁 | | — | — | | 暴力破解 | 脚本无限尝试弱口令 | | 撞库 | 用泄露的密码库批量测试 | | Session劫持 | 窃取登录态 | | 验证码绕过 | 自动化工具无视验证码 | | 账号锁定后绕过 | 业务逻辑缺陷 |
所以,一个”安全”的登录模块,本质是第一道防火墙。
{二、代码实现:我是这样写登录}
| 以下是我平台 soc01/views/login.py 的核心代码(已简化展示,保留安全关键点)
2.1 验证码:拒绝自动化攻击
python
from soc01.utils.captcha import Captcha
captcha_code = request.POST.get('captcha_code', '').strip()session_captcha = request.session.get('captcha_code', '')
if not captcha_code: error = '请输入验证码!'elif not Captcha().verify(captcha_code, session_captcha): error = '验证码错误,请重新输入!'
安全设计点:
- 验证码与 Session 绑定,不靠前端校验
- 验证后立即清除 Session 中的验证码,防止重放
- 登录失败时强制刷新验证码,不给脚本机会
💡 一个小细节:
captcha_timestamp = int(datetime.now().timestamp())传给前端,强制浏览器重新请求验证码,避免旧验证码被复用。
2.2 密码:永远不存明文
python
from django.contrib.auth.hashers import check_password
if check_password(password, user_obj.password): login_success = True
安全设计点:
- 存储用
make_password哈希加盐(PBKDF2) - 比对用
check_password,不自己写算法 - 日志里绝不打印密码原文(哪怕调试)
很多泄露事故,源头是 debug 日志里打印了
password=123456。
2.3 Session:控制凭证生命周期
python
request.session['user_info'] = { 'id': user_obj.id, 'account': user_obj.account, 'uname': user_obj.uname, 'roles': roles_info,}request.session.set_expiry(7200) # 2小时过期
安全设计点:
- 明确 Session 过期时间(2小时)
- 登出时
session.clear(),彻底销毁 - Session 中只存必要信息,不存密码等敏感字段
登录成功后立即
pop('captcha_code'),避免验证码残留被滥用。
2.4 登录拦截装饰器:统一鉴权
python
def login_required(view_func): def wrapper(request, *args, **kwargs): if not request.session.get('user_info'): messages.warning(request, '请先登录后再操作!') return redirect('/login/') return view_func(request, *args, **kwargs) return wrapper
使用方式:
python
@login_requireddef dashboard(request): ...
安全设计点:
- 全局复用,避免遗漏
- 未登录直接重定向,不暴露任何业务数据
- 可扩展:后续可加 IP、User-Agent 二次校验
{三、多角色支持:权限前置设计}
在登录阶段就注入角色信息:
python
roles_info = []for role in user_obj.roles.all(): roles_info.append({ 'role_id': role.id, 'role_identifier': role.identifier, # admin / operator / auditor 'role_name': role.name })request.session['user_info']['roles'] = roles_info
安全设计点:
- “` 登录时加载 ≠ 只依赖登录时加载:Session 存权限用于前端性能优化,真正的权限校验在装饰器中实时查库,性能和安全性兼得
* 支持多角色并存(比如:知识库管理员 + 大黑阔(漏洞提交人)等)
* 为后续 `@require_permission` 装饰器打下基础,前端用 Session 控制菜单显隐,后端用数据库实时判断,两层分离,互不信任
> 记住一句话:**前端权限是用户体验,后端权限是安全红线。**


**{四、登出:不是“关掉浏览器”那么简单}**
python def logout(request): request.session.clear() messages.success(request, ‘已成功退出登录!’) return redirect(‘/login/’) “`
常见错误:
- 只删前端 Cookie,后端 Session 仍有效 → Session 可被重放
- 没有清空服务端 Session → 占用存储 + 安全隐患
正确做法:
- 服务端
clear()或flush() - 客户端清除 Cookie(Django 默认行为)
{五、安全开发三板斧(本期敲重点)}
| 斧头 | 对应设计 | | — | — | | 永远不相信用户输入 | 验证码、参数 strip、空值校验 | | 永远保护凭证生命周期 | Session 过期、登出销毁、验证码一次性 | | 永远为审计留痕 | 记录登录时间、角色、IP(可扩展) |
{六、下期预告}
《安全运营平台 02:权限模型实战 —— 最小权限原则落地》
我会分享:
- RBAC 表结构设计
@require_permission装饰器实现- 菜单动态渲染
- 一个真实案例:越权漏洞是如何被权限模型拦截的
写在最后
这个系列所有代码都来自我正在开发的安全运营平台,不是 demo,不是 toy。
如果你也在做:
- 安全平台开发
- 内部运营系统
- 或单纯想学带安全思维的 Django 开发
欢迎关注、留言、讨论。
安全开发,不是”能跑就行”,而是”能防御才行”。
上一篇文章:
十年甲方安全之路:从表格记录漏洞到一个人使用AI开发上线的安全运营平台(SOC)
历史精彩文章:
甲方攻防大戏:功劳归我,活?归供应商,钱?还想续约不?
Hi,97小伙,请远离黑灰产,珍惜创业机会!别实名制扫描我了~!
从被动写 2 小时情况说明到主动防患:一个甲方安全人牵头 fastjson 升级的全纪实
END
十二载·甲方信安
初心如磐守底线
实战沉淀赋价值
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:新安集 cjstang cjstang《【Atract:安全运营平台】 01:登录模块安全自查清单:你中了几个?》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。









评论