一个请求能带上上百组口令的接口方法,为什么让登录失败锁定拦不住
聊登录爆破防护时,一个请求能带上上百组口令的接口方法,为什么让登录失败锁定拦不住,常被低估。问题不在口令校验松紧,而在它允许把成批参数塞进同一次调用:服务端逐条执行,防御侧的失败计数却按请求推进。WordPress 从 3.5 起默认开启 XML-RPC,界面上的开关后来也被移除,遗留的批量方法 system.multicall 因此长期暴露在公网上。
批量方法把爆破成本压到几个请求
system.multicall 的初衷是减少往返:客户端把多个调用打包成一个数组发过去,服务端依次执行后一次性返回结果。对正常使用者省的是时间,对攻击者省的是请求数。公开资料给的量级很直白,单个命令里可以尝试数百个口令,仅三四个 HTTP 请求就能试完上千组口令组合。
经济账由此改写。逐条提交时,攻击者要承担建连与限速的开销,防御方也更容易在连接层看出异常;打包之后,同样的猜测量用极少的请求就能完成,暴露面还更低。
按失败次数计数的锁定追不上凭据数
多数锁定策略的口径是失败事件数:某个账号或来源地址连续失败若干轮就锁定一段时间。它默认了一个前提,一次请求只携带一组凭据。批量方法恰好打破前提,上百组错误凭据归进同一次调用,计数器最多前进一格,阈值追不上猜测速度。
要在这种入口面前仍然有效,计数就得下沉到凭据层:按用户名分别累计失败次数,来源维度按可疑凭据的条目数累计,而不是按连接数。限流同理,配额按调用条目结算,否则打包请求一次就能把额度耗尽。
同一机制还能被用来做放大攻击
批量之外,这类遗留接口里还常有会主动对外发起请求的方法,pingback 就是一例。攻击者把受害站当跳板,让它向目标发出大量回显请求,来源是真实站点,在防御设备看来链路完全正常。历史上出现过把约 2500 个站点变成发起拒绝服务攻击的僵尸网络的情况,效果来自反射与叠加:被打的一方看到的是海量正常网站的访问,而不是一个攻击源。
对被动卷入的站点来说,代价是出口带宽被吃满、地址进了黑名单、信誉受损,自身数据却一个字节没丢。收口不只是为了防盗号,也是为了不当别人的跳板。
关闭还是拦截:接口收口的层次与取舍
要不要保留这类入口,取决于还有没有合法调用方依赖它。彻底关闭最省心:在路由层移除端点,或在应用入口直接拒绝相关方法名,代价是老的远程发布与客户端集成一起失效。确有依赖时,更常见的做法是收窄公网能力面,按路径拦截、只放行特定来源,或把批量方法从允许列表里剔除,只留必要的单调用。
层次上,应用内拦截更可靠,因为路径规则容易被大小写、编码和重写差异绕过;网关或重写层的封锁胜在生效快,不必发版就能先止血。两处都收口才算关闭。相对照之下,较新的接口设计倾向把能力面收紧:AnQiCMS 以 JWT 承载后台鉴权,接口层的能力面以公开接口为准,并内置针对 SQL 注入与 XSS 的防护,它不提供把上百组凭据打包提交的遗留方法,但按请求计数与按凭据计数的差异仍值得留意:攻击面大小往往比阈值调多低更关键。
常见问题
问:登录锁定已经开启,还要管遗留的批量接口吗? 要。锁定按失败事件计数,批量入口让上百组错误凭据只算一次事件,两者不在同一口径上。先确认站点有没有能打包提交凭据的路径,再谈阈值调多低。
问:直接关闭会不会伤到正常业务? 取决于调用方。远程发布、老客户端之类的集成可能仍依赖这类协议。稳妥顺序是先统计相关路径的合法调用量,再决定彻底关闭、按来源放行还是只剔除批量方法。
问:拦在网关层和应用层,选哪个? 不必二选一。网关或重写层的封锁能在不改代码时立刻止血,应用层的拒绝不依赖路径写法的一致性,两者失效方式不同,同时设置才把缝隙压小。
问:放大攻击打的是别人,站点为什么要负责? 因为跳板身份是被动承担的:出向流量、被目标拉黑、被通报都落在这台服务器上。把对外发起请求的方法限制在必要范围内,等于把自己从别人的攻击链里摘出来。