跳转到帖子

背景

最近在做一个内部业务系统的安全复盘时,遇到一个比较典型的场景:登录接口没有出现明显漏洞利用痕迹,但日志里能看到大量异常请求,包括高频失败登录、参数结构异常、不同 User-Agent 的批量访问,以及少量疑似探测请求。

这类问题在实际环境中很常见。它不一定意味着系统已经被入侵,但通常说明接口暴露面、认证策略、日志可观测性和风控策略存在短板。本文不讨论任何攻击利用方法,重点放在如何从防守视角复盘、分析和加固。

问题场景

业务系统采用常见的前后端分离架构,登录接口大致如下:

POST /api/auth/login HTTP/1.1
Content-Type: application/json

{
  "username": "test",
  "password": "******",
  "captcha": "1234"
}

排查时发现几个现象:

  • 短时间内出现大量登录失败,来源 IP 分散。
  • 部分请求缺失 captcha 字段,或字段类型不符合预期。
  • 接口返回信息区分了“用户不存在”和“密码错误”。
  • 同一账号在不同 IP 下连续失败,但应用层没有统一限速。
  • 日志记录了请求结果,但没有记录关键风险字段,后续关联分析困难。

这些问题单独看都不算复杂,但组合在一起会明显提高账号体系被持续探测的风险。

技术分析

1. 返回信息过于明确

登录接口如果返回“用户不存在”“密码错误”“验证码错误”等过于细粒度的信息,容易暴露账号枚举面。防守上更推荐对外统一返回认证失败,只在服务端日志中记录具体原因。

// 不推荐
{
  "code": 1001,
  "message": "用户不存在"
}

// 推荐
{
  "code": 401,
  "message": "用户名或密码错误"
}

需要注意的是,统一返回并不代表丢失排查能力。正确做法是对外模糊,对内详细。

login_fail reason=user_not_found username_hash=8f14e45f ip=10.1.2.3 ua_hash=...

2. 缺少分层限速

很多系统只做了简单的 IP 限速,但在实际环境中,单一 IP 限速效果有限。更合理的策略是分层限速,例如:

  • 按 IP 限速:限制单个来源的高频请求。
  • 按账号限速:限制同一账号被反复尝试。
  • 按设备指纹或会话标识限速:辅助识别异常客户端。
  • 按网段、ASN、代理特征做风险评分,而不是简单封禁。

Nginx 层可以先做基础频控,应用层再做更精细的策略。

http {
    limit_req_zone $binary_remote_addr zone=login_ip:10m rate=5r/m;

    server {
        location /api/auth/login {
            limit_req zone=login_ip burst=10 nodelay;
            proxy_pass 
        }
    }
}

这类配置只能作为第一层防护,不能替代应用层的账号维度风控。

3. 参数校验不完整

登录接口是高频风险入口,参数校验应尽量前置。常见问题包括:

  • username 未限制长度,导致日志污染或异常消耗。
  • password 接受非字符串类型,触发框架边界行为。
  • captcha 可为空或字段缺失时仍进入密码校验逻辑。
  • JSON 解析异常被统一吞掉,导致监控无法识别异常请求。

建议在进入认证逻辑前完成结构校验,并对异常类型进行分类记录。

if not isinstance(username, str) or len(username) > 128:
    return auth_failed()

if not isinstance(password, str) or len(password) > 256:
    return auth_failed()

if captcha_required and not valid_captcha(captcha):
    return auth_failed()

这里的重点不是代码本身,而是避免让异常输入进入核心认证流程。

4. 日志字段不足

不少系统在出现风险事件后才发现日志不够用。登录接口至少建议记录以下字段:

字段用途
request_id串联网关、应用、审计日志
username_hash保护隐私的同时支持账号维度分析
client_ip来源分析,注意结合可信代理头
user_agent_hash聚合异常客户端特征
fail_reason内部排查原因,不对外返回
risk_score风控策略命中情况
latency_ms识别异常耗时和潜在资源消耗

涉及密码、验证码、完整 Token、Cookie 的内容不要写入日志。这个问题在审计中非常常见,后续日志平台权限一旦扩大,敏感信息泄露面会被放大。

关键排查步骤

1. 先确认时间线

不要一上来就封 IP 或改策略,先确认异常开始时间、峰值时间、持续时间,以及是否和业务发布、营销活动、爬虫流量有关。

