package cj;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
public class SQLInject {
public static void main(String[] args) throws Exception{
read("' or 1 or '");
}
public static void read(String name) throws Exception {
Connection con = null;
ResultSet rs = null;
Statement st = null;
try {
con = JdbcUtil.getConnection();
st = con.createStatement();
String sql = "select id, name from test where name='"+name+"'";
System.out.println("sql:"+sql);
rs = st.executeQuery(sql);
while (rs.next()) {
System.out.print(rs.getObject("name") );
System.out.println();
}
} finally {
JdbcUtil.free(rs, st, con);
}
}
}
这段代码会照成SQL注入,查询出所有的记录。
我们可以看到打印的结果:
sql:select id, name from test where name='' or 1 or ''
这条sql语句怎么样都会执行。
SQL注入攻击是利用是指利用设计上的漏洞在目标服务器上运行Sql语句以及 进行其他方式的攻击,动态生成Sql语句时没有对用户输入的数据进行验证是Sql注入攻击得逞的主要原因。
对于JDBC而言,SQL注入攻击只对Statement有效,对PreparedStatement 是无效的这是因为PreparedStatement不允许在不同的插入时改变查询的逻辑结构。
如验证用户是否存在的SQL语句为 :
select count(*) from usertable where name='用 户 名 ' and pswd='密 码 '
如果在用户名字段中输 入 ' or '1'='1' or '1'='1或是在密码字段中输入 1' or '1'='1将绕过验证,但这种手段只对只对 Statement有效,对PreparedStatement无效。
PreparedStatement 相 对 Statement有以下 优 点:
1.防注入攻 击
2.多次运行速度快
3.防止数据库缓冲区溢出
4.代码的可读性可维护性好
这四点使得 PreparedStatement 成为访问数据库的语句对象的首选,缺点是灵活性不够好,有些场合还是必须使用Statement。