update employer_salary set salary = 1000000 where employer_id = v_employer_id;仔细看看这个语句, v_employer_name 是个变量, 比如说来自于web表单。
update employer_salary set salary = 1000000 where employer_id = 38 OR TRUE;看到了吧, 这条SQL 现在变成了把所有人的工资都变成1000000, 爽吧。还有更可怕的,假如 v_employer_id 的值为: 38;delete from employer_salary;
update employer_salary set salary = 1000000 where employer_id = 38; delete from employer_salary;结果是所有的记录都被干掉了, 厉害了把!
我是觉得很厉害了。 这么厉害的攻击有什么办法应对呢, 三种方法,都不轻松。
这个不多说了, 如果输入要求的是integer 那么在接受到输入后检查下是不是integer。 注入此类,越详细越好。
update employer_salary set salary = 1000000 where employer_id = ?看到没,原本使用变量的地方使用了“?” 作为占位符。 但是这样怎么就有用了呢,我难道不照样输入“38 OR TRUE” 这样的参数来替换占位符吗? 还真不行,原理是这样的,如果是使用占位符以供参数替换的SQL语句RDBMS会预先解析这个SQL,并认为SQL 的结构已经固定了,可变的只是参数。 所以当我们输入“38 OR TRUE” 这样的参数,如果employer_id 是个int类型的列, 会得到一个错误信息。 简单说就是只是将参数的内容当做是参数而不会将参数的部门内容误认为是SQL的结构语句了,因为SQL的结构语句已经预解析过了,固定了。不知道说明白了没,多读几遍应该还是能明白的。
这个方式的缺点在于SQL语句是不允许将SQL结构上的部分当错参数传入的, 如表名, 列名 , 排序顺序:ASC, DESC。
down---ASC up---DESC如果用户输入的不是"down"或者"up"我会报错,或者弄一个默认值如“ASC”, 其实说白了也是一种检查,但是确实是将用户和真正的代码隔离了。