首页 理论教育 Web编程安全优化技巧

Web编程安全优化技巧

时间:2023-06-09 理论教育 版权反馈
【摘要】:在Web程序结构中,浏览器端与应用服务器端采用请求/响应模式进行交互,如图3-5所示。Web页面之间传递数据,是Web程序的重要功能。这4种方法各有特点,安全性也不一样,下面重点对Cookie方法进行分析。服务器端可以对该Cookie进行读取并验证。但是,不能说Cookie就是绝对安全的,因为Cookie是以文件的形式保存在客户端中的,客户端存储的Cookie文件可能被攻击者所发现。3)利用客户端脚本“窃取”Cookie。

Web编程安全优化技巧

实际上,Web程序在架构上属于浏览器/服务器(B/S)模式,是电子商务应用的主要模式。随着Internet技术的兴起,B/S结构成为对C/S结构的一种改进。这种结构有如下特点:

●程序完全放在应用服务器上,并在应用服务器上运行,通过应用服务器同数据库服务器进行通信

●客户机上无须安装任何客户端软件,系统界面通过客户端浏览器展现,客户端只需要在浏览器内输入URL。

●修改了应用系统,只需要维护应用服务器。

目前的网络应用系统中,由于B/S结构有很多优点,所以其占绝对主流地位。

在Web程序结构中,浏览器端与应用服务器端采用请求/响应模式进行交互,如图3-5所示。

978-7-111-39843-1-Chapter03-21.jpg

图3-5 Web请求/响应模式

1.避免URL操作攻击

统一资源定位器(Uniform Resoure Locator,URL),是Internet上用来描述信息资源的字符串,可以帮助计算机来定位这些Web上可用的资源。

URL操作攻击的原理:一般是通过URL来猜测某些资源的存放地址,从而非法访问受保护的资源。举一个例子,假如有一个教学管理系统,教师输入自己的账号、密码,可以看到他所教的班级的学生信息。系统流程如下:

1)首先呈现给教师的是登录页面,如http://localhost:8080/Prj08/login.jsp,该页面代码中,首先显示一个表单。

2)登录成功后,教师会看到welcome界面,如http://localhost:8080/Prj08/welcome.jsp。在该页面中,首先从session中获取登录用户名,然后结合两个表进行查询,得到此班级的学生姓名,在列表中,显示了该教师所教班级的学生;后面的链接负责将该学生的学号传给display.jsp。

3)用户单击名为“李刚”的学生的“查看”链接,到达页面:http://localhost:8080/Prj08/display.jsp?stuno=0035。

表面上看去,该程序没有任何问题。但是,在前面的步骤中,单击“李刚”右边的“查看”链接时,用于学生“李刚”从数据库获取数据的URL为

http://localhost:8080/Prj08/display.jsp?stuno=0035

该URL非常直观,可以从中看到的是获取stuno为0035的数据,因此,给了攻击者机会,可以很容易尝试将表示命令数据库查询学号的学生信息作为输入,例如,stuno为0024,攻击者可以不用登录,直接输入类似上面格式的URL(如http://localhost:8080/Prj08/display.jsp?stuno=0024),将信息显示出来。

为了解决URL操作攻击,程序员可在编写Web应用时,从以下两个方面加以注意:

1)为了避免非登录用户进行访问,对于每一个只有登录成功才能访问的页面,应该进行session的检查。

2)为限制用户访问未被授权的资源,可在查询时将登录用户的用户名也考虑进去。在向数据库查询时,就可以首先检查用户名是否处于登录状态。

2.页面状态值安全

HTTP是无状态的协议。Web页面本身无法向下一个页面传递信息,如果需要让下一个页面得知该页面中的值,除非通过服务器。因此,Web页面保持状态并传递给其他页面,是一个重要技术。

Web页面之间传递数据,是Web程序的重要功能。在HTTP中一共有4种方法来完成这项功能:URL传值、表单传值、Cookie方法和session方法。这4种方法各有特点,安全性也不一样,下面重点对Cookie方法进行分析。

