首先给大家看个例子:

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. 使用ajax的post方式下载excel

    项目需求,前端发起ajax请求,后端生成excel并下载,同时需要在header头中,带上token验证信息,参考了很多文章,最终实现如下: PHP后端使用base64: $filename = 'd ...

  2. 利用node 剥取其他网站的文档数据结构 ---

    1.如何利用nodejs获取其他网站的文档结构呢 以下是代码演示------! //首先需要引入一些核心模块 var http = require('http'); var fs = require( ...

  3. Event Loop浅谈

    event loop 即事件循环.最初了解到js的event loop机制是通过自己对js中异步.同步的疑惑.今天聊一聊自己的理解,希望和大家一起学习. 首先,让我们看一个经典的setTimeOut的 ...

  4. RabbitMQ配置

    RabbitMQ Configuration RabbitMQ提供多种配置方式:配置文件.环境变量.运行时参数等等. 默认配置文件的位置在/etc/rabbitmq/ Config File Loca ...

  5. Go语言下的线程模型

    阅读Go并发编程对go语言线程模型的笔记,解释的非常到,好记性不如烂笔头,忘记的时候回来翻一番,在此做下笔记. Go语言的线程实现模型,又3个必知的核心元素,他们支撑起了这个线程实现模型的主要框架: ...

  6. [NewLife.XCode]数据模型文件

    NewLife.XCode是一个有10多年历史的开源数据中间件,由新生命团队(2002~2019)开发完成并维护至今,以下简称XCode. 整个系列教程会大量结合示例代码和运行日志来进行深入分析,蕴含 ...

  7. SaltStack安装配置详解

    一.简介 Saltstack 比 Puppet 出来晚几年,是基于Python 开发的,也是基于 C/S 架构,服务端 master 和客户端 minions :Saltstack 和 Puppet ...

  8. 【Vue.js】vue引入组件报错:该组件未注册?

    [Vue warn]: Unknown custom element: <QuestionnaireOption> - did you register the component cor ...

  9. hadoop框架详解

    Hadoop框架详解 Hadoop项目主要包括以下四个模块 ◆ Hadoop Common: 为其他Hadoop模块提供基础设施 ◆ Hadoop HDFS: 一个高可靠.高吞吐量的分布式文件系统 ◆ ...

  10. Python之使用Pandas库实现MySQL数据库的读写

      本次分享将介绍如何在Python中使用Pandas库实现MySQL数据库的读写.首先我们需要了解点ORM方面的知识. ORM技术   对象关系映射技术,即ORM(Object-Relational ...