技巧和诀窍:防范SQL注入攻击
Tip/Trick: Guard Against SQL Injection Attacks 【原文发表日期】 Saturday, September 30, 2006 9:11 AM SQL注入攻击是非常令人讨厌的安全漏洞,是所有的web开发人员,不管是什么平台,技术,还是数据层,需要确信他们理解和防止的东西。不幸的是,开发人
Tip/Trick: Guard Against SQL Injection Attacks
【原文发表日期】 Saturday, September 30, 2006 9:11 AM
SQL注入攻击是非常令人讨厌的安全漏洞,是所有的web开发人员,不管是什么平台,技术,还是数据层,需要确信他们理解和防止的东西。不幸的是,开发人员往往不集中花点时间在这上面,以至他们的应用,更糟糕的是,他们的客户极其容易受到攻击。
Michael Sutton 最近发表了一篇非常发人深省的帖子,讲述在公共网上这问题是多么地普遍。他用Google的Search API建了一个C#的客户端程序,寻找那些易受SQL 注入攻击的网站。其步骤很简单:
- 寻找那些带查询字符串的网站(例如,查询那些在URL里带有 "id=" 的URL)
- 给这些确定为动态的网站发送一个请求,改变其中的id=语句,带一个额外的单引号,来试图取消其中的SQL语句(例如,如 id=6' )
- 分析返回的回复,在其中查找象“SQL” 和“query”这样的词,这往往表示应用返回了详细的错误消息(这本身也是很糟糕的)
- 检查错误消息是否表示发送到SQL服务器的参数没有被正确加码(encoded),如果如此,那么表示可对该网站进行SQL注入攻击
对通过Google搜寻找到的1000个网站的随机取样测试,他检测到其中的11.3%有易受SQL注入攻击的可能。这非常,非常地可怕。这意味着黑客可以远程利用那些应用里的数据,获取任何没有hashed或加密的密码或信用卡数据,甚至有以管理员身份登陆进这些应用的可能。这不仅对开发网站的开发人员来说很糟糕,而且对使用网站的消费者或用户来说更糟糕,因为他们给网站提供了数据,想着网站是安全的呢。
那么SQL注入攻击到底是什么玩意?
有几种情形使得SQL注入攻击成为可能。最常见的原因是,你动态地构造了SQL语句,却没有使用正确地加了码(encoded)的参数。譬如,考虑这个SQL查询的编码,其目的是根据由查询字符串提供的社会保险号码(social security number)来查询作者(Authors):
Dim SSN as String
Dim SqlQuery as String
SSN = Request.QueryString("SSN")
SqlQuery = "SELECT au_lname, au_fname FROM authors WHERE au_id = '" + SSN + "'"
如果你有象上面这个片断一样的SQL编码,那么你的整个数据库和应用可以远程地被黑掉。怎么会呢?在普通情形下,用户会使用一个社会保险号码来访问这个网站,编码是象这样执行的:
' URL to the page containing the above code
http://mysite.com/listauthordetails.aspx?SSN=172-32-9999
' SQL Query executed against the database
SELECT au_lname, au_fname FROM authors WHERE au_id = '172-32-9999'
这是开发人员预期的做法,通过社会保险号码来查询数据库中作者的信息。但因为参数值没有被正确地加码,黑客可以很容易地修改查询字符串的值,在要执行的值后面嵌入附加的SQL语句 。譬如,
' URL to the page containing the above code
http://mysite.com/listauthordetails.aspx?SSN=172-32-9999';DROP DATABASE pubs --
' SQL Query executed against the database
SELECT au_lname, au_fname FROM authors WHERE au_id = '';DROP DATABASE pubs --
注意到没有,我可以在SSN查询字符串值的后面添加“ ';DROP DATABASE pubs -- ”,通过 “;”字符来终止当前的SQL语句,然后添加了我自己的恶意的SQL语句,然后把语句的其他部分用“--”字符串注释掉。因为我们是手工在编码里构造SQL语句,我们最后把这个字符串传给了数据库,数据库会先对authors表进行查询,然后把我们的pubs数据库删除。“砰(bang)”的一声,数据库就没了!
万一你认为匿名黑客删除你的数据库的结果很坏,但不幸的是,实际上,这在SQL注入攻击所涉及的情形中算是比较好的。一个黑客可以不单纯摧毁数据,而是使用上面这个编码的弱点,执行一个JOIN语句,来获取你数据库里的所有数据,显示在页面上,允许他们获取用户名,密码,信用卡号码等等。他们也可以添加 UPDATE/INSERT 语句改变产品的价格,添加新的管理员账号,真的搞砸你(screw up your life)呢。想象一下,到月底检查库存时,发现你库房里的实际产品数与你的帐目系统(accounting system)汇报的数目有所不同。。。
那该如何保护你自己?
SQL注入攻击是你需要担心的事情,不管你用什么web编程技术,再说所有的web框架都需要担心这个的。你需要遵循几条非常基本的规则:
1) 在构造动态SQL语句时,一定要使用类安全(type-safe)的参数加码机制。大多数的数据API,包括ADO和ADO.NET,有这样的支持,允许你指定所提供的参数的确切类型(譬如,字符串,整数,日期等),可以保证这些参数被恰当地escaped/encoded了,来避免黑客利用它们。一定要从始到终地使用这些特性。
例如,在ADO.NET里对动态SQL,你可以象下面这样重写上述的语句,使之安全:
Dim SSN as String = Request.QueryString("SSN")
Dim cmd As new SqlCommand("SELECT au_lname, au_fname FROM authors WHERE au_id = @au_id")
Dim param = new SqlParameter("au_id", SqlDbType.VarChar)
param.Value = SSN
cmd.Parameters.Add(param)
这将防止有人试图偷偷注入另外的SQL表达式(因为ADO.NET知道对au_id的字符串值进行加码),以及避免其他数据问题(譬如不正确地转换数值类型等)。注意,VS 2005内置的TableAdapter/DataSet设计器自动使用这个机制,ASP.NET 2.0数据源控件也是如此。
一个常见的错误知觉(misperception)是,假如你使用了存储过程或ORM,你就完全不受SQL注入攻击之害了。这是不正确的,你还是需要确定在给存储过程传递数据时你很谨慎,或在用ORM来定制一个查询时,你的做法是安全的。
2) 在部署你的应用前,始终要做安全审评(security review)。建立一个正式的安全过程(formal security process),在每次你做更新时,对所有的编码做审评。后面一点特别重要。很多次我听说开发队伍在正式上线(going live)前会做很详细的安全审评,然后在几周或几个月之后他们做一些很小的更新时,他们会跳过安全审评这关,推说,“就是一个小小的更新,我们以后再做编码审评好了”。请始终坚持做安全审评。
3) 千万别把敏感性数据在数据库里以明文存放。我个人的意见是,密码应该总是在单向(one-way )hashed过后再存放,我甚至不喜欢将它们在加密后存放。在默认设置下,ASP.NET 2.0 Membership API 自动为你这么做,还同时实现了安全的SALT 随机化行为(SALT randomization behavior)。如果你决定建立自己的成员数据库,我建议你查看一下我们在这里发表的我们自己的Membership provider的源码。同时也确定对你的数据库里的信用卡和其他的私有数据进行了加密。这样即使你的数据库被人入侵(compromised)了的话,起码你的客户的私有数据不会被人利用。
4) 确认你编写了自动化的单元测试,来特别校验你的数据访问层和应用程序不受SQL注入攻击。这么做是非常重要的,有助于捕捉住(catch)“就是一个小小的更新,所有不会有安全问题”的情形带来的疏忽,来提供额外的安全层以避免偶然地引进坏的安全缺陷到你的应用里去。
5) 锁定你的数据库的安全,只给访问数据库的web应用功能所需的最低的权限。如果web应用不需要访问某些表,那么确认它没有访问这些表的权限。如果web应用只需要只读的权限从你的account payables表来生成报表,那么确认你禁止它对此表的 insert/update/delete 的权限。
如何了解更多的相关知识
微软Prescriptive Architecture Guidance (PAG)产品组发表了许多非常棒的安全指导方针方面的文档,你应该留出些时间来阅读一下:
- ASP.NET 2.0 安全指定方针
- ASP.NET 2.0 安全部署清单
- ASP.NET 2.0 安全实践概述
- Web应用工程安全索引
- 如何对托管编码进行安全编码审评
- ASP.NET 2.0 安全问题列表
- ASP.NET 2.0 安全培训单元(Training Modules)
此外,还有这些其他的PAG How-To文章对进一步了解如何保护你免受注入攻击大有用处:
- 如何在ASP.NET里防范表单注入攻击
- 如何在ASP.NET里防范SQL注入攻击
你还可以在我写的这篇关于安全的博客帖子以及我的ASP.NET 技巧和诀窍页上找到关于ASP.NET安全方面的有用的信息。
更新: Bertrand给我指出了他2年前写的这篇关于SQL注入攻击的非常棒的帖子,非常值得一读。
希望本文对你有所帮助,
Scott
ASP.NET, Security, Tips and Tricks
(思归译)

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

