前言
首先介绍HTTP协议和会话管理,然后讲述浏览器的安全性功能之一,也是理解跨站脚本等主要安全隐患的原理的必备知识——同源策略。
一、HTTP与会话管理
可以使用Fiddler观察HTTP消息。
1.HTTP消息
分为请求消息与响应消息两部分,请求消息是浏览器向服务器发出的请求,响应消息是Web服务器返回的内容。
1.1 请求消息
请求行
GET http://example.lp/31/31-001.php HTTP/1.1
请求信息
Accept:Image/gif,Image/x-xbitmap,Image/jpeg,Image/pjpeg,application/x-ms-application
Accept-Language:ja
Host:example.jp
请求行
格式为 请求方法:请求URL+协议版本,请求方法有GET(取得资源),POST,HEAD。
GET http://example.lp/31/31-001.php HTTP/1.1
请求信息
格式为 名称:值,其中只有Host必须,Host表示接收信息的主机名和端口号(80可省略),如果HTTP协议版本为1.0 ,Host也可以省略。
Accept:Image/gif,Image/x-xbitmap,Image/jpeg,Image/pjpeg,application/x-ms-application
Accept-Language:ja
Host:example.jp
1.2 响应消息
状态行
HTTP/1.1 200 OK
响应头信息
Date:Mon,10 Jan 2011 05:34:30 GMT
sEVER:aPACHE/2.2.14(Ubuntu)
X-Powered-By:PHP/5.3.2-1ununtu4.2
Vary:Accept-Encoding
Content-Length:20
Keep-Alive:timeout=15,max=100
Connection:Keep-Alive
Content-Type:text/html;charset=UTF-8
空行
响应正文
<body>
14:34</bosy>
状态行:请求消息经过服务器处理后的状态。
HTTP/1.1 200 OK
状态码的百位数有特殊含义,代表了几种响应状态
状态码 | 概要 |
1xx | 处理正在继续 |
2xx | 成功 |
3xx | 重定向 |
4xx | 客户端错误 |
5xx | 服务器错误 |
常见状态码:200(成功),301和302(重定向),404(找不到资源),500(服务器内部发生错误)
响应头信息
Date:Mon,10 Jan 2011 05:34:30 GMT
sEVER:aPACHE/2.2.14(Ubuntu)
X-Powered-By:PHP/5.3.2-1ununtu4.2
Vary:Accept-Encoding
Content-Length:20 <!-- 显示相应正文的字节数 -->
Keep-Alive:timeout=15,max=100
Connection:Keep-Alive
Content-Type:text/html;charset=UTF-8 <!-- 指定为MIME类型 -->
常见的MIME类型
MIME类型 | 含义 |
text/plain | 文本 |
text/html | HTML文档 |
application/xml | XML文档 |
text/css | CSS |
mage/gif | GIF图像 |
image/jpeg | JPEG图像 |
iamge../Images/7- | PNG图像 |
application/pdf | PDF图像 |
2.会话管理
HTTP会不断的进行请求与响应,可以比喻为对话。
在页面注册时,输入信息后点击确认按钮,可以在Fiddler中查看到HTTP请求信息。
2.1 POST方法
点击“确认”后摘取的部分请求消息
POST /31/31-003.php HTTP/1.1
Referer:http://example.jp/31/31-002.php
Content-Type:application/x-www-form-urlencoded<!-- 发送值的MIME类型,可通过HTML的form元素设置,此处为默认值 -->
Content-Length:70<!-- 消息体的字节数 -->
Host:example.jp
name=%E5%BE%B3%E4%B8%B8%E6%B5%A9&MAIL=TOKU@EXAMPLE.JP&GNEDER=%E7%94%B7<!-- 消息体 -->
消息体
通过POST方法发送的值。
格式 名称=值,通过&相连,其中,名称和值都经过了百分号编码。
百分号编码
中文和特殊符号等不能直接用于URL,需要进行百分号编码。将字符以字节为单位转换成%xx的形式。xx为该字节的十六进制写法。
例如:将“德”进行UTF-8编码,可得到E5 BE B3字节列,百分号编码后为%E5%BE%B3
Referer
能告诉我们当前请求是从哪个页面链接过来的,值就是那个页面的URL。Referer有时可以提升安全性,有时也会成为安全隐患。好处是,通过查看Referer,能够确认应用程序的跳转是否和预期一样。但是,和其他头信息一样,Referer能够通过Fidder之类的工具修改,或者被浏览器插件和其他安全软件修改或删除,所以未必会正确显示链接的来源。当URL中包含敏感信息时,存在被Referer泄密的风险。
例如:URL中包含的对话ID通过Referer泄露给外界,从而使自己的身份被人恶意冒名顶替。
GET与POST区别
GET方法仅用于查阅(获取资源),没有副作用,且使用URL后紧跟查询字符串的形式来传递参数,浏览器和服务器都能够处理的URL长度是6,非常有限。
GET方法风险
1.URL中指定的参数经由Referer泄漏
2.URL中指定的参数残留在访问日志(Access Log)中
副作用:指除了获取资源(内容)以外的其他操作。比如,追加/更新/删除服务器端的数据、购买商品、注册/删除用户等操作
当满足1、请求中包含数据更新等副作用时 2、发送敏感信息时 3、发送的信息量很多时。使用POST,相反则使用GET。
2.2 hidden参数
点击确认注册后,用户在注册页面输入的值会以hidden参数的形式在HTML源代码中记录下来,hidden参数将会被发送给Web服务器。发送前可以通过Fiddler改变hidden参数的值。所以,一旦处理hidden参数的地方存在安全隐患,会有被Fiddler等代理工具实施篡改和攻击的风险(被用户自己更改)。
HTTP协议无状态性:无法记忆客户端的当前状态。因此,需要借助hidden参数记忆状态。
要点:浏览器发送的值都能被变更。
优点
能够有效面对信息泄露与第三方篡改等危险。
像认证和授权信息这样需谨防被用户自己更改的信息,应当保存在会话变量中。除此之外的信息,首先考虑能否保存在hidden参数中。特别是在登录前的状态下,由于不存在与认证、授权相关的信息,因此,应该使用hidden,来防止信息泄露的危险。
2.3 无状态的HTTP认证
HTTP认证根据实现方式可分为Basic认证、NTLM认证和Digest认证等,HTTP认证无状态。
2.4 Cookie与会话管理
HTTP协议具有无状态性,服务器端不能保存客户端的状态,为了实现会话管理,HTTP引入了Cookie机制。Cookie相当于服务器下达给浏览器的命令,让其记住发送给他的“名称=变量”这种格式的值。当前大多数应用都采用Cookie来进行会话管理,这在认证结果的保存等安全性方面扮演着重要角色。
会话管理:记忆应用程序状态的功能。
以用户身份认证为例。在显示输入ID与密码页面时,返回的响应消息如下。通过Set-Cookie响应头信息,Web服务器向浏览器下达了记住此Cookie值的指示。
HTTP/1.1 200 OK
Set-Cookie:PHPSESSID=gg5144avrhmdiaelvh80l4lb53;path=/
Content-Length:279
Content-Type:text/html;charset=UTF-8
<html>
<head><title>请登录</title></head>
<body>
点击登录按钮后,浏览器向服务器发送请求。记住了Cookie值的浏览器,再向相同网站发送请求时,就会同时发送此Cookie值(PHPSESSID)。Cookie可以设置有效期限,没有设置有效期限的Cookie会在浏览器被关闭前一直有效。保存在会话变量中的信息,在会话失效之前随时都能被访问。
PHPSESSID的值被称为会话ID,是访问会话信息的关键。
POST /31/31-021.php HTTP/1.1
Referer:http://example.jp/31/31-020.php
Content-Type:application/x-www-form-urlencoded
Host:example.jp
Content-Length:18
Cookie:PHPSESSID=gg5144avrhmdiaelvh80l4lb53
ID=user1&PWD=pass1
Cookie能让浏览器保存少量数据,但此值能被用户看到或更改,所以不适用于存储敏感信息。可以在Cookie中保存类似“受理编号”的会话ID,实际对应的值保存在服务器端,此方法称为使用Cookie的会话管理。
2.4.1 会话ID需求
需求1:会话ID不能被第三方推测
本质上要求随机数的质量,使用密码学级别的伪随机数生成器生成。在实际开发中,会话ID使用Web应用开发工具提供的会话ID。使用开发工具提供的会话管理机制。
需求2:会话ID不能被第三方劫持
认证后改变会话ID。
需求3:会话ID不能向第三方泄漏
采用SSL(Secure Socket Layer)加密。
2.4.2 Cookie属性
生成Cookie时的主要属性。涉及安全的3个属性为Domain、Secure、HttpOnly。
属性 | 含义 |
Domain | Cookie发送对象服务器的域名 |
Path | Cookie发送对象URL的路径 |
Expires | Cookie的有效期限。未指定则表示至浏览器关闭为止 |
Secure | 仅在SSL加密的情况下发送Cookie |
HttpOnly | 指定了此属性的Cookie不能被JavaScript访问 |
Domain属性
Cookie在默认情况下只能被发送到与其绑定的服务器,指定Domain属性后,可以发送给多个服务器。
Domain=example.jp,Cokkie可以被发送给a.example.jp和b.example.jp。
原则上不设置Cookie的Domain属性。
HttpOnly属性
加大跨站脚本攻击难度,应时常加上HttpOnly属性。
session.cookie_httponly = on