在各种Internet攻击行为中,通过Web方式侵入系统造成信息泄漏、数据丢失的事件非常普遍。例如,攻击者在页面表单中输入恶意内容,绕过输入检查,攻击系统。为此,Web开发者应采取有效的措施从信息采集的入口处堵截恶意内容的进入。本文将对这方面的问题进行分析,并提供几种应对方法。
问题分析
Web页面包含文本和HTML标记,它们由服务器建立,被客户端解释。HTML标记一般被服务器特殊对待。例如,“<”一般指示一个HTML标记的开始,“<P>”可以影响页面的显示格式,<Script>可以将脚本代码引入浏览器而执行。
对于静态页面,服务器可以完全控制它在客户端如何解释。但是对于动态页面,服务器就不可能完全控制它在客户端的解释行为了。这样就产生了问题:如果动态页面中包含了不可信的内容,那么无论是服务器端还是客户端,就不能保证是否会发生安全问题。
现在,几乎所有的商用Web服务器就会建立动态页面。最典型的一个例子就是我们经常要使用的搜索引擎,它接受用户的查询内容后,搜索数据库,然后将动态内容写入一个页面模板,最后显示给用户包含搜索结果的页面。这种情况下,检查动态内容是否包含了特殊字符就非常重要,例如“<”。如果包含了特殊字符,用户端的浏览器就可能将之误解为HTML标记或者引入执行程序,而不是当做文本信息显示出来。危险也就产生于此!如果不对动态页面进行特殊字符的检查,那么攻击者就有可能在交互页面的输入表单中写入些特殊字符串,从而导致输出页面执行非法行为。这种例子很多,比如我们编写一个留言簿,却不对输入内容进行特殊字符的校验,那么攻击者就有可能填写特殊字符,最终导致留言簿页面的非正常工作,例如填写一段恶意代码:死循环JavaScript脚本、重复打开窗口的JavaScript脚本。
应对措施分析
通常,不被信任的内容主要来自以下几个方面:URL参数,表单输入元素,Cookies和数据库查询。要减轻这些方面可能导致的攻击,建议采取如下的步骤:
1、为每个由服务器产生的Web页面明确地设置字符集编码
2、鉴别特殊的字符
3、对动态输出内容编码
4、过滤动态输出内容中的特殊字符
5、检查cookies 值
以下详细分析这5个步骤。
第一步:明确地设置字符集编码
字符集编码就是页面的字符编码体系,在浏览器中可以通过“查看/编码”来转换:
很多Web页面都省略了字符集编码设置,也就是说在页面源代码头部HTTP一节中没有定义charset参数。早期的HTML版本中,如果没有定义charset参数,字符集编码就默认为ISO-8859-1。但实际上,许多浏览器都有各自的默认字符集编码。因此,HTML版本4规定,如果没有指定charset参数,任何可能的字符集编码都可以使用,这就依赖于用户的浏览器种类了。
如果Web服务器不能指定使用哪个字符集编码,那么它就不能区分出特殊字符。没有指定字符集编码的Web页面之所以可以在大多数时间中工作良好,这是因为在大多数的字符集编码类别中,同一字符对应一个小于128的字节值。对于大于128的特殊字符,例如“<”,将采用16位字符编码方案处理。一些浏览器能够识别并执行这种编码方案,但同时,攻击者也可能据此使用恶意脚本,使防范难度加大,因为服务器可能完全不能了解哪个字节代表哪个特殊字符。例如,字符集UTF-7为“<”和“>”提供了可选编码,几种流行的浏览器一般将它们看做标记的起始和结束字符。为了不造成服务器和客户端的字符编码的不一致,Web服务器应该明确设置字符集,以确认插入的数据是否为特殊字符编码的后续字节。比如,下面的代码强行设置了页面使用ISO-8859-1字符集编码:
<HTML>
<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<TITLE>HTML SAMPLE</TITLE>
</HEAD>
<BODY>
<P>This is a sample HTML page
</BODY>
</HTML>