HQL和SQL在Hibernate框架中进行比较:HQL(1.面向对象语法,2.数据库无关的查询,3.类型安全),而SQL直接操作数据库(1.与数据库无关的标准,2.可执行复杂查询和数据操作)。

Win11小技巧分享:一招跳过微软账户登录Windows11是微软最新推出的操作系统,具有全新的设计风格和许多实用的功能。然而,对于一些用户来说,在每次启动系统时都要登录微软账户可能会感到有些烦扰。如果你是其中一员,不妨尝试一下以下的技巧,让你能够跳过微软账户登录,直接进入桌面界面。首先,我们需要在系统中创建一个本地账户,来代替微软账户登录。这样做的好处是

C语言中,表示指针,存储其他变量的地址;&表示地址运算符,返回变量的内存地址。指针的使用技巧包括定义指针、解引用指针,需确保指针指向有效地址;地址运算符&的使用技巧包括获取变量地址,获取数组元素地址时返回数组第一元素地址。实战案例说明了使用指针和地址运算符反转字符串。

Win11技巧大揭秘:如何绕过微软账户登录近期,微软公司推出了全新的操作系统Windows11,引起了广泛关注。相比之前的版本,Windows11在界面设计、功能改进等方面做出了许多新的调整,但也引发了一些争议,其中最引人关注的一点就是强制要求用户使用微软账户登录系统。对于一些用户来说,他们可能更习惯于使用本地账户登录,而不愿意将个人信息与微软账户绑定。

