sql注入漏洞解决方法
SQL注入漏洞的入漏根治办法只有一个:把数据和代码彻底分开。这不是洞解什么高深理论,而是决方所有防御手段的底层逻辑。你写SQL语句时,入漏用户输入就是洞解代码的一部分;你用了参数化查询,用户输入就只是决方数据。就这么简单。入漏 拿个真实案例说事。洞解去年我审计某电商平台的决方后台,登录框直接拼字符串: 最直接的修复方案是参数化查询(PreparedStatement)。Java里这样写: 但参数化不是万能的。表名、列名这种结构标识符没法参数化,因为数据库需要先解析结构再执行。这时候就得搞白名单校验。比如你要按用户选择的字段排序,那就写死一个映射表: 还有个容易被忽略的口子——存储过程。我见过不少系统,代码里参数化做得好好的,结果存储过程内部又拿参数拼了动态SQL。这等于前门锁死了,后门敞开着。存储过程里的动态语句同样必须参数化,或者用EXECUTE ... USING这类绑定变量的语法。别觉得数据库层就安全,注入只认最终执行的SQL长什么样。 再补一层纵深防御。数据库账号权限要按最小化原则划分。应用连接账号只给SELECT、INSERT、UPDATE、DELETE权限,别给DROP、CREATE这类高危权限。万一注入真的发生了,攻击者能做的事也极其有限。有个真实教训:某系统被注入后,攻击者发现连接账号有FILE权限,直接 最后说点实际的排查技巧。如果你在维护老代码,先全局搜字符串拼接的SQL,搜 别迷信WAF(Web应用防火墙)。WAF能拦截大部分自动化攻击,但绕过的姿势每年都在翻新——编码绕过、分块传输、JSON嵌套,花样百出。WAF是减速带,不是防火墙。真正靠得住的还是代码层面把参数化做扎实。你见过哪个认真写了参数化查询的系统被SQL注入搞垮的?反正我没见过。SELECT * FROM admin WHERE username='$user' AND password='$pass'。入漏攻击者在用户名框输入' OR '1'='1,洞解密码随便填,决方直接进后台。入漏这种漏洞现在依然大量存在于中小型系统里,洞解尤其是决方一些外包开发的内部工具,堪称重灾区。PreparedStatement ps = conn.prepareStatement("SELECT * FROM admin WHERE username=? AND password=?");然后ps.setString(1, user);。数据库驱动会把参数当纯文本处理,单引号、注释符全变成普通字符。PHP的PDO、Python的sqlite3、Go的database/sql都有对应实现。只要你用了这个,注入基本就堵死了八成。switch($field) { case 'name': $orderBy = 'name'; break; case 'id': $orderBy = 'id'; default: $orderBy = 'id'; }。别偷懒用黑名单,黑名单永远堵不完,白名单直接让你连注入的机会都没有。SELECT LOAD_FILE('/etc/passwd')把服务器密码文件读走了。权限收紧了,这种连锁攻击就打不穿。$sql = "SELECT后面跟了$_GET或$_POST的写法。把这类代码全列出来,一条条改成参数化。改完用sqlmap跑一遍测试,它能模拟几十种注入手法,比手动测试全面得多。但记住,sqlmap跑出来没漏洞不代表真没漏洞,它只是覆盖了常见攻击模式,业务逻辑里的特殊注入点还得靠人工审。
-
上一篇
-
下一篇
- 随机阅读
- 搜索
-
- 友情链接
-