|
登录框是注入站登黑客最爱的靶子。随便找个没做防护的录系老系统,在密码框里敲一句 ' OR '1'='1,统设回车,计实后台可能就直接放行了。注入站登这不是录系段子,是统设还在发生的真实事故。我见过某内部管理系统,计实用户名输入框连长度都没限制,注入站登DBA一查慢查询日志,录系全是统设拼进去的恶意SQL片段。 防SQL注入的计实核心,说白了就一句话:**别把用户输入当代码执行**。注入站登但落地到登录系统设计里,录系牵扯的统设细节比想象中多。 先谈参数化查询。这是最硬的一道防线。用PreparedStatement或者PDO的绑定参数,SQL结构在编译时定死,用户输入只作为纯数据传递。比如Java里写 WHERE username = ?,那个问号永远只是字符串值,哪怕传进去 ' OR 1=1 --,数据库也只会把它当成一个奇怪的用户名去匹配。效果立竿见影,但有个坑:很多人只对登录查询做了参数化,却忘了同一请求里可能存在的其他操作——比如“记住我”的token校验,或者密码重置时的邮箱查询。漏一个,等于白防。 光靠参数化还不够。登录接口天生容易被暴力破解,攻击者可以用脚本批量尝试弱密码,甚至把注入payload混在字典里撞运气。所以系统得加一层**行为检测**:同一IP短时间失败超过5次,直接封15分钟;同一用户名尝试次数过多,强制走验证码。这些逻辑不复杂,但能挡掉90%的脚本攻击。有个细节值得注意:返回错误信息时,别区分“用户不存在”和“密码错误”,统一提示“用户名或密码不正确”,否则等于给攻击者递情报。 再往深一层,是数据库权限设计。很多登录系统用的数据库账号居然有DROP权限——这纯属给自己埋雷。登录功能只需要SELECT和UPDATE(改最后登录时间),那就单独建个最小权限账号,连接串里写死。就算注入真发生了,攻击者能干的也极其有限。我见过最离谱的案例,某系统用sa账号连数据库,被注入后直接xp_cmdshell执行系统命令,整台服务器沦陷。权限收窄后,这类灾难基本不可能发生。 输入过滤也不能完全放弃。虽然参数化查询是主力,但有些特殊场景——比如动态拼接表名或排序字段——参数化帮不上忙。这时候就得靠白名单校验:排序字段只允许 asc 或 desc,表名写死在代码里。至于那种“过滤单引号、双引号、关键字”的土办法,别依赖,它只能算减负,不是护身符——因为绕过编码方式太多了,Unicode、十六进制、注释符都能耍花招。 最后说点实际的部署细节。登录请求必须走HTTPS,否则密码在传输中裸奔,注入没防住,反而先被中间人抓包了。还有,后台日志要记录完整的SQL绑定参数,不记录原始SQL——万一出问题,你能回溯是哪个参数值触发了告警,而不用面对一堆拼接后的乱码。密码存储用bcrypt或argon2加盐哈希,别用MD5,这年头GPU跑MD5跟喝水一样快。 这套系统设计下来,登录接口的响应时间会多个几十毫秒,但值得。安全本来就是用微小代价换巨大风险降低。真正上线前,拿sqlmap跑一遍,扫不出注入点,才算基本及格。记住,没有绝对安全的系统,但至少别让自己成为那个连参数化查询都没做的靶子。 |