asp.net 如何防止sql注入()-冯金伟博客园

SQL注入攻击和预防

关于SQL注入攻击及防范

随着网络的普及和关系数据库的广泛应用,网络安全变得越来越重要。下面,我为你搜索整理了SQL注入的攻击和防范。请参考并阅读。希望对你有帮助。更多信息请关注我们的应届毕业生培训网!

一.SQL注入袭击

简而言之,SQL注入是应用程序开发人员在应用程序中意外引入SQL代码的过程。其应用程序的糟糕设计使之成为可能,只有那些直接使用用户提供的值来构建SQL语句的应用程序才会受到影响。

例如,在用户输入客户ID后,GridView显示该客户的所有行记录。在更真实的情况下,用户必须输入密码等认证信息,或者根据之前的登录页面获取用户ID。还可能有一些文本框供用户输入关键信息,如订单的日期范围或产品名称。问题是如何执行命令。在这个例子中,SQL语句是通过字符串构造技术动态创建的。文本框txtID的值被直接复制到字符串中。代码如下:

在本例中,攻击者可以篡改SQL语句。通常,攻击的第一个目标是获取错误信息。如果错误处理不当,底层信息将暴露给攻击者。该信息可用于进一步的攻击。

例如,想象一下当您在文本框中输入以下字符串时会发生什么。

阿尔弗基& # 39;或者& # 39;1'='一个

查看结果生成的完整SQL语句:

该语句将返回所有订单记录,即使这些订单不是由ALFDI创建的,因为对于每一行,1=1始终为真。这样做的后果是不显示当前用户的具体信息,而是将所有信息显示给攻击者。如果敏感信息,如社会安全号码、生日或信用卡信息显示在屏幕上,将会带来严重的问题。其实这些简单的SQL注入往往是那些大型电商的烦恼。一般来说,攻击点不在于文本框,而在于查询字符串(可以用来向数据库传输值,比如从列表页到详细页的唯一标识符)。

