SQL注入与防范
2018-06-18 02:53:52来源:未知 阅读 ()
首先给大家看个例子:
1)小编首先在数据库中建立了一张测试表logintable,表内有一条测试信息:
然后写了个测试程序:
package com.java.SqlInject; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class SqlInject { private static String Driver="com.mysql.jdbc.Driver"; //数据库驱动 //连接数据库的URL地址 private static String url="jdbc:mysql://localhost:3306/hellojdbc?useUnicode=true&characterEncoding=UTF-8"; private static String username="root";//数据库连接用户名 private static String password="123456";//数据库连接密码 private static Connection conn=null;//数据库连接对象 private static Statement stat=null;//语句陈述对象 private static ResultSet rs=null;//结果数据集 private static PreparedStatement pst=null;//预编译语句 //使用静态块的方式加载驱动 static { try { //调用Class对象的静态forName()方法加载数据库驱动类 Class.forName(Driver); } catch (ClassNotFoundException e) { e.printStackTrace(); } } //使用单例模式返回数据库连接对象 public static Connection getConnection() throws SQLException{ if(conn==null){ conn=DriverManager.getConnection(url, username, password); return conn; } return conn; } public static void login(String name,String password){ try { conn=getConnection(); stat=conn.createStatement(); //使用动态拼接的方式拼接sql语句 rs=stat.executeQuery("select * from logintable where name='"+name+"' and password='"+password+"'"); if(rs.next()){ System.out.println("用户已注册"); }else System.out.println("无记录"); } catch (SQLException e) { e.printStackTrace(); } } public static void main(String[] args) { login("zhangsan","123456"); } }
输出结果为:
2)然后我们修改main()方法中,login()方法调用时的参数,改为:
public static void main(String[] args) { login("zhangsan","123"); }
执行结果:
3)似乎一切都天经地义,没什么问题。但是这时我们再对login()方法调用的参数做一下修改:
public static void main(String[] args) { //注意:第一个参数两个短杠后面有空格 login("zhangsan';-- ","123"); }
测试执行结果又变成了:
明明用户名和密码都不对,数据库中也没有这条记录,为什么会出现这种情况?
这就是SQL注入带来的漏洞问题。
恶意用户通过伪装请求,来骗过我们的业务程序,达到获取数据库核心数据的目的。
通过上面的例子,我们可以看到我们最后一次改写参数来调用login()方法的时候,java业务程序中接收到的不是我们期望的那个sql语句。
由于分号的存在,使得我们的sql语句拼接后完变成了这样:
select * from logintable where name='zhangsan'; -- 'password='123';
这样就由一条sql语句变成了两条sql语句。在第一条的sql语句中去掉了密码的检索条件,同时注释掉了第二条sql语句。
(两个横线为注释符)
总结一下:
SQL注入就是用户在输入表单或者URL参数中输入SQL命令,到达欺骗应用程序的目的,破坏原有SQL的语义,发送恶意的SQL到后端数据库,导致数据库信息出现泄露的漏洞。
发生这种漏洞的原因是:
我们的sql语句是通过动态拼接组成的,在拼接完成之前,sql语句是不完整的,所以当在拼接时新加入的参数中有sql命令的注入就有可能改变原有的sql语义。
比方像上面的例子中,密码被恶意地屏蔽注释掉了。
解决方法:
传入外部参数时,不使用动态拼接的方式拼接sql语句;使用参数化方式的sql实现方式(格式化,占位符),即使用预编译的statement。
然后传参:
所以上面例子中相关代码应修改为:
conn=getConnection(); //stat=conn.createStatement(); //使用组合的方式拼接sql语句 //rs=stat.executeQuery("select * from logintable where name='"+name+"' and password='"+password+"'"); pst=conn.prepareStatement("select * from logintable where name= ? and password= ?"); pst.setString(1, name); pst.setString(2, password); rs=pst.executeQuery(); if(rs.next()){ System.out.println("用户已注册"); }else System.out.println("无记录");
其他注意事项:
使用严格的数据库管理权限:
1.仅给予Web应用访问数据库的最小权限;
2.避免Drop table等权限。
封装数据库错误:
1.禁止直接将后端数据库异常信息暴露给用户;
2.对后端异常信息进行必要的封装,避免用户直接查看到后端异常。
机密信息禁止明文存储:
1.涉密信息需要加密处理;
2.使用AES_ENCRYPT/AES_DECRYPT加密和解密。
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- JSP+SSH+Mysql+DBCP实现的租车系统 2020-06-09
- JSP+Structs+JDBC+mysql实现的诚欣电子商城 2020-06-08
- Caused by: java.sql.SQLSyntaxErrorException: Unknown col 2020-06-07
- Java高级实战Maven+JSP+SSM+Mysql实现的音乐网站,70%人不会 2020-06-04
- Java Spring注入一个接口的多个实现类在map里如何实现?案 2020-06-04
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash