6.6 安全最佳实践


6.6 安全最佳实践

本节摘要:功能做加法,安全做减法——它决定不了服务有多好,却能一票否决它。本节把全书散落的安全点收拢成一张上线自检清单:注入、越权、密钥泄露、调试模式暴露、传输加密、常见 Web 攻击面。每个条目都对应轻记账里已学过的具体防线,收官之前逐条打勾,v1.0 才配得上"上线"两个字。

本节要解决什么

阅读完本节,你应当能够:

  1. 解释注入攻击的原理,确认参数化查询的正确用法
  2. 做越权自检:逐个接口确认资源归属校验
  3. 列出密钥与敏感配置的正确处理方式
  4. 认识常见 Web 攻击面及框架提供的默认防护
  5. 执行完整的上线前安全自检清单

安全的思维方式

安全不是"加一个防火墙"的一次性动作,而是假设敌人已进门的持续审计:假设用户会提交恶意输入,假设数据库会被拖走,假设任何一处校验的疏漏都会被发现。听起来吓人,好消息是轻记账一路走来已经埋好了大部分防线——本节一半的内容是把它们点名叫出来,另一半是补齐剩余的几块短板。

图 6-6 轻记账的攻击面与防线地图

图 6-6 轻记账的攻击面与防线地图

五道重点防线逐条过

注入防线(5.1 落实)。所有数据库操作只用参数化查询:SQL 模板与数据分离,数据永远是数据、永远当不了代码。自查方法:全局搜索字符串拼接进 SQL 的写法,一处不留。

越权防线(5.4 落实)。每个按 id 操作资源的接口都两问:登录了吗(装饰器)、这条数据是你的吗(查询条件带归属)。自查方法:拿 A 用户的凭证对 B 用户的数据执行改删,必须得到 404 或 403。

凭证防线(5.4 落实)。密码加盐高迭代哈希;登录失败提示模糊;连续失败锁定。自查方法:确认数据库里没有任何字段能还原出明文密码。

配置防线(6.2 落实)。密钥全走环境变量,.env 进忽略清单,Git 历史里搜不到密钥;生产环境调试模式关闭。自查方法:在生产环境故意访问一个会报错的路径,响应必须是简洁的 500 页而非带源码上下文的调试页。

传输防线(6.3 落实)。HTTPS 全站启用,HTTP 强制跳转 HTTPS;登录接口绝不允许明文提交。自查方法:浏览器地址栏确认小锁图标,历史页面无混合内容告警。

补齐的最后几块短板

CSRF 跨站请求伪造:恶意网站诱导已登录用户的浏览器向你的接口发请求——浏览器会自动带上 Cookie。传统表单站点的解法是"表单里埋一次性令牌、服务端核验";轻记账这类纯 JSON API 依赖 CORS 收紧(6.1 的生产配置)与会话 Cookie 的 SameSite 属性,两道闸都要检查。

依赖安全:你信任的第三方库也可能有漏洞。保持依赖清单定期更新,关注所用库的安全公告——2.3 说的"依赖是负债",其利息之一就是这份持续看守的责任。

日志与监控:记录登录失败、越权尝试、异常堆栈,日志是事故后唯一的时间机器。但日志本身也是敏感面:绝不记录明文密码与完整令牌

最小权限:数据库账号不给超管权限;服务器上服务用独立低权限用户跑,不给 root——每一处都遵循"只给它需要的最小能力"。

演练:一次完整的上线自检

把上述内容浓缩成打勾清单,逐条过一遍轻记账:

[ ] 全局无字符串拼接 SQL [ ] 所有资源接口带归属校验,跨用户操作返回 404 [ ] 密码字段全为加盐哈希,登录提示不区分账号与密码错误 [ ] 登录连续失败五次锁定十分钟 [ ] .env 不在 Git,历史无密钥,生产密钥为独立强随机值 [ ] 生产调试模式关闭,报错页无源码信息 [ ] HTTPS 启用,HTTP 跳转,无混合内容 [ ] CORS 收紧至正式域名,Cookie 带 SameSite [ ] 依赖为近期版本,无已知高危公告 [ ] 日志在记录,且无敏感明文