还可以进行更复杂的攻击。例如,攻击者可以使用两个连字符(-)来注释掉SQL语句的其余部分。这种攻击仅限于SQL Server,但对于其他类型的数据库也有等效的方法,比如MySql使用(#)和Oracle使用(;)号。此外,攻击者可以执行包含任意SQL语句的批处理命令。对于SQL Server提供程序,攻击者只需在新命令前面加上分号(;)。攻击者可以通过这种方式删除其他表的内容,甚至可以调用SQL Server的系统存储过程xp_cmdshell来命令和执行任意程序。

攻击者在文本框中输入以下内容,其目标是删除Customers表中的所有行。

《伦春》;从客户中删除*

第二,预防

如何防止SQL注入袭击?需要记住几点。首先,使用文本框是个好主意。MaxLength属性来防止用户输入过长的字符。因为它们不够长,所以减少了大量粘贴脚本的可能性。其次,应该使用ASP.NET验证控件来锁定错误的数据(如文本、空单元格和数值中的特殊字符)。此外,您应该限制错误消息给出的提示。当捕获到数据库异常时,只显示一些常规信息(如“数据源错误”),而不是异常中的信息。消息属性,这可能暴露系统攻击点。

更重要的是,必须小心地删除特殊字符。例如,您可以用两个单引号替换单引号,这样就不会与SQL语句的分隔符混淆:

字符串ID=txtID。文本()。替换(“”、“”);

当然,如果文本确实需要包含单引号,这样做会带来其他麻烦。此外,一些SQL注入攻击是可行的。替换单引号可以防止用户提前结束字符串。但是,如果包含数值的SQL语句是动态构造的,SQL注入攻击将再次发挥作用空。这个漏洞经常被忽视(这是非常危险的)。更好的解决方案是使用参数化命令或存储过程进行转义,以防止SQL注入攻击。

另一个好的建议是限制用于访问数据库的帐户的权限。该帐户无权访问其他数据库或执行扩展存储过程。但是,这并不能解决SQL脚本注入的问题,因为用于连接数据库的进程几乎总是比任何单个用户需要更多的权限。通过限制权限,可以防止删除表的攻击,但是不能防止攻击者偷看别人的。信息。

第三,注射后攻击

精明的用户可能知道还有另一种攻击Web控件的潜在方法。尽管参数化命令可以防止SQL注入攻击,但它们无法防止攻击者向发送回服务器的数据中添加恶意值。如果不检查这些值,攻击者可以提交本来不存在的控制值。

例如,假设您有一个显示当前用户订单的列表。狡猾的攻击者可能会保存页面的本地副本,修改HTML内容以向列表中添加更多项目,然后选择一个“假”项目。如果攻击成功,攻击者将能够看到其他用户的订单,这显然是一个问题。幸运的是,ASP.NET使用一个很少被提及的功能“事件验证”来防止这种攻击。事件验证检查发送回服务器的数据,并验证其值的合法性。例如,如果提交的数据表明用户选择了一个无意义的数据(因为它不存在于控件中),ASP.NET将生成一个错误并停止处理。通过在Page指令中将EnableEventValidation属性设置为false,可以禁用事件验证。当您创建使用客户端脚本动态更改内容的页面时,您需要执行此步骤。但是,此时,在使用这些值之前,请注意检查潜在的后注入攻击。

;

MyBatis怎么防止SQL注入?

用#{参数}进行预编译就可以防止了,千万别用${}这种方式注入参数。

mybatis框架作为一款半自动化的持久层框架,其sql语句都要我们自己来手动编写,这个时候当然需要防止sql注入。其实Mybatis的sql是一个具有“输入+输出”功能,类似于函数的结构,如下:

select id,title,author,content

from blog where id=#{id}

这里,parameterType标示了输入的参数类型,resultType标示了输出的参数类型。回应上文,如果我们想防止sql注入,理所当然地要在输入参数上下功夫。上面代码中高亮部分即输入参数在sql中拼接的部分,传入参数后,打印出执行的sql语句,会看到sql是这样的:

select id,title,author,content from blog where id = ?

不管输入什么参数,打印出的sql都是这样的。这是因为mybatis启用了预编译功能,在sql执行前,会先将上面的sql发送给数据库进行编译,执行时,直接使用编译好的sql,替换占位符“?”就可以了。因为sql注入只能对编译过程起作用,所以这样的方式就很好地避免了sql注入的问题。

网站如何防止SQL注入?

防止SQL注入的方法就是不要在程序中使用拼接的方式生成SQL语句

如:”select*fromTableNamewherecolumnName='”+变量+”‘”

这样很容易被注入,

如果变量=”‘or1=1–“

这句sql的条件将永远为真

如果采用拼接SQL要把变量中的’(单引号)替换为”(两个单引号)

预编译为什么能防止sql注入?

因为preparedStatement中可以不包含数据,只包含操作,这样就不需要用数据来拼接SQL。

java如何防sql攻击?

java防SQL注入,最简单的办法是杜绝SQL拼接,SQL注入攻击能得逞是因为在原有SQL语句中加入了新的逻辑,如果使用PreparedStatement来代替Statement来执行SQL语句,其后只是输入参数,SQL注入攻击手段将无效,这是因为PreparedStatement不允许在不同的插入时间改变查询的逻辑结构 ,大部分的SQL注入已经挡住了, 在WEB层我们可以过滤用户的输入来防止SQL注入比如用Filter来过滤全局的表单参数 。下面就举三个例子来说明一下:

第一种:

采用预编译语句集,它内置了处理SQL注入的能力,只要使用它的setString方法传值即可,如下所示:

String sql= “select * from users where username=? and password=?;PreparedStatement preState = conn.prepareStatement(sql);preState.setString(1, userName);preState.setString(2, password);ResultSet rs = preState.executeQuery();…

第二种:

采用正则表达式将包含有 单引号(‘),分号(;) 和 注释符号(–)的语句给替换掉来防止SQL注入,如下所示:

public static String TransactSQLInjection(String str)

{

return str.replaceAll(“.*(+|(–)+).*”, ” “);

}

userName=TransactSQLInjection(userName);

password=TransactSQLInjection(password);

String sql=”select * from users where username='”+userName+”‘ and password='”+password+”‘ “

Statement sta = conn.createStatement();

ResultSet rs = sta.executeQuery(sql);

第三种:

使用Hibernate框架的SQL注入防范 Hibernate是目前使用最多的ORM框架,在Java Web开发中,很多时候不直接使用JDBC,而使用Hibernate来提高开发效率。

在Hibernate中,仍然不应该通过拼接HQL的方式,而应使用参数化的方式来防范SQL注入。有两种方式,一种仍然是使用JDBC一样的占位符“?”,但更好的方式是使用Hibernate的命名参数,例如检测用户名和密码是否正确,使用Hibernate可以写成如下:

String queryStr = “from user where username=:username ”+”password=:password”;

List result = session.createQuery(queryStr).setString(“username”, username).setString(“password”, password).list();