# 示例:按分钟统计登录失败数量
cat app.log | grep 'login_fail' | awk '{print $1" "$2}' | cut -c1-16 | sort | uniq -c

如果日志是 JSON 格式,可以用 jq 做更稳定的分析。

cat app.log | jq -r 'select(.event=="login_fail") | .time[0:16]' | sort | uniq -c

2. 识别异常聚合维度

重点不要只看 IP。建议同时聚合以下维度:

  • 失败次数最多的账号。
  • 单账号来源 IP 数量。
  • 单 IP 尝试账号数量。
  • User-Agent 分布。
  • 请求体异常比例。
  • 验证码失败和密码失败的比例。
# 按 username_hash 聚合失败次数
cat app.log | jq -r 'select(.event=="login_fail") | .username_hash' | sort | uniq -c | sort -nr | head

3. 检查认证链路顺序

认证链路建议遵循“低成本校验在前,高成本操作在后”的原则。例如:

  • 请求方法、Content-Type 校验。
  • JSON 结构和字段类型校验。
  • 限速和风险策略判断。
  • 验证码或二次验证校验。
  • 账号状态检查。
  • 密码哈希校验。

密码哈希计算通常是相对高成本操作,如果大量异常请求都能走到这一步,可能造成不必要的资源压力。

4. 检查代理 IP 获取逻辑

如果系统部署在反向代理、负载均衡或 CDN 后面,应用获取客户端 IP 时要谨慎。不能直接信任任意请求头中的 X-Forwarded-For。

# 思路示例:只信任来自可信代理的转发头
trusted_proxies = ["10.0.0.0/8", "192.168.0.0/16"]

if remote_addr in trusted_proxies:
    client_ip = parse_x_forwarded_for(headers)
else:
    client_ip = remote_addr

如果这一步做错,限速和审计都会失真。

加固建议

1. 对外响应统一

登录失败统一返回认证失败,不暴露账号是否存在、是否冻结、验证码是否单独错误等细节。内部日志保留具体原因,方便排查。

2. 增加账号维度保护

对连续失败的账号进行冷却,例如短时间内多次失败后要求二次验证,或者延迟再次尝试。注意不要简单锁死账号,否则可能被滥用为拒绝服务手段。

3. 引入风险评分而非单点拦截

可以把 IP 信誉、失败次数、账号敏感度、设备变化、地理位置变化、请求异常程度综合为风险分。风险高时提高验证强度,而不是只依赖固定阈值。

4. 敏感日志脱敏

用户名建议哈希化后记录,手机号、邮箱保留部分掩码即可。Token、密码、验证码不应进入日志。

username_hash = sha256(normalize(username) + log_salt)

这里的 log_salt 建议单独管理,避免被用于反查明文。

5. 设置告警规则

告警不要只看总量,也要看结构性异常。例如:

  • 同一账号 10 分钟内失败来源超过 N 个。
  • 同一 IP 10 分钟内尝试账号超过 N 个。
  • 登录失败率突然高于历史基线。
  • 参数校验失败比例异常升高。
  • 验证码失败量与密码失败量比例异常。

这类告警比单纯的 QPS 告警更有价值。

注意点

  • 不要在生产环境直接打印完整请求体,尤其是登录、支付、个人资料接口。
  • 限速策略上线前要灰度,避免误伤真实用户。
  • 账号锁定策略要谨慎,避免被利用来批量锁定他人账号。
  • 如果接入 CDN 或网关,应用层仍应保留基础校验和审计能力。
  • 排查异常流量时要区分安全风险、业务活动和监控探测,避免误判。

总结

登录接口安全并不只是“密码校验是否正确”这么简单,它涉及认证反馈、限速、参数校验、日志审计、风险识别和告警联动。很多线上风险不是单个高危漏洞导致的,而是多个小问题叠加后形成了可被持续消耗和探测的入口。

从长期维护角度看,建议把登录接口当作一个独立的安全资产来管理:有清晰的日志字段,有分层限速,有统一的错误响应,有可回溯的审计链路,也有可灰度调整的风控策略。这样即使遇到异常流量,也能更快判断影响范围,并采取相对稳妥的处置措施。

网络流量与边界分析示意图
网络请求、日志与边界流量分析示意

0篇意见

推荐意见

没有意见。

游客
抱歉,你的帖子内容包括我们不允许的字词。请编辑你的帖子,删除下面高亮的屏蔽字。
添加意见…