首先给大家看个例子:

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加密和解密。

SQL注入与防范的更多相关文章

  1. 常见sql注入的防范总结

    在平时的开发过程中,我们可能很少会刻意的去为项目做一个sql注入的防范,这是因为你可能因为使用了某些框架,而无意间已经有了对应sql注入的一些防范操作(比如mybatis使用#{XX}传参,属于预编译 ...

  2. Java开发工程师(Web方向) - 03.数据库开发 - 第3章.SQL注入与防范

    第3章--SQL注入与防范 SQL注入与防范 经常遇到的问题:数据安全问题,尤其是sql注入导致的数据库的安全漏洞 国内著名漏洞曝光平台:WooYun.org 数据库泄露的风险:用户信息.交易信息的泄 ...

  3. PHP SQL注入的防范

    说到网站安全就不得不提到SQL注入(SQL Injection),如果你用过ASP,对SQL注入一定有比较深的理解,PHP的安全性相对较高,这是因为MYSQL4以下的版本不支持子语句,而且当php.i ...

  4. php web开发安全之sql注入和防范:(一)简单的select语句注入和防范

    sql注入主要是指通过在get.post请求参数中构造sql语句,以修改程序运行时所执行的sql语句,从而实现获取.修改信息甚至是删除数据的目的,sql被注入的原因主要是代码编写的有问题(有漏洞),只 ...

  5. PHP 关于SQL注入的防范措施。

    最近在使用框架的时候还是有点不安,不知道框架的设计者有没有考虑到SQL-Injection的问题,我在顶层需不需要做一些必要的过滤等等,由 此我特意的去StackOverflow看了下,真是获益良多, ...

  6. sql 注入的防范(一)

    为了保证程序的健壮性,我们必须对用户输入的数据做有效性验证,防止用户恶意提交数据. 关于防止 sql 注入 我主要从三个方面入手: 1.确认为正整数的,强制转化为int,$id  =$_GET('id ...

  7. Mybatlis SQL 注入与防范

    SQL注射原理 所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令.具体来说,它是利用现有应用程序,将(恶意)的SQL命令 ...

  8. MySQL 及 SQL 注入与防范方法

    所谓SQL注入,就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令. 我们永远不要信任用户的输入,我们必须认定用户输入的数据都是不安全的, ...

  9. MySQL防范SQL注入风险

    MySQL防范SQL注入风险 0.导读 在MySQL里,如何识别并且避免发生SQL注入风险 1.关于SQL注入 互联网很危险,信息及数据安全很重要,SQL注入是最常见的入侵手段之一,其技术门槛低.成本 ...

随机推荐

  1. pycharm删除project

    1 在pycharm里面选择关闭project 2 返回到这个页面,然后点×让project不在project列表显示(最好记住project的位置) 3 到源文件夹删除这个project文件夹 大功 ...

  2. Ubuntu下安装和使用开源的tts软件Flite

    Flite是什么? Flite是一个小型.快速的TTS系统,是festival的C版本,可用于嵌入式系统,支持WinCE.Palm OS 等. 下载方法: wget http://www.festvo ...

  3. Python档案袋( Sys 与 Import 模块)

    Sys模块: 获取Python有关的环境变量: import sys #得到Python的一些相关路径,环境变量 #其中site-packages目录存放的是一些第三方库 #其中lib目录存放的是一些 ...

  4. [原创]K8 cping 3.0大型内网渗透扫描工具

    [原创]K8 Cscan 大型内网渗透自定义扫描器 https://www.cnblogs.com/k8gege/p/10519321.html Cscan简介:何为自定义扫描器?其实也是插件化,但C ...

  5. [原创]K8Cscan插件之Windows密码爆破

    [原创]K8 Cscan 大型内网渗透自定义扫描器 https://www.cnblogs.com/k8gege/p/10519321.html Cscan简介:何为自定义扫描器?其实也是插件化,但C ...

  6. 【hadoop】1、MapReduce进行日志分析,并排序统计结果

    1.网上很多关于搭建Hadoop集群的知识,这里不多做叙述,并且本机运行Hadoop程序是不需要hdfs集群的,我们本机运行只做个demo样式,当真的需要运行大数据的时候,才需要真正的集群 2.还有就 ...

  7. mysql 开发进阶篇系列 1 SQL优化(show status命令)

    一.概述 随着上线后,数据越来越多,很多sql语句开始显露出性能问题,本章介绍在mysql中优化sql语句的方法.  1.  通过show status 命令了解各种sql的执行频率 通过show [ ...

  8. Vagrant挂载目录失败mount: unknown filesystem type ‘vboxsf’

    一.背景 ​ 最近在玩Mac OS下的虚拟机,然后有朋友推荐了我Vagrant,但是在设置完跟宿主机共享目录然后启动虚拟机的时候,出现了vagrant mount: unknown filesyste ...

  9. iOS逆向开发(3):锁定APP的目标类与函数 | reveal | lldb | debugserver | 远程调试

    之前介绍了怎么获取APP的所有类的结构信息,这个有什么用呢?用处大了,比如以这一步为基础,下一步通过注入来做更多研究工作. 注入的最小单位是函数,实际上,编译执行的程序在编译后,类就不复存在了,留下来 ...

  10. [转]phpredis中文手册

    本文是参考<redis中文手册>,将示例代码用php来实现,注意php-redis与redis_cli的区别(主要是返回值类型和参数用法). 目录(使用CTRL+F快速查找命令): Key ...