短信验证码(SMS OTP)广泛应用于登录、注册、交易确认、账号绑定等关键业务流程。
但在安全设计上,“能发短信”并不等于“短信发送是可控的”。
如果缺乏系统性的安全约束,短信接口很容易被滥用为:
- 短信轰炸工具
- 用户骚扰与社工入口
- 绕过风控或消耗资源的攻击面
本文结合实际业务与安全实践,从 发送频控、发送对象数量控制、短信内容可信性 三个关键方向,总结短信验证码场景中必须具备的安全设计能力。
一、发送频控:以“主体维度”做强限制
1. 风险背景
短信接口的第一道防线是频控,但如果频控仅停留在 手机号维度,攻击者只需不断切换号码即可轻易绕过限制。
因此,频控必须围绕“主体”而非“单一参数”设计。
2. 频控维度设计建议
推荐在短信发送接口中,至少引入以下维度进行限制:
- 设备维度
- deviceId、设备指纹、设备画像,以及任何能够唯一标识该设备的字段,都能用于频控
- 用于识别同一物理或逻辑设备的高频行为
- IP / 网络维度
- 源 IP、IP 段、ASN
- 防止脚本或代理池批量触发
- 账号维度
- 账号 ID、登录态、业务身份、以及任何能够唯一标识该用户的字段,都能用于频控
- 限制单账号异常触发短信能力
- 手机号维度
- 单手机号在分钟 / 小时 / 天级别的发送上限
3. 实践建议
- 采用多维度叠加限制(想象成把这些判断参数都放进一个篮子,只要其中一个参数命中,就算命中防御),而非单点判断
- 形成 短期 / 中期 / 长期 的梯度限制策略
- 在异常高频触发时,引入:
- 图形验证码
- 行为验证码
- 二次校验
- 记录频控命中日志,用于后续安全分析与策略调优
设计目标:
让单一主体无法通过切换手机号、IP 或设备来持续突破短信发送限制。
二、发送对象数量控制:防止“群发式”滥用
1. 场景问题
短信验证码的本质是 “向单一用户发送的安全凭证”,
但在实际业务中,常会出现以下扩展场景:
- 卡片分享
- 邀请好友
- 好友协助 / 转赠
如果对发送对象数量缺乏限制,这类接口极易被滥用为 短信骚扰或群发工具。
2. 典型风险点
- 前端可控发送对象数量
- 单次请求携带大量手机号
- “分享 / 邀请”场景被滥用为群发入口
即使接口逻辑正确,也可能引发:
- 用户投诉
- 运营风险
- 合规与监管风险
3. 安全设计建议
- 评估业务合理对象数量
- 例如:卡片分享默认 1 人,最多 3 人
- 设置单次与周期性上限
- 防止通过多次操作绕过限制
- 分场景差异化限制
- 分享、邀请、绑定等场景上限应不同
- 非核心场景严禁大规模发送
- 超过阈值直接拦截,而非降级放行
设计目标:
明确“合理数量”,让短信发送始终保持“单用户验证”的安全属性。
三、短信内容不可前端可控:防止信任边界错位
1. 风险说明
如果短信内容由前端直接传参或拼装,将引入严重的信任边界问题:
- 攻击者可构造钓鱼、误导性文本
- 服务端被动“信任前端”,导致语义失控
- 绕过业务规则发送非预期短信内容
前端输入天然不可信,短信内容尤其如此。
2. 核心设计原则
- 短信内容必须由服务端模板生成
- 前端仅传递必要的业务标识信息
- 如:场景类型、操作标识
- 服务端对前端可控参数进行严格合法性校验
3. 实践建议
- 使用 模板 ID + 参数占位 的生成方式
- 对可控参数进行:
- 白名单校验
- 长度限制
- 格式与字符集校验
- 严禁前端直接传入完整短信正文或可拼接内容
设计目标:
服务端完全掌控短信内容与语义,前端仅负责触发业务场景。
四、总结
短信验证码的安全设计,并不是“加一个验证码接口”就结束,而是需要在以下三条线上建立完整防护:
- 频控:多维度限制,防止切换主体绕过
- 对象数量:限制发送范围,避免被滥用为群发
- 内容控制:模板化生成,前端不可直接控制内容
只有把这些基础能力设计清楚,
短信验证码才能真正成为 安全体系的一环,而不是攻击入口。
以下是一些典型场景的安全防控措施总结
后续可结合风险模型与用户行为分析,对短信发送能力进行动态调节与分级控制。