Cookie是一个小的文本数据,由服务器端生成,发送给客户端浏览器。客户端浏览器如果设置为启用Cookie,则会将这个小文本数据保存到某个目录下的文本文件中,Windows操作系统中一般保存到Temporary Internet Files文件夹中。

客户端下次登录同一个网站时,浏览器会自动将Cookie读入,并传递给服务器端。服务器端可以对该Cookie进行读取并验证。

基于这个原理,当Web页面之间传递数据时,可以用Cookie来进行。即在第一个页面中,将要共享的变量值保存在客户端Cookie文件内,在客户端访问第二个页面时,由于浏览器自动将Cookie读入之后,传递给服务器端,因此只需要在第二个页面中,由服务器端页面读取这个Cookie值即可。

以JSP为例,编写对Cookie的操作方法的代码为cookieP1.jsp:

978-7-111-39843-1-Chapter03-22.jpg

978-7-111-39843-1-Chapter03-23.jpg

页面上有一个链接到达cookieP2.jsp,其代码为:

978-7-111-39843-1-Chapter03-24.jpg

运行cookieP1和cookieP2,在用户端的浏览器上,看不到任何与传递的值相关的信息,说明在客户端浏览器中,Cookie中的数据是安全的。

但是,不能说Cookie就是绝对安全的,因为Cookie是以文件的形式保存在客户端中的,客户端存储的Cookie文件可能被攻击者所发现。以Windows XP系统为例,C盘是系统盘,Cookie文件保存在C:\Document and Settings\当前用户名\Cookie目录下。打开Cookie文件,内容即以文本的形式展现。其中,Number的值12可以很容易被找到。

很明显,如果将用户名、密码等敏感信息保存在Cookie内,在用户离开客户机时未注意清空,这些信息容易泄露,因此Cookie在保存敏感信息方面具有潜在危险。

不过,可以很清楚地看到,Cookie的危险性来源于Cookie的被“盗取”。目前“盗取”的方法有很多种:

1)利用跨站脚本技术,将信息发给目标服务器。为了隐藏跨站脚本的URL,甚至可以结合Ajax(异步JavaScript和XML技术)后台“窃取”Cookie。

2)通过某些软件,窃取硬盘下的Cookie。如前所述,当用户访问完某站点后,Cookie文件会存储在机器的某个文件夹下,因此可以通过某些“盗取”和分析软件来“窃取”Cookie。

3)利用客户端脚本“窃取”Cookie。在JavaScript中有很多API可以读取客户端Cookie,可以将这些代码隐藏在一个程序中,很隐秘地得到Cookie的值,不过,这也是跨站脚本的一种实现方式。

同样,以上问题不代表Cookie就没有任何用处,Cookie在Web编程中还是应用很广的,主要包括以下几个方面:

1)Cookie的值能够持久化,即使客户端机器关闭,下次打开还是可以得到里面的值。因此Cookie可以用来减轻用户一些验证工作的输入负担。

2)Cookie可以帮助服务器端保存多个状态信息,但是不用服务器端专门分配存储资源,减轻了服务器端的负担。

3)Cookie可以持久保存一些与客户相关的信息。如很多网站上,客户可以自主设计自己的个性化主页,其作用是避免用户每次都重新寻找自己喜爱的内容。

解决Cookie安全问题的方法有很多,常见的有以下几种。

1)替代Cookie。将数据保存在服务器端,可选的是session方案。

2)及时删除Cookie。要删除一个已经存在的Cookie,有以下几种方法:

●给一个Cookie赋以空值。(www.xing528.com)

●设置Cookie的失效时间为当前时间,让该Cookie在当前页面浏览完后就被删除。

●通过浏览器删除Cookie。如在IE中,可以选择“工具”→“Internet选项”→“常规”,单击“删除Cookies”,就可以删除文件夹中的Cookie。

