热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

深入研究数据访问:什么是SQL注入

简单地说,SQL注入是一种技术,它可以让恶意用户注入SQL命令,这些命令在语义上是合法的,但可以改变命令预期的行为,并且有可能危及应用程序的安全。这会儿你可能在挠头,并尝试多读几次看是否有更多的意义。通过示例解释起来会更直观一些。

简单地说,SQL注入是一种技术,它可以让恶意用户注入SQL命令,这些命令在语义上是合法的,但可以改变命令预期的行为,并且有可能危及应用程序的安全。这会儿你可能在挠头,并尝试多读几次看是否有更多的意义。通过示例解释起来会更直观一些。

想想前面章节看到的SQL,一个典型的例子是根据所属的类别检索记录:


1
varsql ="SELECT* FROM Items where CategoryId = 2";

<

该语句的问题是:类别是常量。它不会改变,这意味着始终会检索出属于WHERE语句指定的类别的数据。根据网站的情况和需求,这可能确实不是一件坏事。向用户提供一种可以通过类别过滤产品的方法是非常常见的需求。通常使用表单,将类别列表放在下拉菜单或文本框中。服务器端代码接收到传递过来的选项,用它动态组装成一条可用的SQL语句,如下所示:


1
varsql ="SELECT * FROM Items WHERE CategoryId = "+ Request["categoryId"];

<

此刻,任何传入Request[“categoryId”]的值都将和SQL字符串连接在一起并在数据库中执行。没有阻止用户向文本框里输入非法信息的措施。如果用户向文本框中输入垃圾数据,连接在一起的结果可能会不符合SQL语法,网站会出现问题;否则SQL会成功执行。在前面的例子里,如果用户输入数值2,同时对前一章的示例数据库执行SQL,那么将导致所有属于Computing类别的条目被检索出来。但是用户还可以向文本框中输入下面的内容:


1
2or1=1

<

当被拼接在一起时候,结果会是这样:


1
SELECT * FROMItems WHERE CategoryId =2or1=1

<

这完全是有效的SQL,同时会返回所有行,因为WHERE 1 = 1这个条件一直是成立的。

该SQL的初衷是提供一种方法,在用户知道哪些有效的类别可用的情况下,可以将结果限制在一种类别里;但是由于允许用户通过注入额外的过滤器修改SQL的行为,导致了预料不到的结果。这就是SQL注入,是安全性不高的网站暴露出的最多的两个漏洞之一。

前面的例子看起来不怎么危险,那么SQL注入能导致什么问题呢?首先,为了好的初衷才提供了过滤器。因为有上百万条记录,过滤器原本可能是用来防止检索出所有的记录,同时持续请求所有的记录会降低网站的性能。这也使得拒绝服务攻击(DoS)变得更加容易,另外还有更大的风险。

看看下面的代码段:

1
2
3
varsql = @"SELECTCount(*) FROM Users   
WHERE UserName ='" + Request["UserName"] + "'  
AND Password ='"+ Request["UserPass"] + "'";

 

 

这常作为用户认证的方式,用于匹配在登录表单中提供的用户名和密码。它用于测试数据库中有多少条记录和用户提供的用户名和密码匹配,如果结果大于0,用户就可以进一步操作。在前面的示例中,展示了总是成立的条件并导致返回了所有的记录。这里有另外一个总是成立的条件:


1
WHERE' '=' '

<

 

对于黑客来说,很容易向这个SQL中注入代码,从而返回用户表中的所有数据,因此只需要向用户名或密码文本框中输入'or'"=',就可以访问网站中的限制区域。拼接将完成创建有效的可被执行的SQL语句的工作。

幸运的是,相比SQL Server完整版,SQL Server Compact有一些功能性限制。例如,Compact版本不支持批处理语句,更强大的数据库可以做到这点,这会令它们面临潜在的严重后果。批处理语句可以在一条SQL语句中传递多个操作,每个独立的命令都会依次执行。下面展示了一个批处理示例:


1
SELECT * FROMItems; DROP TABLE Users

 

在SQL Server数据库中执行该语句,首先会返回Items表中的所有条目,然后会永久删除名为Users的数据表。甚至还有更强大的命令,能够导致整个数据库被删除,甚至导致黑客获取数据库所在服务器的完整控制权。

参数保护

现在知道了问题的本质,以及能够导致的潜在的非常严重的后果,就需要学习如何使代码远离SQL注入的威胁。一些人建议使用黑名单作为有效途径。这涉及监控用户是否输入了SQL关键词,如果检查到关键字,就驳回提交的请求。这种做法具有两面性:很多SQL关键词是日常用语(or、and等),并且SQL关键词时常变更。这意味着如果黑名单中引入了新的关键词,就不得不更新构建的每个网站。第二个建议是避开单引号,当然这也是有效的,但如果字符串不是SQL的一部分就起不了作用,就像前面的第一个示例。

事实是,只有一种被证明有效的方法能够保护网站不受SQL注入攻击,那就是使用参数。参数是动态数据的占位符,在执行SQL时,这些动态数据以一种安全的方式和SQL语句拼接在一起。为了帮助大家理解它的工作机制,下面举一个例子展示数据库辅助程序如何支持参数的使用:


