目录

《图解HTTP》笔记

目录

《图解 HTTP》是一本通俗易懂的介绍 HTTP 协议的书,由日本作者上野宣写作于 2014 年。由于写作时间早于 HTTP/2 的正式发布时间——2015 年 5 月,书中对于 HTTP/2 的部分表述可能有所出入。

了解 Web 及网络基础

网络基础 TCP/IP 协议族

TCP/IP 协议族由上至下分为 4 层:应用层、传输层、网络层、数据链路层。

利用 TCP/IP 协议族进行网络通信时,会通过分层顺序与对方进行通信。发送端从应用层往下走,接收端则往应用层往上走。

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

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

IP(Internet Protocol)网际协议位于网络层,IP 协议的作用是把各种数据包传送给对方。

路由选择(routing),没有计算机设备能够掌握互联网中的细节。

字节流服务(Byte Stream Service)是指,为了方便传输,将大块数据分割成以报文段(segment)为单位的数据包进行管理。

URI 和 URL

URL(Uniform Resource Locator统一资源定位符)。URL 正是使用 Web 浏览器等访问 Web 页面时需要输入的网页地址。

URI 是 Uniform Resource Identifier 的缩写,称为统一资源标识符

  • Uniform:规定统一的格式;
  • Resource:资源的定义是“可标识的任何东西”。
  • Identifier:表示可标识的对象。也称为标识符。

综上所述,URI 就是由某个协议方案表示的资源的定位标识符。

标准的 URI 协议方案有 30 种左右,由隶属于国际互联网资源管理的非营利社团 ICANN(Internet Corporation for Assigned Names and Numbers,互联网名称与数字地址分配机构 )的 IANA(Internet Assigned Numbers Authority,互联网号码分配局)管理颁布。

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

简单的 HTTP 协议

请求报文和响应报文

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

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

HTTP 方法

  • GET 获取资源;
  • POST 传输实体;
  • PUT 传输文件,HTTP/1.1 的 PUT 方法自身不带验证机制;
  • HEAD 与 GET 一样,但不返回报文主体内容;
  • OPTIONS 用来查询支持的方法。
  • TRACE 让 Web 服务器端将之前的请求通信环回给客户端的方法。
  • CONNECT 要求在与代理服务器通信时建立隧道,实现用隧道协议进行 TCP 通信。

HTTP 报文内的 HTTP 信息

编码提升传输速率

压缩传输的内容编码:把实体压缩后传送。主要有:

  • gzip(GNU zip)
  • compress(UNIX 系统的标准压缩)
  • deflate(zlib)
  • identity(不进行编码)

分割发送的分块传输编码:在传输大容量数据时,把数据分割成多块传送。

multipart

  • multipart/form-data 在 Web 表单文件上传时使用。
  • multipart/byteranges 状态码 206(Partial Content,部分内容)响应报文包含了多个范围的内容时使用。

使用时会在 header 中加上 Content-type 字段,并在其中指明 boundary 字符串,来划分多部分对象集合指明的各类实体。在 boundary 字符串指定的各个实体的起始行之前插入--标记,而在多部分对象集合对应的字符串的最后插入--标记。多部分对象集合的每个部分类型中,都可以含有首部字段。

