日期:2011-12-06  浏览次数:21124 次

2.2 cookie的问题
2.2.1 概念介绍
按照Netscape官方文档中的定义,Cookie是在HTTP协议下,服务器或脚本可以维护客户工作站上信息的一种方式。Cookie是由Web服务器保
存在用户浏览器上的小广西文件,它可以包含有关用户的信息(如身份识别号码、密码、用户在Web站点购物的方式或用户访问该站点的次数)
。无论何时用户链接到服务器,Web站点都可以访问Cookie信息。

通俗地讲,浏览器用一个或多个限定的文件来支持Cookie。这些文件在使用Windows操作系统的机器上叫做Cookie文件,在Macintosh机器上
叫做magic Cookie 文件,这些文件被网站用来在上面存储Cookie数据。网站可以在这些Cookie文件中插入信息,这样对有些网络用户就有些
副作用。有些用户认为这造成了对个人隐私的侵犯,更糟的是,有些人认为Cookie是对个人空间的侵占,而且会对用户的计算机带来安全性的危
害。

目前有些Cookie是临时的,另一些则是持续的。临时的Cookie只在浏览器上保存一段规定的时间,一旦超过规定的时间该Cookie就会被系统清
除。例如在PHP中Cookie被用来跟踪用户进程直到用户离开网站。持续的Cookie则保存在用户的Cookie文件中,下一次用户返回时,仍然可以
对它进行调用。

要了解Cookie,必不可少地要知道它的工作原理。一般来说,Cookie通过HTTP Headers从服务器端返回到浏览器上。首先,服务器端在响应
中利用Set-Cookie header来创建一个Cookie,然后,浏览器在它的请求中通过Cookie header包含这个已经创建的Cookie,并且反它返回
至服务器,从而完成浏览器的论证。 例如,我们创建了一个名字为login的Cookie来包含访问者的信息,创建Cookie时,服务器端的Header如
下面所示,这里假设访问者的注册名是"Michael Jordan",同时还对所创建的Cookie的属性如path、domain、expires等进行了指定。

Set-Cookie:login=Michael Jordan;path=/;domain=msn.com;
expires=Monday,01-Mar-99 00:00:01 GMT

上面这个Header会自动在浏览器端计算机的Cookie文件中添加一条记录。浏览器将变量名为"login"的Cookie赋值为"Michael Jordon"。注意
,在实际传递过程中这个Cookie的值是经过了URLEncode方法的URL编码操作的。

这个含有Cookie值的HTTP Header被保存到浏览器的Cookie文件后,Header就通知浏览器将Cookie通过请求以忽略路径的方式返回到服务器
,完成浏览器的认证操作。

此外,我们使用了Cookie的一些属性来限定该Cookie的使用。例如Domain属性能够在浏览器端对Cookie发送进行限定,具体到上面的例子,
该Cookie只能传达室到指定的服务器上,而决不会跑到其他的如www.hp.com的Web站点上去。Expires属性则指定了该Cookie保存的时间期
限,例如上面的Cookie在浏览器上只保存到1999年3月1日1秒。当然,如果浏览器上Cookie太多,超过了系统所允许的范围,浏览器将自动对
它进行删除。至于属性Path,用来指定Cookie将被发送到服务器的哪一个目录路径下。

说明:浏览器创建了一个Cookie后,对于每一个针对该网站的请求,都会在Header中带着这个Cookie;不过,对于其他网站的请求Cookie是
绝对不会跟着发送的。而且浏览器会这样一直发送,直到Cookie过期为止。