3)禁用Cookie。很多浏览器中都可以设置禁用Cookie,如在IE中,可以选择“工具”→“Internet选项”→“隐私”,将隐私级别设置为禁用Cookie。

3.Web跨站脚本攻击

跨站脚本在英文中称为Cross-Site Scripting,缩写为CSS。但是,由于层叠样式表(Cascading Style Sheets)的缩写也为CSS,为不与其混淆,特将跨站脚本缩写为XSS。跨站脚本,顾名思义,就是恶意攻击者利用网站漏洞往Web页面里插入恶意代码,一般需要以下几个条件:

●客户端访问的网站是一个有漏洞的网站,但是他没有意识到。

●在这个网站中通过一些手段放入一段可以执行的代码,吸引客户执行(通过鼠标单击等)。

●客户单击后,代码执行,可以达到攻击目的。

以下模拟了一个通过邮件单击链接的攻击过程。攻击者给客户发送一个邮件,并且在电子邮件中,通过某个利益的诱惑,鼓动用户尽快访问某个网站,并在邮件中给出一个地址链接,这个链接的URL中含有脚本,客户在单击的过程中,就执行了这段代码。

模拟一个邮箱系统,首先是用户登录页面,当用户登录成功后,为了以后操作方便,该网站采用了“记住登录状态”的功能,将自己的用户名和密码放入Cookie,并保存在客户端。

首先,输入正确的账号和密码(如ligang和123456),如果登录成功,程序跳到登录成功页面,并在页面底部有一个“查看邮箱”链接。为了模拟攻击,单击“查看邮箱”,在里面放置一封“邮件”(该邮件的内容由攻击者撰写)。maiIList.jsp代码如下:

978-7-111-39843-1-Chapter03-25.jpg

978-7-111-39843-1-Chapter03-26.jpg

通过这里的“领奖”链路可链接到另一个网站,该网站一般是攻击者自行建立。为了保证模拟的真实性,在IIS下用ASP写了一个网页,因为攻击者页面和被攻击者页面一般不在一个网站内。很明显,如果用户单击链接,脚本中的send函数会将内容发送给http://localhost/attackPage.asp。假设http://localhost/attackPage.asp的源代码如下:

978-7-111-39843-1-Chapter03-27.jpg

注意,attackPage.asp要在IIS中运行,和前面的例子运行的不是一个服务器。用户如果单击了“领奖”链接,运行结果将会显示account和password,即Cookie中的关键值都被攻击者知道了。在实际攻击的过程中,Cookie的值可以被攻击者保存到数据库或者通过其他手段得知,也就是说,Cookie的值不可能直接在攻击页面上显示,否则很容易被用户发现,这里只是模拟。

从以上例子可以看出,XSS可以诱使Web站点执行本来不属于它的代码,而这些代码由攻击者提供、为用户浏览器加载,攻击者利用这些代码执行来获取信息。XSS涉及三方,即攻击者、客户端与客户端访问的网站。XSS的攻击目标是“盗取”客户端的敏感信息。从本质上讲,XSS漏洞终究原因是由于网站的Web应用对用户提交请求参数未做充分的检查过滤。

防范XSS攻击主要从网站开发者和用户角度来考虑。

(1)从网站开发者角度

●对于任意的输入数据应该进行验证,以有效检测攻击,也就是说,某个数据被接受之前,必须使用一定的验证机制来验证所有的输入数据。

●对于任意的输出数据,要进行适当的编码,防止任何已成功注入的脚本在浏览器端运行。数据输出前,确保用户提交的数据已被正确地进行编码。

(2)从网站用户角度

●打开一些E-mail或附件、浏览论坛帖子时,进行操作时一定要特别谨慎,否则有可能导致恶意脚本执行。不过,也可以在浏览器设置中关闭JavaScript,如果是IE的话,可以单击“工具”→“Internet选项”→“安全”→“自定义级别”进行设置。