举个栗子(from POST - HTTP | MDN

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
POST /test HTTP/1.1
Host: foo.example
Content-Type: multipart/form-data;boundary="boundary"

--boundary
Content-Disposition: form-data; name="field1"

value1
--boundary
Content-Disposition: form-data; name="field2"; filename="example.txt"

value2
--boundary--

获取部分内容的范围请求

指定所请求实体的范围发送的请求叫做范围请求(Range Request)

执行范围请求时,会用到首部字段 Range 来指定资源的 byte 范围。

1
Range: bytes=5001-10000

针对范围请求,响应会返回状态码为 206 Partial Content 的响应报文。

如果服务器端无法响应范围请求,则会返回状态码 200 OK 和完整的实体内容。

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

  • 内容协商(Content Negotiation)
  • 服务器驱动协商(Server-driven Negotiation)
  • 客户端驱动协商(Agent-driven Negotiation)
  • 透明协商(Transparent Negotiation)

返回结果的 HTTP 状态码

状态码以 3 位数字和原因短语组成,例如 200 OK

2XX 成功

204 No Content 该状态码代表服务器接收的请求已成功处理,但在返回的响应报文中不含实体的主体部分。另外,也不允许返回任何实体的主体。

206 Partial Content 该状态码表示客户端进行了范围请求,而服务器成功执行了这部分的 GET 请求。响应报文中包含由 Content-Range 指定范围的实体内容。

3XX 重定向

303 See Other 303 状态码和 302 Found 状态码有着相同的功能,但 303 状态码明确表示客户端应当采用 GET 方法获取资源,这点与 302 状态码有区别。301、302 标准是禁止将 POST 方法改变成 GET 方法的,但实际使用时大家都会这么做。

307 Temporary Redirect 和 302 Found 状态码有着相同的含义,但 307 会遵照浏览器标准,不会从 POST 变成 GET。

4XX 客户端错误

401 Unauthorized 该状态码表示发送的请求需要有通过 HTTP 认证(BASIC 认证、DIGEST 认证)的认证信息。返回含有 401 的响应必须包含一个适用于被请求资源的 WWW-Authenticate 首部用以质询(challenge)用户信息。也就是说,不采用 HTTP 认证的 Web 系统不应该使用该状态码。

5XX 服务器错误

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

与 HTTP 协作的 Web 服务器

代理、网关和隧道

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

代理:

  • 缓存代理(Caching Proxy) 会预先将资源的副本(缓存)保存在代理服务器上
  • 透明代理(Transparent Proxy) 转发请求或响应时,不对报文做任何加工的代理。反之,对报文内容进行加工的代理被称为非透明代理。

网关能使通信线路上的服务器提供非 HTTP 协议服务。

隧道的目的是确保客户端能与服务器进行安全的通信,隧道本身不会去解析 HTTP 请求。

HTTP 首部

HTTP 报文首部

在请求中,HTTP 报文由方法、URI、HTTP 版本、HTTP 首部字段等部分构成。

在响应中,HTTP 报文由 HTTP 版本、状态码(数字和原因短语)、HTTP 首部字段 3 部分构成。

HTTP 首部字段

根据实际用途被分为以下 4 种类型:

  • 通用首部字段(General Header Fields)
  • 请求首部字段(Request Header Fields)
  • 响应首部字段(Response Header Fields)
  • 实体首部字段(Entity Header Fields)

实体首部字段是针对请求报文和响应报文的实体部分使用的首部。补充了资源内容更新时间等与实体有关的信息。

首部字段的主要定义在 RFC 2616 - Hypertext Transfer Protocol -- HTTP/1.1RFC 4229 - HTTP Header Field Registrations 中。

逐跳首部(Hop-by-hop Header)首部只对单次转发有效,会因通过缓存或代理而不再转发。HTTP/1.1 中的逐跳首部字段有:

  • Connection
  • Keep-Alive
  • Proxy-Authenticate
  • Proxy-Authorization
  • Trailer
  • TE
  • Transfer-Encoding
  • Upgrade

除这 8 个首部字段之外,其他所有字段都属于端到端首部。

HTTP/1.1 通用首部字段

Cache-Control

通过指定首部字段 Cache-Control 的指令,就能操作缓存的工作机制。

no-cache 指令:

  • 客户端发送的请求中如果包含 no-cache 指令,则表示客户端将不会接收缓存过的响应。于是,“中间”的缓存服务器必须把客户端请求转发给源服务器。
  • 如果服务器返回的响应中包含 no-cache 指令,那么缓存服务器不能对资源进行缓存。
  • 由服务器返回的响应中,若报文首部字段 Cache-Control 中对 no-cache 字段名具体指定参数值,那么客户端在接收到这个被指定参数值的首部字段对应的响应报文后,就不能使用缓存。

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

max-age 指令:

  • 当客户端发送的请求中包含 max-age 指令时,如果判定缓存资源的缓存时间数值比指定时间的数值更小,那么客户端就接收缓存的资源。另外,当指定 max-age 值为 0,那么缓存服务器通常需要将请求转发给源服务器。
  • 当服务器返回的响应中包含 max-age 指令时,缓存服务器将不对资源的有效性再作确认,而 max-age 数值代表资源保存为缓存的最长时间。

no-transform 指令:无论是在请求还是响应中,缓存都不能改变实体主体的媒体类型。

Connection

Connection 字段的作用:

  • 控制不再转发给代理的首部字段。在客户端发送请求和服务器返回响应内,使用 Connection 首部字段,可控制不再转发给代理的首部字段(即 Hop-by-hop 首部)。
  • 管理持久连接。HTTP/1.1 版本的默认连接都是持久连接。为此,客户端会在持久连接上连续发送请求。当服务器端想明确断开连接时,则指定 Connection 首部字段的值为 Close

Transfer-Encoding

首部字段 Transfer-Encoding 规定了传输报文主体时采用的编码方式。HTTP/1.1 的传输编码方式仅对分块传输编码有效。

Upgrade

首部字段 Upgrade 用于检测 HTTP 协议及其他协议是否可使用更高的版本进行通信,其参数值可以用来指定一个完全不同的通信协议。

Upgrade 首部字段产生作用的 Upgrade 对象仅限于客户端和邻接服务器之间。因此,使用首部字段 Upgrade 时,还需要额外指定 Connection:Upgrade

Via

使用首部字段 Via 是为了追踪客户端与服务器之间的请求和响应报文的传输路径。

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

请求首部字段

Accept 首部字段可通知服务器,用户代理能够处理的媒体类型及媒体类型的相对优先级。可使用 type/subtype 这种形式,一次指定多种媒体类型。若想要给显示的媒体类型增加优先级,则使用 q=来额外表示权重值

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

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

  • gzip
  • compress
  • deflate
  • identity

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

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

Expect 来告知服务器,期望出现的某种特定行为。因服务器无法理解客户端的期望作出回应而发生错误时,会返回状态码 417 Expectation Failed。

From 用来告知服务器使用用户代理的用户的电子邮件地址。

Host 会告知服务器,请求的资源所处的互联网主机名和端口号。Host 首部字段在 HTTP/1.1 规范内是唯一一个必须被包含在请求内的首部字段。

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

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

Range:对于只需获取部分资源的范围请求,包含首部字段 Range 即可告知服务器资源的指定范围。

Referer:正确拼写应是 Referrer,当直接在浏览器的地址栏输入 URI 时,或出于安全性的考虑时,也可以不发送该首部字段。

响应首部字段

ETag 能告知客户端实体标识。它是一种可将资源以字符串形式做唯一性标识的方式。服务器会为每份资源分配对应的 ETag 值。

Location 可以将响应接收方引导至某个与请求 URI 位置不同的资源。

Proxy-Authenticate 会把由代理服务器所要求的认证信息发送给客户端。

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

Server 告知客户端当前服务器上安装的 HTTP 服务器应用程序的信息。

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

实体首部字段

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

Allow 用于通知客户端能够支持 Request-URI 指定资源的所有 HTTP 方法。

Content-Encoding 会告知客户端服务器对实体的主体部分选用的内容编码方式,主要有:

  • gzip
  • compress
  • deflate
  • identity

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

Content-Type 说明了实体主体内对象的媒体类型。

Cookie 的 path 属性可用于限制指定 Cookie 的发送范围的文件目录。不过另有办法可避开这项限制,看来对其作为安全机制的效果不能抱有期待。

通过 Cookie 的 domain 属性指定的域名可做到与结尾匹配一致。

其他首部字段

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

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

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

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

DNT 属于 HTTP 请求首部,其中 DNT 是 Do Not Track 的简称,意为拒绝个人信息被收集,是表示拒绝被精准广告追踪的一种方法。首部字段 DNT 可指定的字段值有:

  • 0 :同意被追踪
  • 1 :拒绝被追踪

在 HTTP 等多种协议中,通过给非标准参数加上前缀 X-,来区别于标准参数,并使那些非标准的参数作为扩展变成可能。但是这种简单粗暴的做法有百害而无一益,因此在 RFC 6648 - Deprecating the “X-” Prefix and Similar Constructs in Application Protocols 中提议停止该做法。然而,对已经在使用中的 X-前缀来说,不应该要求其变更。

确保 Web 安全的 HTTPS

HTTP 的缺点

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

几个名词缩写:

  • SSL(Secure Socket Layer,安全套接层)
  • TLS(Transport LayerSecurity,安全传输层协议)
  • PGP(Pretty Good Privacy,完美隐私)

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

SSL 是独立于 HTTP 的协议,所以不光是 HTTP 协议,其他运行在应用层的 SMTP 和 Telnet 等协议均可配合 SSL 协议使用。可以说 SSL 是当今世界上应用最为广泛的网络安全技术。

两种加密方式:

  • 公开密钥加密(Public-key cryptography) 加密使用一对非对称的密钥,分别叫做私钥(private key)和公钥(public key)。私钥不能让其他任何人知道,而公钥则可以随意发布,任何人都可以获得。
  • 共享密钥加密(Common key crypto system) 加密和解密同用一个密钥,也被叫做对称密钥加密。

HTTPS 采用共享密钥加密和公开密钥加密两者并用的混合加密机制——在交换密钥环节使用公开密钥加密方式,之后的建立通信交换报文阶段则使用共享密钥加密方式。

HTTPS 数字证书

  1. 数字证书认证机构(CA, Certificate Authority)处于客户端与服务器双方都可信赖的第三方机构的立场上。在判明提出申请者的身份之后,会对申请的公钥做数字签名,然后分配这个已签名的公钥,并将该公钥放入公钥证书后绑定在一起。公钥证书也可叫做数字证书或直接称为证书。
  2. 服务器会将这份由数字证书认证机构颁发的公钥证书发送给客户端;
  3. 客户端可使用数字证书认证机构的公开密钥,对那张证书上的数字签名进行验证,一旦验证通过,客户端便可确认认证服务器公钥的是真实有效的数字证书认证机构,进而确认服务器的公钥是值得信赖的。

SSL 机制中,介入认证机构之所以可行,是因为建立在其信用绝对可靠这一大前提下的。值得信赖的第三方机构介入认证,才能让已植入在浏览器内的认证机构颁布的公开密钥发挥作用,并借此证明服务器的真实性。

HTTPS 中还可以使用客户端证书。以客户端证书进行客户端认证,证明服务器正在通信的对方始终是预料之内的客户端,其作用跟服务器证书如出一辙。但客户端证书仍存在几点问题:

  • 证书的获取及发布困难,对 Web 系统的用户来说自行安装证书需要学习成本;
  • 客户端证书只能用来证明客户端真实有效,而不能用来证明用户本人的真实有效性;

HTTPS 的通信步骤

  1. 客户端通过发送 Client Hello 报文开始 SSL 通信。报文中包含客户端支持的 SSL 的指定版本、加密组件(Cipher Suite)列表(所使用的加密算法及密钥长度等)。
  2. 服务器可进行 SSL 通信时,会以 Server Hello 报文作为应答。和客户端一样,在报文中包含 SSL 版本以及加密组件。服务器的加密组- 件内容是从接收到的客户端加密组件内筛选出来的。
  3. 之后服务器发送 Certificate 报文。报文中包含公开密钥证书。
  4. 最后服务器发送 Server Hello Done 报文通知客户端,最初阶段的 SSL 握手协商部分结束。
  5. SSL 第一次握手结束之后,客户端以 Client Key Exchange 报文作为回应。报文中包含通信加密中使用的一种被称为 Pre-master secret 的随机密码串。该报文已用步骤 3 中的公开密钥进行加密。
  6. 接着客户端继续发送 Change Cipher Spec 报文。该报文会提示服务器,在此报文之后的通信会采用 Pre-master secret 密钥加密。
  7. 客户端发送 Finished 报文。该报文包含连接至今全部报文的整体校验值。这次握手协商是否能够成功,要以服务器是否能够正确解密该报文作为判定标准。
  8. 服务器同样发送 Change Cipher Spec 报文。
  9. 服务器同样发送 Finished 报文。
  10. 服务器和客户端的 Finished 报文交换完毕之后,SSL 连接就算建立完成。当然,通信会受到 SSL 的保护。从此处开始进行应用层协议的通信,即发送 HTTP 请求。
  11. 应用层协议通信,即发送 HTTP 响应。
  12. 最后由客户端断开连接。断开连接时,发送 close_notify 报文。上图做了一些省略,这步之后再发送 TCP FIN 报文来关闭与 TCP 的通信。

在以上流程中,应用层发送数据时会附加一种叫做 MAC(Message Authentication Code) 的报文摘要。MAC 能够查知报文是否遭到篡改,从而保护报文的完整性。

CBC 模式(Cipher Block Chaining) 又名密码分组链接模式。在此模式下,将前一个明文块加密处理后和下一个明文块做 XOR 运算,使之重叠,然后再对运算结果做加密处理。对第一个明文块做加密时,要么使用前一段密文的最后一块,要么利用外部生成的初始向量(initial vector,IV)

确认访问用户身份的认证

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

HTTP BASIC 认证和 HTTP DIGEST 认证都属于质询/响应认证方式。

BASIC 认证

认证步骤:

  1. 当请求的资源需要 BASIC 认证时,服务器会随状态码 401 Authorization Required,返回带 WWW-Authenticate 首部字段的响应。该字段内包含认证的方式(BASIC)及 Request-URI 安全域字符串(realm)。
  2. 接收到状态码 401 的客户端为了通过 BASIC 认证,需要将用户 ID 及密码发送给服务器。发送的字符串内容是由用户 ID 和密码构成,两者中间以冒号 : 连接后,再经过 Base64 编码处理,放在 header 字段 Authorization 中。

缺点:

  1. 由于明文解码后就是用户 ID 和密码,在 HTTP 等非加密通信的线路上进行 BASIC 认证的过程中,如果被人窃听,被盗的可能性极高。
  2. 除此之外想再进行一次 BASIC 认证时,一般的浏览器却无法实现认证注销操作,这也是问题之一。

DIGEST 认证

DIGEST 认证弥补了 BASIC 认证直接发送明文密码的缺点。

认证步骤:

  1. 请求需认证的资源时,服务器会随着状态码 401 AuthorizationRequired,返回带 WWW-Authenticate 首部字段的响应。首部字段 WWW-Authenticate 内必须包含 realmnonce 这两个字段的信息。客户端就是依靠向服务器回送这两个值进行认证的。nonce 是一种每次随返回的 401 响应生成的任意随机字符串。该字符串通常推荐由 Base64 编码的十六进制数的组成形式,但实际内容依赖服务器的具体实现。
  2. 接收到 401 状态码的客户端,返回的响应中包含 DIGEST 认证必须的首部字段 Authorization 信息。首部字段 Authorization 内必须包含 usernamerealmnonceuriresponse 的字段信息。其中,realmnonce 就是之前从服务器接收到的响应中的字段。uri(digest-uri)即 Request-URI 的值,但考虑到经代理转发后 Request-URI 的值可能被修改,因此事先会复制一份副本保存在 uri 内。response 也可叫做 Request-Digest,存放经过哈希算法运算后的密码字符串(不是简单的对密码做哈希),形成响应码。
  3. 服务器认证通过后则返回包含 Request-URI 资源的响应。并且这时会在首部字段 Authentication-Info 写入一些认证成功的相关信息。

缺点:DIGEST 认证提供防止密码被窃听的保护机制,但并不存在防止用户伪装的保护机制。

SSL 客户端认证

认证步骤:

  1. 接收到需要认证资源的请求,服务器会发送 Certificate Request 报文,要求客户端提供客户端证书。
  2. 用户选择将发送的客户端证书后,客户端会把客户端证书信息以 Client Certificate 报文方式发送给服务器。
  3. 服务器验证客户端证书验证通过后方可领取证书内客户端的公开密钥,然后开始 HTTPS 加密通信。

多数情况下,SSL 客户端认证会作为一种多因素认证方式存在,而不会单独使用(因为无法该方式只能认证客户端有效,不能证明客户本人有效)。并且由于成本、易用性等原因,仅在部分安全要求较高的 Web 系统中使用,例如网银、支付系统等。

基于表单认证

但是对于 Web 网站的认证功能,能够满足其安全使用级别的标准规范并不存在,所以只好使用由 Web 应用程序各自实现基于表单的认证方式。

保证安全性:

  1. Session ID 应使用难以推测的字符串,且服务器端也需要进行有效期的管理,保证其安全性。
  2. 为减轻跨站脚本攻击(XSS)造成的损失,建议事先在 Cookie 内加上 httponly 属性。
  3. 不明文保存密码,加盐后做哈希。

基于 HTTP 的功能追加协议

HTTP 的瓶颈:

  • 一条连接上只可发送一个请求。
  • 请求只能从客户端开始。客户端不可以接收除响应以外的指令。
  • 请求/响应首部未经压缩就发送。首部信息越多延迟越大。
  • 发送冗长的首部。每次互相发送相同的首部造成的浪费较多。
  • 可任意选择数据压缩格式。非强制压缩发送。

Ajax、Comet 和 SPDY

Ajax(Asynchronous JavaScript and XML,异步 JavaScript 与 XML 技术),Ajax 的核心技术是名为 XMLHttpRequest 的 API,借由这种手段从已加载完毕的 Web 页面上发起请求,只更新局部页面。但是,利用 Ajax 实时地从服务器获取内容,有可能会导致大量请求产生。另外 Ajax 仍未解决 HTTP 协议本身存在的问题。

Comet 是一种通过延迟应答,模拟实现服务器端向客户端推送(Server Push)的功能。Comet 会先将响应置于挂起状态,当服务器端有内容更新时,再返回该响应。这导致为了维持连接会消耗更多的资源。

SPDY 是由 Google 开发的网络传输协议,SPDY 未能单独成为正式标准,但 SPDY 的成果被采纳而最终演变为 HTTP/2。SPDY 协议通过压缩、多路复用和优先级来缩短加载时间。SPDY 基本上只是将单个域名(IP 地址)的通信多路复用,所以当一个 Web 网站上使用多个域名下的资源,改善效果就会受到限制。

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

WebSocket 通信协议在 2011 年 12 月 11 日,被 RFC 6455 - The WebSocket Protocol 定为标准。由于是建立在 HTTP 基础上的协议,因此连接的发起方仍是客户端,而一旦确立 WebSocket 通信连接,不论服务器还是客户端,任意一方都可直接向对方发送报文。

WebSocket 协议的主要特点:

  • 推送功能:支持由服务器向客户端推送数据;
  • 减少通信量:长连接,header 信息比 HTTP 少;

Web 服务器管理文件的 WebDAV

WebDAV(Web-based Distributed Authoring and Versioning,基于万维网的分布式创作和版本控制)是一个可对 Web 服务器上的内容直接进行文件复制、编辑等操作的分布式文件系统。它还具备文件创建者管理、文件编辑过程中禁止其他用户内容覆盖的加锁功能,以及对文件内容修改的版本控制功能。

构建 Web 内容的技术

CGI 和 Servlet

CGI(Common Gateway Interface,通用网关接口)是指 Web 服务器在接收到客户端发送过来的请求后转发给程序的一组机制。由于每次接到请求,程序都要跟着启动一次。因此一旦访问量过大,Web 服务器要承担相当大的负载。

Servlet 是一种能在服务器上创建动态内容的程序。Servlet 是用 Java 语言实现的一个接口,属于面向企业级 Java(JavaEE,Java Enterprise Edition)的一部分。

数据发布的格式及语言

  • XML(eXtensible Markup Language,可扩展标记语言)
  • RSS(简易信息聚合,也叫聚合内容)和 Atom
  • JSON(JavaScript Object Notation)

Web 的攻击技术

对 Web 应用的攻击模式

对 Web 应用的攻击模式有两种:

  • 主动攻击(active attack) 是指攻击者通过直接访问 Web 应用,把攻击代码传入的攻击模式。主动攻击模式里具有代表性的攻击是 SQL 注入攻击和 OS 命令注入攻击。
  • 被动攻击(passive attack) 是指利用圈套策略执行攻击代码的攻击模式。被动攻击模式中具有代表性的攻击是跨站脚本攻击和跨站点请求伪造。

主动攻击直接针对服务器资源进行攻击,被动攻击的目标是使用 Web 应用的用户。

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

跨站脚本攻击

跨站脚本攻击(Cross-Site Scripting,XSS) 是指通过存在安全漏洞的 Web 网站注册用户的浏览器内运行非法的 HTML 标签或 JavaScript 进行的一种攻击。

会造成以下影响:

  • 利用虚假输入表单骗取用户个人信息;
  • 利用脚本窃取用户的 Cookie 值,被害者在不知情的情况下,帮助攻击者发送恶意请求;
  • 显示伪造的文章或图片。

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

SQL 注入

SQL 注入(SQL Injection) 是指针对 Web 应用使用的数据库,通过运行非法的 SQL 而产生的攻击。

SQL 注入攻击有可能会造成以下等影响:

  • 非法查看或篡改数据库内的数据;
  • 规避认证;
  • 执行和数据库服务器业务关联的程序等。

OS 命令注入

OS 命令注入攻击(OS Command Injection) 是指通过 Web 应用,执行非法的操作系统命令达到攻击的目的。

OS 命令注入攻击可以向 Shell 发送命令,让 Windows 或 Linux 操作系统的命令行启动程序。也就是说,通过 OS 注入攻击可执行 OS 上安装着的各种程序。

HTTP 首部注入

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

HTTP 首部注入攻击有可能会造成以下一些影响:

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

向首部主体内添加内容的攻击称为 HTTP 响应截断攻击(HTTP Response Splitting Attack)

HTTP 响应截断攻击是用在 HTTP 首部注入的一种攻击。攻击顺序相同,但是要将两个 %0D%0A% 并排插入字符串后发送(%0D%0A代表 HTTP 报文中的换行符)。利用这两个连续的换行就可作出 HTTP 首部与主体分隔所需的空行了,这样就能显示伪造的主体,达到攻击目的。

另外,滥用 HTTP/1.1 中汇集多响应返回功能,会导致缓存服务器对任意内容进行缓存操作。这种攻击称为缓存污染。使用该缓存服务器的用户,在浏览遭受攻击的网站时,会不断地浏览被替换掉的 Web 网页。

邮件首部注入

邮件首部注入(Mail Header Injection) 是指 Web 应用中的邮件发送功能,攻击者通过向邮件首部 To 或 Subject 内任意添加非法内容发起的攻击。利用存在安全漏洞的 Web 网站,可对任意邮件地址发送广告邮件或病毒邮件。

目录遍历

目录遍历(Directory Traversal)攻击 是指对本无意公开的文件目录,通过非法截断其目录路径后,达成访问目的的一种攻击。这种攻击有时也称为 路径遍历(Path Traversal) 攻击。因此服务器上任意的文件或文件目录皆有可能被访问到。这样一来,就有可能非法浏览、篡改或删除 Web 服务器上的文件。

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

强制浏览

强制浏览(Forced Browsing) 安全漏洞是指,从安置在 Web 服务器的公开目录下的文件中,浏览那些原本非自愿公开的文件。

会造成的影响有:

  • 泄露顾客的个人信息等重要情报;
  • 泄露原本需要具有访问权限的用户才可查阅的信息内容;
  • 泄露未外连到外界的文件;

容易产生的漏洞地方:

  • 文件目录一览;
  • 容易被推测的文件名及目录名;
  • 备份文件;
  • 经认证才可显示的文件;

不正确的错误消息处理

不正确的错误消息处理(Error Handling Vulnerability) 的安全漏洞是指,Web 应用的错误信息内包含对攻击者有用的信息。主要包括:

  • Web 应用抛出的错误消息;
  • -数据库等系统抛出的错误消息;
  • PHP 或 ASP 等脚本错误;
  • 数据库或中间件的错误;
  • Web 服务器的错误;

开放重定向

开放重定向(Open Redirect) 是一种对指定的任意 URL 作重定向跳转的功能。而与此功能相关联的安全漏洞是指,假如指定的重定向 URL 到某个具有恶意的 Web 网站,那么用户就会被诱导至那个 Web 网站。

可信度高的 Web 网站如果开放重定向功能,则很有可能被攻击者选中并用来作为钓鱼攻击的跳板。

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

会话劫持

会话劫持(Session Hijack) 是指攻击者通过某种手段拿到了用户的会话 ID,并非法使用此会话 ID 伪装成用户,达到攻击的目的。

攻击者可获得会话 ID 的途径有:

  • 通过非正规的生成方法推测会话 ID;
  • 通过窃听或 XSS 攻击盗取会话 ID;
  • 通过会话固定攻击(Session Fixation)强行获取会话 ID;

会话固定攻击

对以窃取目标会话 ID 为主动攻击手段的会话劫持而言,会话固定攻击(Session Fixation) 攻击会强制用户使用攻击者指定的会话 ID,属于被动攻击。

跨站点请求伪造

跨站点请求伪造(Cross-Site Request Forgeries,CSRF) 攻击是指攻击者通过设置好的陷阱,强制对已完成认证的用户进行非预期的个人信息或设定信息等某些状态更新,属于被动攻击。

可能会造成的影响:

  • 利用已通过认证的用户权限更新设定信息等;
  • 利用已通过认证的用户权限购买商品;
  • 利用已通过认证的用户权限在留言板上发表言论;

其他安全漏洞

密码破解攻击

密码破解攻击(Password Cracking) 即算出密码,突破认证。

密码破解有以下两种手段:

  • 通过网络的密码试错;
  • 对已加密密码的破解(指攻击者入侵系统,已获得加密或散列处理的密码数据的情况);

通过网络的密码试错的方法主要有:

  • 穷举法(Brute-force Attack,又称暴力破解法)是指对所有密钥集合构成的密钥空间(Keyspace)进行穷举。
  • 字典攻击是指利用事先收集好的候选密码(经过各种组合方式后存入字典),枚举字典中的密码,尝试通过认证的一种攻击手法。

对已加密密码的破解的方法主要有:

  • 通过穷举法和字典攻击进行类推;
  • 彩虹表;
  • 拿到密钥;
  • 加密算法的漏洞;

彩虹表(Rainbow Table)是由明文密码及与之对应的散列值构成的一张数据库表,是一种通过事先制作庞大的彩虹表,可在穷举法·字典攻击等实际破解过程中缩短消耗时间的技巧。

点击劫持

点击劫持(Click jacking)是指利用透明的按钮或链接做成陷阱,覆盖在 Web 页面之上。然后诱使用户在不知情的情况下,点击那个链接访问内容的一种攻击手段。这种行为又称为界面伪装(UI Redressing)。

DoS 攻击

DoS 攻击(Denial of Service attack) 是一种让运行中的服务呈停止状态的攻击。有时也叫做服务停止攻击或拒绝服务攻击。DoS 攻击的对象不仅限于 Web 网站,还包括网络设备及服务器等。

攻击方式主要有:

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

多台计算机发起的 DoS 攻击称为 DDoS 攻击(Distributed Denial of Service attack)

后门程序

后门程序(Backdoor) 是指开发设置的隐藏入口,可不按正常步骤使用受限功能。