十项全勾才许宣布上线。变式一:以攻击者视角写一份"轻记账渗透笔记"——只写思路不写代码:先探什么接口、试什么输入、看什么报错,你会发现每一步都撞在自己修过的墙上。变式二:把清单做成 CI 脚本的一部分(能自动化的项:密钥扫描、依赖检查),安全从"上线前检查"进化为"每次提交都查"。

易错点清单

  • "我项目小没人盯":自动化扫描不挑食,小站反而常沦为跳板
  • 安全靠清单跑一次:上线后代码还在改,清单要随每次大改动重跑
  • 报错信息太热情:堆栈、SQL、路径全端给用户,等于给攻击者画地图
  • 只在入口设防:纵深防御是原则——数据库约束、应用校验、网关限流层层设卡

漏洞与防御对照表

安全知识最容易停留在口号层面,把它整理成"攻击手法 → 成因 → 防御手段 → 代码层面的动作"四栏,才落得了地。

漏洞类型 成因 防御手段 代码层面的动作
SQL 注入 把用户输入拼进 SQL 字符串 参数化查询 一律用 ORM 或占位符,禁止字符串拼接
XSS 把用户输入原样输出到页面 输出转义 + 内容安全策略 模板引擎自动转义,慎用"不转义"标记
CSRF 利用用户已登录的身份发起请求 令牌校验 + SameSite Cookie 表单与接口带一次性令牌
越权访问 只验证登录、不验证归属 每次数据访问都校验归属 查询条件带上当前用户标识
敏感信息泄露 密钥进仓库、日志打明文密码 密钥走环境变量、日志脱敏 提交前扫描、日志过滤
依赖供应链风险 第三方库存在已知漏洞 依赖扫描与定期升级 锁定版本 + 定期跑扫描工具
# 依赖漏洞扫描:把已知漏洞清单拉出来(应加入持续集成流程) python -m pip_audit -r requirements.txt # 输出示例:django 3.2.0 → 已知漏洞 GHSA-xxxx,建议升级到 3.2.15 及以上 # 密钥与敏感信息扫描:检查工作区是否误提交密钥 python -m detect_secrets scan --all-files

上线前的安全自检清单

把上面这张表压缩成可执行的一次自检,每次发版前过一遍,成本不到十分钟:

  1. 依赖扫描无高危项——有高危项先升级,无法升级的要有临时缓解措施与排期;
  2. 仓库里没有密钥——用扫描工具过一遍,仓库历史里也不能有(历史中的密钥同样要轮换);
  3. 所有数据访问都带归属校验——抽查几个接口,把用户标识换成别人的,看能否读到数据;
  4. 错误信息不泄露内部细节——生产环境关掉调试模式,异常页面不显示堆栈与配置;
  5. 传输全程加密——对外只提供 HTTPS,内网跳转也要配置好证书;
  6. 备份存在且可恢复——这一条既是安全也是可用性底线,勒索与误删都靠它兜底。

安全的三个思维习惯

比具体清单更重要的是三条习惯:默认不信任输入——所有进入系统的数据都要校验,包括"内部"系统传来的;最小权限——服务账号、数据库账号、内部接口调用都只给刚好够用的权限;假设已被攻破——设计时问一句"如果这一层被拿下,攻击者能走到哪一步",据此做隔离与限速。

这三条习惯的共同点是把安全从事后补救前移到设计阶段。等系统上线后再补安全,代价通常是重写。

本节要点回顾

  • 安全是持续审计不是一次性动作,假设敌人已进门
  • 五大已建防线:参数化、归属校验、哈希凭证、配置分离、HTTPS
  • 补齐的短板:CSRF 双闸、依赖看守、日志卫生、最小权限
  • 十项自检清单全勾才上线,能自动化的进 CI
  • 报错与日志都是双刃剑:对人要简洁,对攻击者要吝啬

清单打完,v1.0 正式上线。全书"轻记账成长记"就此闭环——从二十行脚本到安全上线的小服务,你走过的每一站,都是全栈开发者地图上的一个坐标。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U