`
stanxl
  • 浏览: 4027 次
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

Statement的注入问题浅谈

 
阅读更多

前天有人问我说,我知道用Statement可能会产生注入问题,但是啥是注入问题?其实我知道他了解过,但是现在忘记了…..
谁说不是呢,我也是有些遗忘了,我就知道如果在sql语句后直接拼接条件,是可能产生注入问题 ,当然了如果你设置的条件是你想要,肯定不会出现注入问题的
话不多说,既然说到了注入问题,就去看看这个传说中的“注入问题”….
先让问题暴露出来,看下面的代码:
现在是这样,假设现在我的库里的数据是这样的:
1 黄药师 1900-1-1 400
2 黄晓明 1920-1-1 800

public class StatementTest{
    public static void create(){
        Connection con = null;
        Statement st = null;
        try{
            con = //加载驱动,获得连接;
            st = con.createStatement();
            String sql = "insert into users(name, birthday, money) values('周伯通', '1900-1-1', 300)";
            st.execute(sql);
            System.out.println("存入成功!");
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            //释放资源,调用close()
        }
        public static void read(String uid){
            Connection con = null;
            Statement st = null;
            ResultSet rs = null;
            try{
                con = //加载驱动,获得连接;
                st = con.createStatement();
                String sql = "select * from users where uid =" + uid;
                st.execute(sql);
                rs = st.getResultSet();
                while(rs.next()){
                    System.out.print(rs.getObject(1) + "\t");
                    System.out.print(rs.getObject(2) + "\t");
                    System.out.print(rs.getObject(3) + "\t");
                    System.out.print(rs.getObject(4) + "\t");
                }
            }catch(Exception e){
                e.printStackTrace();
            }finally{
                //释放资源,调用close()
            }
        }
    }
    public static void main(String[] args){
        create();
        read("1 or 1 < 2");
    }   
}

这个时候,查询到的结果是全部:

1 黄药师 1900-1-1 400
2 黄晓明 1920-1-1 800
3 周伯通 1900-1-1 300

可以看出,传入的参数中,包含了sql代码! 这个代码会让条件失效!
解决方法:以后再也不要使用Statement了。取而代之使用java.sql.PreparedStatement!

public static void read(String uid){
            Connection con = null;
            PreparedStatement ps = null;
            ResultSet rs = null;
            try{
                con = //加载驱动,获得连接;
                // 通过数据库连接,获得预处理语句对象!
                // 预处理语句对象和Statement对象的作用很像,但是用法有区别.
                // 预处理语句中可以出现占位符,用?代表一个占位
                // 在执行sql语句之前,必须把所有的占位符替换成真正的值!

                String sql = "select * from users where uid = ?";
                ps = con.prepareStatement(sql);
                ps.setString(1,Integer.parseInt("uid"));
                ps.executeQuery();
                rs = ps.getResultSet();
                while(rs.next()){
                    System.out.print(rs.getObject(1) + "\t");
                    System.out.print(rs.getObject(2) + "\t");
                    System.out.print(rs.getObject(3) + "\t");
                    System.out.print(rs.getObject(4) + "\t");
                }
            }catch(Exception e){
                e.printStackTrace();
            }finally{
                //释放资源,调用close()
            }
        }

再在main方法里调用 read(“1 or 1 < 2”)时,就会报错了,通过PrepareStatement预处理语句,将不合理的条件过滤掉,解决了注入问题。
所以以后就把createStatement舍弃吧,也尽量不要在sql语句后面直接拼接条件。

<script type="text/javascript"> $(function () { $('pre.prettyprint code').each(function () { var lines = $(this).text().split('\n').length; var $numbering = $('<ul/>').addClass('pre-numbering').hide(); $(this).addClass('has-numbering').parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($('<li/>').text(i)); }; $numbering.fadeIn(1700); }); }); </script>

版权声明:本文为博主原创文章,未经博主允许不得转载。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics