SQL注入漏洞 详解

漏洞影响
攻击者利用该漏洞可能导致

1.网页被篡改

2.数据被篡改

3. 核心数据被窃取

4. 数据库所在服务器被攻击变成傀儡主机

解决方法:

1.      过滤用户输入的内容,检查用户输入的内容中是否有非法内容。如,|(竖线符号)、 & (& 符号)、;(分号)、$(美元符号)、%(百分比符号)、@(at 符号)、\‘(单引号)、"(引号)、\\\‘(反斜杠转义单引号)、\\"(反斜杠转义引号)、<>(尖括号)、()(括号)、+(加号)、 CR(回车符,ASCII 0x0d)、 LF(换行,ASCII 0x0a)、,(逗号)、\\(反斜杠)、)(结束括号)等符号。

2.      过滤危险的SQL语句关键字,如select,from,update,insert,delete等。

3.      利用存储过程,将数据访问抽象化,让用户不直接访问表或视图。当使用存储过程时,请利用 ADO 命令对象来实施它们,以强化变量类型。

4.      使用防注入系统。

5.      修复示例

Asp.Net

以下是保护 Web 应用程序免遭 SQL 注入攻击的两种可行方法:

5.1  使用存储过程,不用动态构建的 SQL 查询字符串。将参数传递给 SQL Server 存储过程的方式,可防止使用单引号和连字符。

以下是如何在ASP.NET 中使用存储过程的简单示例:

\‘ Visual Basic example

Dim DS As DataSet

Dim MyConnection AsSqlConnection

Dim MyCommand AsSqlDataAdapter

Dim SelectCommand As String= "select * from users where username = @username"

...

MyCommand.SelectCommand.Parameters.Add(NewSqlParameter("@username", SqlDbType.NVarChar, 20))

MyCommand.SelectCommand.Parameters("@username").Value =UserNameField.Value

// C# example

String selectCmd ="select * from Authors where state = @username";

SqlConnection myConnection =new SqlConnection("server=...");

SqlDataAdapter myCommand =new SqlDataAdapter(selectCmd, myConnection);

myCommand.SelectCommand.Parameters.Add(newSqlParameter("@username", SqlDbType.NVarChar, 20));

myCommand.SelectCommand.Parameters["@username"].Value= UserNameField.Value;

5.2  您可以使用验证控件,将输入验证添加到“Web 表单”页面。验证控件提供适用于所有常见类型的标准验证的易用机制,例如,测试验证日期是否有效,或验证值是否在范围内,以及进行自定义编写验证的方法。此外,验证控件还可以使您能够完整定义向用户显示错误信息的方式。验证控件可搭配“Web 表单”页面的类文件中处理的任何控件使用,其中包括 HTML 和 Web 服务器控件。为了确保用户输入仅包含有效值,您可以使用以下其中一种验证控件:

5.2.1 “RangeValidator”:检查用户条目(值)是否在指定的上下界限之间。 您可以检查配对数字、字母字符和日期内的范围。

5.2.2 “RegularExpressionValidator”:检查条目是否与正则表达式定义的模式相匹配。 此类型的验证使您能够检查可预见的字符序列,如电子邮件地址、电话号码、邮政编码等中的字符序列。最后:验证控件不会阻止用户输入或更改页面处理流程;它们只会设置错误状态,并产生错误消息。程序员的职责是,在执行进一步的应用程序特定操作前,测试代码中控件的状态。有两种方法可检查用户输入的有效性: 1. 测试常规错误状态:在您的代码中,测试页面的 IsValid 属性。该属性会将页面上所有验证控件的 IsValid 属性值汇总(使用逻辑 AND)。如果将其中一个验证控件设置为无效,那么页面属性将会返回 false。 2. 测试个别控件的错误状态:在页面的“验证器”集合中循环,该集合包含对所有验证控件的引用。然后,您就可以检查每个验证控件的 IsValid 属性。

PHP

5.3过滤用户输入

将任何数据传给 SQL 查询之前,应始终先使用筛选技术来适当过滤。 这无论如何强调都不为过。 过滤用户输入可让许多注入缺陷在到达数据库之前便得到更正。

5.4将用户输入加引号

不论任何数据类型,只要数据库允许,便用单引号括住所有用户数据。

5.5 转义数据值

如果使用 MySQL4.3.0 或更新的版本,您应该用 mysql_real_escape_string() 来转义所有字符串。 如果使用旧版的 MySQL,便应该使用mysql_escape_string() 函数。如果未使用 MySQL,您可以选择使用特定数据库的特定换码功能。如果不知道换码功能,您可以选择使用较一般的换码功能,例如,addslashes()。

如果使用 PEAR DB 数据库抽象层,您可以使用DB::quote() 方法或使用 ? 之类的查询占位符,它会自动转义替换占位符的值。参考资料http://ca3.php.net/mysql_real_escape_string

http://ca.php.net/mysql_escape_string

http://ca.php.net/addslasheshttp://pear.php.net/package-info.php?package=DB

5.6输入数据验证:虽然为方便用户而在客户端层上提供数据验证,但仍必须始终在服务器层上执行数据验证。客户端验证本身就不安全,因为这些验证可轻易绕过,例如,通过禁用 Javascript。一个好的设计通常需要 Web 应用程序框架,以提供服务器端实用程序例程,从而验证以下内容:必需字段,字段数据类型(缺省情况下,所有 HTTP 请求参数都是“字符串”),字段长度,字段范围,字段选项,字段模式, cookie 值,HTTP 响应等,以下部分描述一些检查的示例。

// PHP example to validaterequired fields

functionvalidateRequired($input) {

...

$pass = false;

if(strlen(trim($input))>0){

$pass = true;

}

return $pass;

...

}

...

if(validateRequired($fieldName)) {

// fieldName is valid,continue processing request

...

}

J2EE

** 预编译语句:

以下是保护应用程序免遭 SQL 注入(即恶意篡改 SQL 参数)的三种可行方法。使用以下方法,而非动态构建 SQL 语句:

5.7 PreparedStatement,通过预编译并且存储在PreparedStatement 对象池中。 PreparedStatement 定义 setter 方法,以注册与受支持的 JDBC SQL 数据类型兼容的输入参数。例如,setString 应该用于 VARCHAR 或 LONGVARCHAR 类型的输入参数(请参阅 Java API,以获取进一步的详细信息)。通过这种方法来设置输入参数,可防止攻击者通过注入错误字符(如单引号)来操纵 SQL 语句。

如何在 J2EE 中使用 PreparedStatement 的示例:

//J2EE PreparedStatemenet Example

//Get a connection to the database

Connection myConnection;

if(isDataSourceEnabled()) {

// using the DataSource to get a managed connection

Context ctx = new InitialContext();

myConnection =((DataSource)ctx.lookup(datasourceName)).getConnection(dbUserName, dbPassword);

}else {

try {

// using the DriverManager to get a JDBC connection

Class.forName(jdbcDriverClassPath);

myConnection = DriverManager.getConnection(jdbcURL, dbUserName,dbPassword);

} catch (ClassNotFoundException e) {

...

}

}

...

try{

PreparedStatement myStatement =myConnection.prepareStatement("select * from users where username =?");

myStatement.setString(1, userNameField);

ResultSet rs = myStatement.executeQuery();

...

rs.close();

}catch (SQLException sqlException) {

...

}finally {

myStatement.close();

myConnection.close();

}

5.8 CallableStatement,扩展PreparedStatement 以执行数据库 SQL 存储过程。该类继承 PreparedStatement 的输入 setter 方法(请参阅上面的 [1])。

以下示例假定已创建该数据库存储过程:

CREATE PROCEDURE select_user (@usernamevarchar(20)) AS SELECT * FROM USERS WHERE USERNAME = @username;

如何在 J2EE 中使用 CallableStatement 以执行以上存储过程的示例:

//J2EE PreparedStatemenet Example

//Get a connection to the database

Connection myConnection;

if(isDataSourceEnabled()) {

// using the DataSource to get a managed connection

Context ctx = new InitialContext();

myConnection =((DataSource)ctx.lookup(datasourceName)).getConnection(dbUserName, dbPassword);

}else {

try {

// using the DriverManager to get a JDBC connection

Class.forName(jdbcDriverClassPath);

myConnection = DriverManager.getConnection(jdbcURL, dbUserName,dbPassword);

} catch (ClassNotFoundException e) {

...

}

}

...

try{

PreparedStatement myStatement = myConnection.prepareCall("{?= callselect_user ?,?}");

myStatement.setString(1, userNameField);

myStatement.registerOutParameter(1, Types.VARCHAR);

ResultSet rs = myStatement.executeQuery();

...

rs.close();

}catch (SQLException sqlException) {

...

}finally {

myStatement.close();

myConnection.close();

}

5.9实体 Bean,代表持久存储机制中的EJB 业务对象。实体 Bean 有两种类型:bean 管理和容器管理。当使用 bean 管理的持久性时,开发者负责撰写访问数据库的 SQL 代码。当使用容器管理的持久性时,EJB 容器会自动生成 SQL 代码。因此,容器要负责防止恶意尝试篡改生成的 SQL 代码。

如何在 J2EE 中使用实体 Bean 的示例:

//J2EE EJB Example

try{

// lookup the User home interface

UserHome userHome = (UserHome)context.lookup(User.class);

// find the User remote interface

User = userHome.findByPrimaryKey(new UserKey(userNameField));

...

}catch (Exception e) {

...

}

推荐使用的 JAVA 工具不适用

参考资料http://java.sun.com/j2se/1.4.1/docs/api/java/sql/PreparedStatement.htmlhttp://java.sun.com/j2se/1.4.1/docs/api/java/sql/CallableStatement.html

时间: 2024-12-15 06:09:37

SQL注入漏洞 详解的相关文章

Java程序员从笨鸟到菜鸟之(一百)sql注入攻击详解(一)sql注入原理详解

前段时间,在很多博客和微博中暴漏出了12306铁道部网站的一些漏洞,作为这么大的一个项目,要说有漏洞也不是没可能,但其漏洞确是一些菜鸟级程序员才会犯的错误.其实sql注入漏洞就是一个.作为一个菜鸟小程序员,我对sql注入的东西了解的也不深入,所以抽出时间专门学习了一下.现在把学习成果分享给大家,希望可以帮助大家学习.下面我们就来看一下. 一.什么是sql注入呢?         所谓SQL注入,就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的

Java程序员从笨鸟到菜鸟之(一百零一)sql注入攻击详解(二)sql注入过程详解

在上篇博客中我们分析了sql注入的原理,今天我们就来看一下sql注入的整体过程,也就是说如何进行sql注入,由于本人数据库和网络方面知识有限,此文章是对网上大量同类文章的分析与总结,其中有不少直接引用,参考文章太多,没有注意出处,请原作者见谅) SQL注入攻击的总体思路是: 1.发现SQL注入位置: 2.判断后台数据库类型: 3.确定XP_CMDSHELL可执行情况 4.发现WEB虚拟目录 5. 上传ASP木马: 6.得到管理员权限: 一.SQL注入漏洞的判断 一般来说,SQL注入一般存在于形如

常见sql注入原理详解!

1.首先我们创建一个mysqli的链接 /**数据库配置*/ $config = ['hostname'=>"localhost", 'port'=>"3306", 'username'=>"root",'password'=>'','db'=>'sql']; /**接收参数*/ $id = $_GET['id']?$_GET['id']:""; if(empty($id)){ echo &quo

利用SQL注入漏洞登录后台的实现方法 。。。。转载

一.SQL注入的步骤 a) 寻找注入点(如:登录界面.留言板等) b) 用户自己构造SQL语句(如:' or 1=1#,后面会讲解) c) 将sql语句发送给数据库管理系统(DBMS) d) DBMS接收请求,并将该请求解释成机器代码指令,执行必要的存取操作 e) DBMS接受返回的结果,并处理,返回给用户 因为用户构造了特殊的SQL语句,必定返回特殊的结果(只要你的SQL语句够灵活的话). 下面,我通过一个实例具体来演示下SQL注入 二.SQL注入实例详解(以上测试均假设服务器未开启magic

利用SQL注入漏洞登录后台的实现方法

利用SQL注入漏洞登录后台的实现方法 作者: 字体:[增加 减小] 类型:转载 时间:2012-01-12我要评论 工作需要,得好好补习下关于WEB安全方面的相关知识,故撰此文,权当总结,别无它意.读这篇文章,我假设读者有过写SQL语句的经历,或者能看得懂SQL语句 早在02年,国外关于SQL注入漏洞的技术文章已经很多,而国内在05年左右才开始的.  如今,谈SQL注入漏洞是否已是明日黄花,国内大大小小的网站都已经补上漏洞.但,百密必有一疏,入侵是偶然的,但安全绝对不是必然的.  前些天,网上传

利用SQL注入漏洞登录后台

题记:工作需要,得好好补习下关于WEB安全方面的相关知识,故撰此文,权当总结,别无它意.读这篇文章,我假设读者有过写SQL语句的经历,或者能看得懂SQL语句 早在02年,国外关于SQL注入漏洞的技术文章已经很多,而国内在05年左右才开始的. 如今,谈SQL注入漏洞是否已是明日黄花,国内大大小小的网站都已经补上漏洞.但,百密必有一疏,入侵是偶然的,但安全绝对不是必然的. 前些天,网上传得沸沸扬扬的“拖库”事件给我们敲响了安全警钟. 在开发网站的时候,出于安全考虑,需要过滤从页面传递过来的字符.通常

Android LaunchAnyWhere (Google Bug 7699048)漏洞详解及防御措施

开始 近日,Google修复一个组件安全的漏洞LaunchAnyWhere(Google Bug 7699048).这个漏洞属于Intend Based提取漏洞,攻击者利用这个漏洞,可以突破了应用间的权限隔离,达到调用任意私有Activity(exported为false)的目的. 该漏洞影响Android 2.3至4.3固件. 漏洞分析 在分析这个漏洞之前,需要先介绍两个东西. Account管理机制 从Android2.0开始,系统引入了Account管理机制,详细使用说明见Android官

jdbc mysql crud dao模型 sql注入漏洞 jdbc 操作大文件

day17总结 今日内容 l JDBC 1.1 上次课内容总结 SQL语句: 1.外键约束:foreign key * 维护多个表关系! * 用来保证数据完整性! 2.三种关系: * 一对多: * 一个客户可以对应多个订单,一个订单只属于一个客户! * 建表原则: * 在多的一方创建一个字段,作为外键指向一的一方的主键!!! * 多对多: * 一个学生可以选择多个课程,一个课程也可以被多个学生选择! * 建表原则: * 创建第三张表,第三张表中放入两个字段,作为外键分别指向多对多双方的主键! *

WEB安全:XSS漏洞与SQL注入漏洞介绍及解决方案

对web安全方面的知识非常薄弱,这篇文章把Xss跨站攻击和sql注入的相关知识整理了下,希望大家多多提意见. 对于防止sql注入发生,我只用过简单拼接字符串的注入及参数化查询,可以说没什么好经验,为避免后知后觉的犯下大错,专门参考大量前辈们的心得,小小的总结一下,欢迎大家拍砖啊 一.跨站脚本攻击(XSS) 跨站脚本攻击的原理 XSS又叫CSS (Cross Site Script) ,跨站脚本攻击.它指的是恶意攻击者往Web页面里插入恶意脚本代码,而程序对于用户输入内容未过滤,当用户浏览该页之时