安全学习-sql注入

sql注入

如果入参传入:id; select 1 –
最终执行的sql会变成:select * from user order by id; select 1 – limit 1,20
–会把后面的limit语句注释掉,导致分页条件失效,返回了所有数据。
攻击者可以通过这个漏洞一次性获取所有数据。动态排序这个功能原本的想法是好的,
但是却有sql注入的风险。值得庆幸的是,这次我们及时发现了问题,并且及时解决了,没有造成什么损失。

sql注入事故还原

首先查看服务器日志,找出数据库连接过多异常。

运维重启,让连接数从100调成500,能即时生效争取时间

setGLOBAL max_connection=500;

查看线程执行情况:show processlist

找出耗时执行的sql,kill -9 杀死那个线程 (待学习

攻击代码使用 statement 预编译而非 preparestatement 预编译(待学习

preparestatement 在sql执行前进行语法分析,编译优化,其中参数位用占位符代替

[‘or’1’=‘1] 作为passwd传入进来,甚至[’;drop table tb_name;]

select * from tb_name =‘任意字符’ and passwd=’’ or ‘1’=‘1’; 在 statement 下,会直接注入成功

select * from t_user where password='ddd\' or \'1\'=\'1'; 

在 preparestatement 下无效,因为执行语句前给参数赋值,避免因普通的拼接sql字符串语句所带来的安全问题,
而且准备sql和执行sql是在两个语句里面完成的,也提高了语句执行的效率 比如单引号会给你加一个转义,加个斜杠。

比如:name是必填的,如果注入了:%,最后执行的sql会变成这样的:

select * from user where name like '%%%';

这种情况预编译机制是正常通过的,但sql的执行结果不会返回包含%的用户,而是返回了所有用户。name字段必填变得没啥用了,攻击者同样可以获取用户表所有数据。
为什么会出现这个问题呢?%在mysql中是关键字,如果使用like ‘%%%’,该like条件会失效。如何解决呢?需要对%进行转义:%。转义后的sql变成:select * from user where name like ‘%%%’;只会返回包含%的用户。

注意点:
和Statement不不同的是,使用PreparedStatement时,是无法直接使用System.out.println(SQL)输出当前执行的SQL语句的,此时输出的结果会是 slect * from course where courseno=? 仍然是定义的string类型的带?的sql语句

使用PreparedStatement预编译的java代码:

import java.sql.*;

public class PreparedStmt {
    public static void main(String[] args) {
        String driverName = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
        String dbUrl = "jdbc:sqlserver://localhost:1433;DatabaseName=SC";
        String userName = "test";
        String userPwd = "test";
        Connection conn = null;
        PreparedStatement pStmt = null;
        try {
            Class.forName(driverName);
            conn = DriverManager.getConnection(dbUrl, userName, userPwd);
            String sql = "insert into course values(?,?,?,null)";
            pStmt = conn.prepareStatement(sql);//注意是prepareStatement()方法
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        try {
            //设置参数的值
            pStmt.setString(1, "1009");
            pStmt.setString(2, "JDBC教程");
            pStmt.setDouble(3, 3.5);
            pStmt.execute();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            if(pStmt != null) pStmt.close();
            if(conn != null) conn.close();
        } catch(SQLException e) {
            e.printStackTrace();
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值