English
 电子信箱
 加入收藏

  威盾防火墙 >> 新闻中心 >> 威盾新闻 >> 怎么防止SQL语句注入

 

怎么防止SQL语句注入

威盾防火墙 2015-01-12

 
如何防止SQL语句注入
版权:JavaIT学习室_在线Java学习论坛


为了给大家将SQL注入的原理,需要大家具备如下的知识:
(1)掌握基本Swing组件的开发
(2)掌握基本JDBC的开发

此课题的视频我们也为大家做好了。在文章的底部,大家可以看看。详细的SQL注入原理可以参考我们论坛的文章: tid=53&extra=page%3D1

1、什么样的SQL语句是SQL注入语句

大家先看如下没有加入SQL注入设计的SQL语句

  select * from student where sno = 's001'



根据上面的SQL语句,我们只需要改变一下就能够完成SQL语句的注入

  select * from student where sno = 's001' or '1'='1'



2、在编写JDBC程序时候,如何利用上面SQL语句注入,完成输入不存在的学号也可以登录成功???

防止SQL注入的方法:利用JDBC的PreparedStatement来完成

3、代码实现
(1)编写界面窗口

  package test; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.sql.SQLException; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JTextField; /** * * @author JavaIT学习 * */ public class TestFrame extends JFrame { private JLabel sno; //学号 private JTextField sno_t; //学号的文本框 private JButton b; //登录按钮 public TestFrame() { init(); //创建窗口的相关属性,例如:设置窗口的大小 } private void init() { this.setTitle("防止SQL语句注入危险的程序"); //设置窗口标题 this.setSize(300, 200); //设置窗口的高和宽 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //设置窗口的关闭方式 this.setResizable(false); //设置窗口不可最大化,或是设置窗口不可调整大小 //在放置基本组件的时候一定要注意窗口的布局方式 this.setLayout(new FlowLayout()); //设置窗口是流式布局 sno = new JLabel("学号:"); sno_t = new JTextField(8); b = new JButton("登录"); this.getContentPane().add(sno); this.getContentPane().add(sno_t); this.getContentPane().add(b); b.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub String s = sno_t.getText(); //返回窗口中输入的学号信息 try { int i = DBUtil.getInstance().check_2(s); if (i > 0) { JOptionPane.showMessageDialog(null, "登录成功"); } else { JOptionPane.showMessageDialog(null, "登录不成功"); } } catch (SQLException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } //将学号传入到数据库中进行匹配 } //为按钮添加点击事情 }); this.setVisible(true); //设置窗口可以显示 } /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub new TestFrame(); } }



(2)数据库代码

  package test; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; /** * 数据库连接的类,利用JDBC技术完成 * @author JavaIT学习室 * */ public class DBUtil { private static final String USER_NAME = "sa"; private static final String PASSWORD = "123456"; private static final String driverclass = "com.microsoft.sqlserver.jdbc.SQLServerDriver"; private static final String url = "jdbc:sqlserver://localhost:1433;DatabaseName=stu"; private static DBUtil db = null; //它是一个单例的对象 private DBUtil() { try { Class.forName(driverclass); //加载驱动,必须将数据库的驱动包导入到工程中,不然会报错。sqljdbc.jar } catch (Exception e) { e.printStackTrace(); } } /** * 返回主类DBConnectionUtil的对象,因为构造方法被定义为private,所以在初始化主类对象的时候只能用此方法实现 * @return */ public static DBUtil getInstance() { if (db == null) { db = new DBUtil(); } return db; } /** * 获取数据库连接Connection的对象 * @return */ public Connection getConnection() { Connection conn = null; try { conn = DriverManager.getConnection(url, USER_NAME, PASSWORD); } catch (SQLException e) { e.printStackTrace(); } return conn; } /** * 关闭数据库连接对象的方法 * @param conn */ public void close(Connection conn) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } /** * 没有防止SQL注入的代码 * @return * @throws SQLException */ public int check(String sno) throws SQLException { String sql = "select count(sno) from student where sno = '"+sno+"'"; System.out.println(sql); Statement stmt = DBUtil.getInstance().getConnection().createStatement(); ResultSet rs = stmt.executeQuery(sql); if (rs != null && rs.next()) { //对执行的SQL语句的结果集进行遍历 if (rs.getInt(1) > 0) { return 1; //确认该学生在数据库中存在 } } return 0; } /** * PreparedStatement可以防止SQL注意的接口 * @param sno * @return * @throws SQLException */ public int check_2(String sno) throws SQLException { String sql = "select count(sno) from student where sno = "; PreparedStatement ps = DBUtil.getInstance().getConnection().prepareStatement(sql); ps.setString(1, sno); ResultSet rs = ps.executeQuery(); if (rs != null && rs.next()) { //对执行的SQL语句的结果集进行遍历 if (rs.getInt(1) > 0) { return 1; //确认该学生在数据库中存在 } } return 0; } }


相关内容: 最新内容:
预防SQL注入攻击之我见[2015-01-12]
注意那些容易被忽略的SQL注入技巧[2015-01-12]
深入研究MySQL结果字符串[2015-01-12]
MySQL系统变量应用探究[2015-01-12]
十大最值得注意的MySQL变量[2015-01-12]
详解MySQL注入利用的变量[2015-01-12]
预防SQL注入攻击之我见[2015-01-12]
注意那些容易被忽略的SQL注入技巧[2015-01-12]
深入研究MySQL结果字符串[2015-01-12]
MySQL系统变量应用探究[2015-01-12]
十大最值得注意的MySQL变量[2015-01-12]
详解MySQL注入利用的变量[2015-01-12]