您现在的位置是:百科 >>正文
sql注入漏洞怎么修复
百科4489人已围观
简介```html 去年有个做电商的朋友找我,说后台订单数据被人翻了个底朝天。我让他把数据库日志导出来一看,攻击者用的就是最基础的 ' OR '1'='1。他那个查询接口直接把用户输入的订单号拼进了SQL ...
去年有个做电商的入漏朋友找我,说后台订单数据被人翻了个底朝天。洞修我让他把数据库日志导出来一看,入漏攻击者用的洞修就是最基础的 ' OR '1'='1。他那个查询接口直接把用户输入的入漏订单号拼进了SQL语句里,连过滤都没做。洞修这种事每天都在发生,入漏修复方法其实不复杂,洞修但很多人就是入漏懒得改。
先说最根本的洞修一条:别拼字符串。我见过太多代码长这样——"SELECT * FROM users WHERE name = '" + userName + "'"。入漏这种写法等于把大门钥匙插在锁上还贴了张纸条说“欢迎光临”。洞修正确的入漏做法是使用参数化查询,也就是洞修预编译语句。拿Java举例,入漏用 PreparedStatement:
String sql = "SELECT * FROM users WHERE name = ?"; PreparedStatement ps = connection.prepareStatement(sql); ps.setString(1, userName); ResultSet rs = ps.executeQuery(); 这样数据库会把 userName 当成纯数据,就算里面塞了 ' OR 1=1 -- 也只会被当作一个普通的字符串去匹配,不会改变SQL结构。PHP里用PDO的 prepare 加 execute,Python里用 cursor.execute("... %s", (user_input,)),原理都一样。参数化查询是防注入的底线,没有之一。
但光靠参数化还不够。有些场景没法用参数化,比如动态表名、动态排序字段。这时候就得用白名单校验。比如用户传过来一个 sort=price,你不能直接拼 ORDER BY price,而是先检查这个值在不在允许的列表里:["price", "create_time", "id"]。不在就拒绝或者用默认值。表名同理,把可选的表名硬编码成一个数组,用户传什么就查什么,别让数据库去猜。
还有一个容易被忽略的点:数据库账号权限。很多应用连数据库用的是 root 或者 sa,这等于把整个数据库的钥匙都交给了前端。正确的做法是给每个应用单独建账号,只授予它需要的权限。比如一个只读的查询接口,账号就只给 SELECT,别给 DROP、UPDATE、DELETE。就算注入漏洞真的被利用了,攻击者也只能读到有限的数据,没法删库跑路。我见过一个案例,攻击者通过注入拿到了 mysql.user 表的哈希,就是因为那个账号有 SELECT 全库的权限。
输入验证要不要做?要做,但别指望它。很多人觉得把单引号过滤掉就安全了,结果攻击者用 %27 或者宽字节编码绕过去。过滤特殊字符只能挡住最笨的脚本小子,挡不住稍微懂点编码的人。所以输入验证是辅助手段,不是主要防线。真正该做的是在参数化查询的基础上,对输入做类型和格式的检查。比如订单号只允许数字,那就用正则 ^\d+$ 卡死,不符合的直接返回错误。
最后说一个实际项目里常见的坑:ORM框架。很多人以为用了Hibernate、MyBatis就万事大吉了,但如果你在MyBatis里写 ${ } 而不是 #{ },照样会注入。${ } 是直接拼接,#{ } 才是参数化。我见过一个团队用MyBatis,所有查询都写 ${ },理由是“方便调试”。结果上线三个月就被拖了库。所以用ORM也要看具体写法,别把安全责任全推给框架。
修复SQL注入没有银弹,就是老老实实把参数化查询用对,把权限收窄,把白名单加上。这些事做起来不酷,但能让你晚上睡得着觉。我那个电商朋友后来把整个DAO层重写了一遍,花了三天,之后半年再没出过事。三天换半年安宁,这笔账怎么算都值。
```Tags:
下一篇:在B2B网站怎么发帖
相关文章
c xss漏洞解决
百科C XSS漏洞解决 凌晨两点,监控弹出一条告警。攻击载荷是`alert(document.cookie)`,但奇怪的是,它被原样存进了数据库,又原样吐在了页面上——连HTML实体都没转。我盯着那条日志 ...
【百科】
阅读更多知乎网站打不开
百科2024年3月14日晚上十一点半,我正翻着知乎上一篇关于机械键盘轴体的长文,刚看到关键段落,页面突然白了。刷新,转圈,再刷新,还是白。切到App,一样打不开,只弹出一行冷冰冰的“网络连接失败”。我第一 ...
【百科】
阅读更多网站登录入口
百科上周帮邻居王叔找回他那个用了七八年的邮箱密码,折腾了四十分钟。问题出在哪?他记不清自己当初注册时填的是手机号还是那个已经停用的固话号码。登录入口就在眼前,输入框也认识,可验证环节把他卡死了。这事让我意 ...
【百科】
阅读更多