2.2.2 要点方法
setcookie-----送出 Cookie 信息到浏览器。
语法: int setcookie(string name, string value, int expire, string path, string domain, int secure);
返回值: 整数
本函数会跟着标识 Header 送出一段小信息字符串到浏览器。使用本函数要在送出 HTML 数据前,实际上 cookie 也算标识的一部份。本函数的
参数除了第一个 name 之外,都是可以省略的。参数 name 表示 cookie 的名称;value 表示这个 cookie 的值,这个参数为空字符串则表示取
消浏览器中该 cookie 的数据;expire 表示该 cookie 的有效时间;path 为该 cookie 的相关路径;domain 表示 cookie 的网站;secure 则
需在 https 的安全传输时才有效。想得到更多的 cookie 信息可以到 http://www.netscape.com/newsref/std/cookie_spec.html,由
cookie 原创者 Netscape 所提供的完整信息。

对于一个网站会员而言,经常存在需要一次注册,多次认证的问题,例如我们经常接触到的论坛、社区等,一般采用手段为cookie或 input
type=hidden来传递认证参数。这里面有几点隐患:

I. setcookie内容必须完整包含帐号密码,或类似的完整安全信息,如果只携带帐号信息或用某种权限标志来认证,极容易造成非法入侵。
例如某站点中的会员更新页面中携带的认证信息是两个,用户名和Uid(均为明文传送)已知Uid对于每个会员是唯一的。由于我们只需要知道对
方的帐号和Uid就可以更改对方信息(不需要知道密码!),只要攻击者知道Uid(攻击者可以通过暴力猜测的方法来得到Uid,有时候站点本身
也会泄露用户的Uid,例如在论坛等处)那么,攻击者就可以通过遍历攻击完成对任意一个帐号的信息更改。

II. 必须所有需要权限操作的页面都必须执行认证判断的操作。如果任何一页没有进行这种认证判断,都有可能给攻击者以恶意入侵的机会。

III. 很多网站为了方便,将用户名以及口令信息储存在Cookie中,有的甚至以明文方式保存口令。如果攻击者可以访问到用户的主机,就可能
通过保存的Cookie文件得到用户名和口令。

3. 脚本保护的问题
3.1 概念介绍
在程序编写时优秀的程序员都会知道,用有意义的变量名,文件名有助于增加程序的可读性,具有良好的程序风格。这个非常好但在脚本语言不太
适合,为了不让恶意用户猜到你的变量或数据库名等信息,必须改掉这些信息。动态的网页在服务器端执行后返回给客户的是执行后的代码,这可
以保护服务器端的很多不想叫或不能叫浏览者知道的信息。安全是相对的,每天都在有新的安全漏洞被发现,如果恶意的用户在你之前知道了一个
可以看你的脚本源代码的漏洞或这个漏洞一时间无法修补怎么办?
3.2 主意要点
建议用一些比较怪异的名字命名,删掉脚本中的注释。如果还需要保持程序的可读性的话,可以建立一个映射,你可以写个具有良好风格的脚本程
序,然后再做一个变量名映射建立一个具有较安全命名方法的脚本,去掉这个脚本中的注视和所有能去掉的信息,修改时作个同步就可以了
我们可以在程序的使用前对程序进行加密,以保护我们自己的程序再万一的情况下部被泄漏。
3.3 保护方法

我看到过很多的对脚本的加密方法,都很不错,有的是专门的加密软件,有的是通过一些技巧加上利用语言的特性进行加密的,例如随机生成一个
密匙,把密匙放在"不可见的"地方,通过一些算法对脚本进行加解密,就是由于某些系统漏洞导致你的脚本源代码泄漏,也无济于事。

4 .实例说明
下面这个例子是在网上经常被提到的,这是个非常经典的例子,所以在这里通过这个实例告诉大家可能存在的危险。
问题描述:
  大部分网站把密码放到数据库中,在登陆验证中用以下sql,(以asp为例)
sql="select * from user where username='"&username&"'and pass='"& pass &'"
  此时,您只要根据sql构造一个特殊的用户名和密码,如:ben' or '1'='1
就可以进入本来你没有特权的页面。再来看看上面那个语句吧:
sql="select * from user where username='"&username&"'and pass='"& pass&'&q