SQL注入及解决方案
SQL注入及解决方案
SQL注入
如果说你要实现一个登录的业务, 需要username和password来验证登录
当接收到用户输入的username和password时, 我们假设使用字符串拼接的形式注入SQL语句
例如, 我们的SQL语句时这样的 (假设uname时用户输入的用户名, pwd是密码)
String sql = "select * from user
where username = '" +uname "' and password = '" + pwd + "'";
我如果输入用户名: tom'#'
密码随便输入或者不输入, 那么你的SQL语句就变成了这样:
select * from user where username = 'tom'#'' and password = '你输入的密码'
可见 #
号后面的password条件被当成了SQL中的注释, 并未被执行
或者输入用户名为: tom' or '1=1
, 密码不输入或者随便输入, SQL如下:
select * from user from username = 'tom' or '1=1' and password = '你输入的密码'
有了or
自然只要username = 'tom'
成立, 后面的也不会起作用
解决方案
使用prepareStatement
来代替原有的 Statement
这里依然使用了JDBC的 工具类 来获取Connection连接对象和关闭操作
Connection conn = null;
// Statement stat = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
// 注册驱动并连接
conn = JdbcUtil.getConn();
// 获取传输器, 执行sql并返回结果
String sql = "select * from user where username = ? and password = ?";
ps = conn.prepareStatement(sql);
ps.setString(1, user);
ps.setString(2, pwd);
rs = ps.executeQuery();
System.out.println(ps);
// 处理结果 检查是否允许登录
if (rs.next()) { // true -- 有数据
System.out.println("登录成功! ");
} else {
System.out.println("登录失败! 用户名或密码错误");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JdbcUtil.close(conn, ps, rs);
}
注意, 调用setString()
或者 setInt()
, setDouble()
等方法的时候, 第一个参数是从1开始的, 表示第几个问号
这样就解决了!!!
插入数据案例
Connection conn = null;
PreparedStatement ps = null;
try {
conn = JdbcUtil.getConn();
String sql = "insert into user value(null, ?, ?)";
ps = conn.prepareStatement(sql);
ps.setString(1, "孙尚香");
ps.setString(2, "123456");
int rows = ps.executeUpdate();
System.out.println("影响行数: " + rows);
} catch (Exception e) {
e.printStackTrace();
} finally {
JdbcUtil.close(conn, ps, null);
}
查询数据案例
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = JdbcUtil.getConn();
String sql = "select * from user";
ps = conn.prepareStatement(sql);
rs = ps.executeQuery();
while (rs.next()) {
System.out.print(rs.getInt("id") + ", ");
System.out.print(rs.getString("username") + ", ");
System.out.print(rs.getString("password") + "\n");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JdbcUtil.close(conn, ps, rs);
}