●增强安全意识,只信任值得信任的站点或内容,不要随意相信陌生网站发到自己信任的网站中的内容。

4.SQL注入

SQL注入(SQL Injection)是黑客对Web数据库进行攻击的常用手段之一。在这种攻击方式中,恶意代码被插入到查询字符串中,然后将该字符串传递到数据库服务器执行,根据数据库返回的结果,获得某些数据并发起进一步攻击,甚至获取管理员账号及密码、窃取或者篡改系统数据。

举例说明SQL注入。假定数据库中有一个表格,通过登录页面,可输入用户的账号、密码,然后登录,查询数据库,为了简化问题,仅提供其SQL程序予以分析。Login.jsp代码如下。

978-7-111-39843-1-Chapter03-28.jpg

运行login.jsp,在文本框内输入查询信息,提交,能够到达loginResult.jsp,显示登录结果。代码如下:

978-7-111-39843-1-Chapter03-29.jpg

运行loginResult.jsp,显示的结果为SELECT*FROM USERS WHERE ACCOUNT='ligang' AND PASSWORD='123456'。熟悉SQL的读者可以看到,该结果没有任何问题,但是该程序有漏洞。例如,客户输入账号为aa'ORl=1--,密码随意输入,显示结果为SELECT*FROM USERS WHERE ACCOUNT='aa'ORl=1--'AND PASSWORD='123456'。其中,--表示注释,因此,真正运行的SQL语句如下:

SELECT*FROM USERS WHERE ACCOUNT='aa'OR1=1

此处,1=1永真,所以该语句将返回USERS表中的所有记录。网站受到了SQL注入的攻击。

另一种方法是使用通配符进行注入。例如,有一个页面,可以从STUDENTS表中对学生的姓名(STUNAME)进行模糊查询,其基本过程同上例。但是当该程序客户输入非正常数据%'—充当STUNAME时,查询显示的结果为SELECT*FROM STUDENTS WHERE STUNAME LIKE'%%'--%'。该程序中,--同样表示注释,因此,真正运行的SQL语句是SELECT*FROM STUDENTS WHERE STUNAME LIKE'%%'。该语句中,也会将STUDENTS中所有的内容显示出来,相当于程序又允许了无条件的模糊查询。

SQL注入攻击问题的解决方法有很多种,目前比较常见的有:

1)将输入中的单引号变成双引号。这种方法经常用于解决数据库输入问题,同时也是一种针对数据库安全问题的补救措施。

2)使用存储过程。如上面的例子中,可以将查询功能写在存储过程proGetCustomer内,当攻击者输入“'ligang'orl--”时,SQL命令显然无法通过存储过程的编译。

3)认真对表单输入进行校验,从查询变量中滤去尽可能多的可疑字符。可以利用一些手段,测试输入字符串变量的内容,定义一个格式为只接受的格式,只有此种格式下的数据才能被接受,拒绝其他输入的内容。

4)在程序中,组织SQL语句时,应该尽量将用户输入的字符串以参数的形式进行包装,而不是直接嵌入SQL语句。

5)严格区分数据库访问权限。在权限设计中,对于应用软件的使用者,一定要严格限制权限,没有必要赋予数据库对象的建立、删除等权限。

6)多层架构下的防治策略。在多层环境下,用户输入数据的校验与数据库的查询被分离成多个层次。

7)对于数据库敏感的、重要的数据,不要以明文显示,要进行加密。

8)对数据库查询中的出错信息进行屏蔽,尽量减小攻击者根据数据库的查询出错信息来猜测数据库特征的可能。

9)由于SQL注入有时伴随着猜测,因此,如果发现一个IP不断登录或者短时间内不断进行查询,可以自动拒绝其登录,也可以建立攻击者IP地址备案机制。

10)可以使用专业的漏洞扫描工具来寻找可能被攻击的漏洞。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