1
2
varsql ="SELECT* FROM Items WHERE CategoryId = @0;   
vardata =db.Query(sql, Request["categoryId"]);

 

 

注意,@0标记代表了SQL语句中的动态数据,@符号后面跟一个0。像往常一样,SQL被传递到Query方法,但是这次它后面跟着动态数据的源。在内部,数据库辅助程序会创建ADO.NET参数对象并且将其传递到数据库中。数据库会依次检查传入的参数值以保证它们的数据类型和目标列是匹配的,从而避免期望的是数值类型、但传入的是字符串类型的情况;也能保证按照字面含义处理所有被成功传入的字符串,而不是作为被执行SQL的一部分。当然,即使这样还是应该按照第5章中介绍的对用户输入的值进行类型验证。但是现在应该明白参数是如何提供保护网站的。如果只通过参数的形式验证数据类型,应用程序会产生很多异常。

在下面的SQL片段中,按照顺序传入了多个参数:


1
2
3
4
5
varsql ="INSERT INTO items (Title,Description, Price) VALUES (@0, @1, @2) ";   
vartitle =Request["title"];   
vardesc =Request["desc"];   
varprice =Request["price"];   
db.Execute(sql,title, desc, price);

 

参数标识从@0开始,依次递增,这是预先设定的,无法改变。如果序列从@1开始就会产生异常,遗漏任何一个数字也会产生异常。

现在清楚了如何使用数据库辅助程序和参数与数据库安全地交互。下一节将使用这些知识,将之应用到第5章中构建的表单中,在数据库中保存提交的数据。


推荐阅读
  • 深入理解 SQL 视图、存储过程与事务
    本文详细介绍了SQL中的视图、存储过程和事务的概念及应用。视图为用户提供了一种灵活的数据查询方式,存储过程则封装了复杂的SQL逻辑,而事务确保了数据库操作的完整性和一致性。 ... [详细]
  • 本文详细介绍了IBM DB2数据库在大型应用系统中的应用,强调其卓越的可扩展性和多环境支持能力。文章深入分析了DB2在数据利用性、完整性、安全性和恢复性方面的优势,并提供了优化建议以提升其在不同规模应用程序中的表现。 ... [详细]
  • Docker的安全基准
    nsitionalENhttp:www.w3.orgTRxhtml1DTDxhtml1-transitional.dtd ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 360SRC安全应急响应:从漏洞提交到修复的全过程
    本文详细介绍了360SRC平台处理一起关键安全事件的过程,涵盖从漏洞提交、验证、排查到最终修复的各个环节。通过这一案例,展示了360在安全应急响应方面的专业能力和严谨态度。 ... [详细]
  • MySQL缓存机制深度解析
    本文详细探讨了MySQL的缓存机制,包括主从复制、读写分离以及缓存同步策略等内容。通过理解这些概念和技术,读者可以更好地优化数据库性能。 ... [详细]
  • MySQL 数据库迁移指南:从本地到远程及磁盘间迁移
    本文详细介绍了如何在不同场景下进行 MySQL 数据库的迁移,包括从一个硬盘迁移到另一个硬盘、从一台计算机迁移到另一台计算机,以及解决迁移过程中可能遇到的问题。 ... [详细]
  • Startup 类配置服务和应用的请求管道。Startup类ASP.NETCore应用使用 Startup 类,按照约定命名为 Startup。 Startup 类:可选择性地包括 ... [详细]
  • 科研单位信息系统中的DevOps实践与优化
    本文探讨了某科研单位通过引入云原生平台实现DevOps开发和运维一体化,显著提升了项目交付效率和产品质量。详细介绍了如何在实际项目中应用DevOps理念,解决了传统开发模式下的诸多痛点。 ... [详细]
  • 本文深入探讨了SQL数据库中常见的面试问题,包括如何获取自增字段的当前值、防止SQL注入的方法、游标的作用与使用、索引的形式及其优缺点,以及事务和存储过程的概念。通过详细的解答和示例,帮助读者更好地理解和应对这些技术问题。 ... [详细]
  • 本章详细介绍SP框架中的数据操作方法,包括数据查找、记录查询、新增、删除、更新、计数及字段增减等核心功能。通过具体示例和详细解析,帮助开发者更好地理解和使用这些方法。 ... [详细]
  • 配置PHPStudy环境并使用DVWA进行Web安全测试
    本文详细介绍了如何在PHPStudy环境下配置DVWA( Damn Vulnerable Web Application ),并利用该平台进行SQL注入和XSS攻击的练习。通过此过程,读者可以熟悉常见的Web漏洞及其利用方法。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • Windows服务与数据库交互问题解析
    本文探讨了在Windows 10(64位)环境下开发的Windows服务,旨在定期向本地MS SQL Server (v.11)插入记录。尽管服务已成功安装并运行,但记录并未正确插入。我们将详细分析可能的原因及解决方案。 ... [详细]
  • 使用C#开发SQL Server存储过程的指南
    本文介绍如何利用C#在SQL Server中创建存储过程,涵盖背景、步骤和应用场景,旨在帮助开发者更好地理解和应用这一技术。 ... [详细]
author-avatar
yzxnha_975
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有