在Go语言程序开发中,函数重构技巧是十分重要的一环。通过优化和重构函数,不仅可以提高代码质量和可维护性,还可以提升程序的性能和可读性。本文将深入探讨Go语言中的函数重构技巧,结合具体的代码示例,帮助读者更好地理解和应用这些技巧。1.代码示例1:提取重复代码片段在实际开发中,经常会遇到重复使用的代码片段,这时就可以考虑将重复代码提取出来作为一个独立的函数,以

排位打累了?那就来打球吧!默契配合的队友,让对手尝一尝出其不意的滋味!瞬息万变的战场,试看如何巧用技能一招破局!《永劫无间》在4月11日的更新中上线了一个全新的团队对抗模式,下面就给大家带来永劫无间热血斗振球活动介绍。永劫无间热血斗振球玩法一览简介:通过各种手段反弹斗球,击败敌人。人数:单排9人,三排6人玩法说明:回合:1、游戏分为多个回合,每回合开始时,斗球会出生在场地中央随机选取一名玩家追击,玩家使用各种手段击球会使斗球提速,被斗球击中将会扣除体力。2、单排每人每回合拥有一点体力,三排每人每

题目:PHP替换技巧大揭秘!PHP作为一种流行的服务器端脚本语言,经常被用来处理数据的替换和操作。在日常开发中,我们经常会遇到需要对字符串进行替换的情况。本文将为大家揭秘PHP中一些常用的替换技巧,并给出具体的代码示例,帮助读者更好地掌握这些技术。1.使用str_replace()函数str_replace()函数是PHP中最常用的字符串替换函数之一。它可

BitMEX交易所提币要求:必须完成两步验证和身份验证。最低提币金额因币种而异。提币流程包括登录账户、输入提币地址、输入金额和确认交易。BitMEX提币的优点包括快速处理、低手续费、多种币种支持和严格的安全措施。然而,它也面临监管不足、黑客攻击风险、提币限制和账户冻结风险等缺点。
