《图解HTTP》整理

读完了《图解HTTP》,就算是对计算机网络和HTTP部分内容做了个温习吧。同步做了整理,以便加强记忆和后面回顾。

概述

请求报文构成:

  • 方法
  • URI(绝对或是相对)
  • HTTP版本
  • 请求首部
  • 内容实体

响应报文构成:

  • HTTP版本号
  • 状态码
  • 状态码原语
  • 响应头部
  • 响应主体

请求URI是服务器本身时,可以用*代替URI。

可用的方法列表:

  • GET 获取资源
  • POST 传输信息
  • PUT 传输文件,没有用户验证机制,很少用到
  • DELETE 删除文件,同上,很少用到
  • HEAD 获得响应头部,不返回主体
  • OPTIONS 询问支持方法
  • CONNECT 用来建立HTTPS连接的隧道
  • TRACE 追踪路径上的所有服务器节点,很少用到

其中后面三个是HTTP1.1才开始支持的。

持久化

在HTTP1.1后,HTTP建立的TCP连接默认是长连接(keep-alive),避免不必要的多次TCP握手和挥手。在此基础上,客户端可以同时向服务端发起多个资源请求。

状态化

HTTP本身是无状态的。通过cookie实现状态化,cookie通过服务端在响应头部的set-cookie字段下发,设置信息、使用范围、过期时间等内容。客户端在使用范围内的请求默认会携带上cookie信息。

HTTP报文结构

  • 请求首部和主体通过CR+LF分割开来
  • 报文编码
    • 编码压缩
      • gzip (GNU zip)
      • compress(UNIX compress)
      • deflate(zlib)
      • indentity(不压缩)
    • 分块发送
    • 多部分发送(multipart)
      • multipart/form-data 表单文件上传,用boundary字符--表示新的part的开始
      • multipart/byterange 配合206响应只包含了部分数据时使用
    • 部分发送
      • Range指定字节范围
      • 206响应状态码
  • 内容协商
    • 双方就合适的语言、字符集、编码方式、过期时间进行协商

HTTP状态码

  • 1xx 这一类型的状态码,代表请求已被接受,需要继续处理
    • 100 Continue:客户端应当继续发送请求。
    • 101 Switching Protocals:将通过Upgrade消息头通知客户端采用不同的协议来完成这个请求。
  • 2xx 成功:这一类型的状态码,代表请求已成功被服务器接收、理解、并接受。
    • 200 OK:请求已成功,在方法时HEAD时不返回响应主体
    • 204 No Content:服务器成功处理了请求,但不需要返回任何实体内容,用户浏览器应保留发送了该请求的页面
    • 205 Reset Content:和204的唯一不同是返回此状态码的响应要求请求者重置文档视图
    • 206 Partial Content:服务器已经成功处理了部分GET请求。请求必须包含Range头信息来指示客户端希望得到的内容范围,返回使用Content-Range多用于下载工具
  • 3xx 重定向:这类状态码代表需要客户端采取进一步的操作才能完成请求。通常,这些状态码用来重定向,后续的请求地址在本次响应的Location域中指明。
    • 300 Multiple Choices:被请求的资源有一系列可供选择的回馈信息,每个都有自己特定的地址和浏览器驱动的商议信息。用户或浏览器能够自行选择一个首选的地址进行重定向。
    • 301 Moved Permanently:被请求的资源已永久移动到新位置,建议使用Location中的新地址
    • 302 Found:请求的资源现在临时从不同的URI响应请求
    • 303 See Other:和302的区别是,客户端应当采用GET的方式访问新的资源
    • 304 Not Modified:如果客户端发送了一个带条件(包括缓存相关的请求头部)的GET请求且该请求已被允许,而文档的内容(自上次访问以来或者根据请求的条件)并没有改变
    • 305 Use Proxy:被请求的资源必须通过指定的代理才能被访问
  • 4xx 客户端错误:客户端发生了错误
    • 400 Bad Request:由于包含语法错误,当前请求无法被服务器理解
    • 401 Unauthorized:当前请求需要用户验证,或用户未通过验证。
    • 403 Forbidden:服务器已经理解请求,但是拒绝执行它
    • 404 Not Found:资源未被在服务器上发现
    • 405 Method Not Allowed:请求行中指定的请求方法不能被用于请求相应的资源,响应中必须返回一个Allow头信息用以表示出当前资源能够接受的请求方法的列表
    • 406 Not Acceptable:请求的资源的内容特性无法满足请求头中的条件
    • 413 Request Entity Too Large
    • 414 Request-URI Too Long
  • 5xx 服务器错误:服务器在处理请求的过程中有错误发生
    • 500 Internal Server Error:这个问题会在服务器的代码出错时出现
    • 501 Not Implemented:服务器不支持当前请求所需要的某个功能
    • 502 Bad GateWay:作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应
    • 503 Service Unavailable:临时的服务器维护或者过载。这个状况是临时的,并且将在一段时间以后恢复。
    • 504 Gateway Timeout:作为网关或者代理工作的服务器尝试执行请求时,未能及时从上游服务器或者辅助服务器收到响应

协作机制

  • 代理(Proxy),单纯转发HTTP请求,会在响应头部的Via字段留下痕迹
  • 网关(Gateway),隔绝服务器和客户端,有安全、计费等逻辑
  • 隧道(tunnel),基于协议搭建,保证传输安全,对用户侧透明
  • 缓存(Cache),本地、服务端二级缓存,加快响应时间,有过期时间

报文头部

  • 首部用来进行连接的各种信息描述。每个首部的字段用字段名和值组成,两者用:隔开。
  • 首部分为端到端和逐跳两类,前者在报文转发的整个过程都保留,后者在转发后就会丢弃。典型的逐条首部有Connection, Keep-Alive, Transfer-Encoding, Upgrade

通用首部

Cache-Control

客户端和服务端协商缓存机制。配合下面一些首部字段使用:

  • Etag
  • Last-Modified
  • Expires(HTTP1.0)
  • Pragma(HTTP1.0)
  • Age(HTTP1.0)
  • If-None-Match
  • If-Not-Modified-Since

Cache-Control有下面一些可配置项。

缓冲能力上,

  • private,缓存只针对当前用户而言
  • public,缓存对所有用户生效
  • no-cache,始终对缓存进行过期验证
  • no-store,不允许缓存

过期时间上,

  • min-fresh,返回指定时间范围内的非过期资源
  • max-stale,返回指定时间范围内过期、非过期资源
  • max-age,单位:秒,最大缓存时间
  • s-max-age,同上,只用于CDN缓存

二次验证上,

  • only-if-cached,强制从缓存服务器中获取内容
  • immutable,一旦缓存不可更改
  • must-revalidate,即使本地已缓存,仍要求检查CDN缓存
  • proxy-revalidate,缓存服务器必须检查源内容是否改变

Connection

管理连接,主要有两个用途。

  • 指定不希望转发给代理的字段
  • 管理持久连接。使用Connection: Keep-Alive建立连接(HTTP1.1默认行为),使用Connection: Close终止连接

Date

报文创建时间。行如“Date: Tue, 03 Jul 2012 04:31:12 GMT”

Pragma

历史遗留字段。Pragma: no-cache等同于Cache-Control: no-cache

除此外还有:

  • Trailer,说明报文主体中记录的首部字段
  • Transfer-Encoding,分段传输的主体编码
  • Upgrade,切换协议,配合Connection: Upgrade使用
  • Via,标明沿途的整条路径
  • Warning,缓存相关警告

请求首部

  • Accept 接受文件的类型,类型间可以指定q=x表示权重值,x的取值在0到1之间。下同
  • Accept-Charset 可以接受的文件字符集
  • Accept-Encoding 可以接受的文件编码,有gzip,compress,deflate,indentity几种
  • Accept-Language 可接受的语言
  • Authorization 服务端需要的用户验证信息
  • Age 从缓存实体产生到现在经历的时间
  • Expect 期望的服务端返回状态码,服务端无法满足时返回417状态码,客户端等待服务端100响应时发送的请求都要带上该字段
  • Host 服务器的主机名,通常是请求资源的URL
  • If-Match 需要匹配的Etag,不满足时返回412,表示不满足条件
  • If-Modified-Since 返回指定日期后的新内容,否则返回304
  • If-Unmodified-Since 类似上
  • If-Range 类似If-Match不过是范围匹配
  • Max-Forwards 报文最多转发次数,通常配合TRACE方法使用
  • Proxy-Authorization 代理服务端需要的用户验证信息
  • Range 请求资源的部分内容,一般用在多线程下载(客户端发起)
  • Referer 当前请求从哪个地址发起
  • User-Agent 请求发起终端信息

响应首部

  • Accept-Ranges,表示服务器是否支持Range请求,支持时值为bytes,否则是none
  • Age,表示缓存到目前为止过了多久(HTTP1.0)
  • Etag,资源的唯一标识,分为强Etag和弱Etag
  • Location,用在3xx的请求中,表示客户端需要重定向到的新地址
  • WWW-Authentication/Proxy-Authentication,服务器、代理使用的认证类型
  • Server,服务器信息
  • Vary,与Vary指定首部字段同名的请求才会命中缓存

实体首部

  • Allow 允许的访问方法
  • Content-Encoding/Content-Language/Content-Length/ 内容的编码、语言、长度、类型
  • Content-Location 内容的位置,通常在和访问URI时会用到
  • Content-MD5 内容MD5编码,便于和客户端编码后进行对比,防止内容篡改
  • Content-Range 用于部分请求
  • Content-Type 文件类型,包括MIME type和字符集
  • Expires/Last-Modified 文件的过期时间和上次修改时间,用户判断缓存是否过期

除此之外,还有和Cookie相关的两个头部,它们来自网景公司对于Cookie的设计。

  • Set-Cookie,服务端下发设置Cookie信息。包含下列信息
    • expires,过期时间
    • path,适用路径
    • domain,适用域名
    • secure,限制https才会携带Cookie
    • HttpOnly,限制JS脚本访问Cookie
    • 下发的cookie内容
  • Cookie,客户端期望的cookie内容

另外还有一些常用的首部字段:

  • X-Frame-Options,规定页面在iframe中的呈现方式
    • DENY 禁止访问
    • SAMEORIGIN 仅允许同源访问
  • X-XSS-Protection,为1时开启XSS防御

不建议使用”X-“开头的方式拓展非标准首部

HTTPS简介

HTTP缺点:

  • 使用明文 -> 通信内容可以被窃听 –HTTPS–> 加密通信内容
  • 不能验证身份 -> DDoS攻击和伪装服务器、客户端身份 –HTTPS–> 证书证明身份
  • 不能验证内容完整性 -> 中间人攻击 –HTTPS–> HTTPS保证完整性

HTTPS特征:

  • 加密内容
  • 证书
  • 完整性保护

HTTPS建立在SSL连接之上,SSL建立在TCP连接上。SSL使用共享秘钥和公开秘钥加密两种方式混合加密。在秘钥确保安全的情况下,使用共享秘钥对称加密,优化速度;否则使用公开秘钥确保安全性。

  • 共享秘钥,双方使用同一秘钥加密和解密,秘钥被监听后加密就失去了意义
  • 公开秘钥,使用公开秘钥加密,使用私有秘钥解密

然而公开密钥本身并不能确保完整性,需要证书机构(CA)颁发证书认证,确保秘钥和端的有效以及合法性。服务端也可以使用OpenSSL为自己颁发自认证证书,但是一般会在浏览器上弹出警告。

HTTPS建立连接的过程包括:

  1. 协商决定秘钥组件
  2. 服务端发送公开密钥、证书
  3. 客户端检查证书合法性,以确认服务端身份,并拿到公钥
  4. 客户端发送pre-master secret随机字符串
  5. 服务端使用私钥加密pre-master secret hash值,返回加密的hash值(避免黑客尝试破解私钥)
  6. 客户端使用公钥解密hash,对比自己之前生成的pre-master secret字符串hash,若一致,及证明服务端身份的合法性
  7. 客户端生成一个对称加密算法和秘钥master-secret,使用公钥加密,发送给服务端
  8. 双方使用master-secret进行通信

通信的完整性可以通过将报文内容生成hash交由客户端验证来实现。

SSL最初由网景开发,1.0和2.0版本被发现存在问题已被废弃。3.0后由IETF接手。目前可用的协议版本有SSL3.0和TLS1.0、TLS1.1、TLS1.2,其中最常用的是SSL3.0和TLS1.0。

证书

证书包含:

  • 发布机构(CA)
  • 有效期
  • 持有者(由CA担保证明持有者身份)
  • 公钥
  • 数字签名算法
  • 指纹算法

为了保证安全,在证书的发布机构发布证书时,证书的指纹和指纹算法,都会用自己的私钥加密后再和证书放到一起发布。使用者在打开证书时,根据加密算法,系统使用自带的公钥解密指纹和指纹算法,使用指纹算法计算证书的hash值和指纹对比,如果对的上就代表证书没问题。系统使用的公钥和证书一般由证书发布机构自己生成,内嵌在操作系统中。

证书颁发机构(CA)通常会去做很多工作确保持有者的合法性,信任CA代表着信任CA颁发证书中的所有信息。所以一般系统只选择信誉较好的CA机构。公司内部使用或自生成的证书就只能被在指定范围内被信任。

身份验证

  • BASIC 使用用户名密码验证,明文传输
  • DIGEST 质询响应,防止密码被拦截,安全度和便利性都较差
  • SSL 客户端证书 + HTTPS传输,成本高
  • HTTP表单 + Cookie/Session验证

功能追加协议

WebSocket

全双工,解决Ajax,长短轮询的局限。握手过程很简单:

  • 请求方添加Upgrade首部字段,声明升级到websocket。包含Sec-WebSocket-Key,Sec-WebSocket-Protocol,Sec-WebSocket-Verison等必要字段
  • 响应方回复101状态码,包含Sec-WebSocket-Accept(是根据Sec-WebSocket-Key生成的),Sec-WebSocket-Protocol

连接建立后,双方使用WebSocket的方式进行通信

WebDAV

基于Web的文件属性管理。新增了一些方法和状态码,允许客户端远程修改服务器上的文件。

Web应用

RSS

RDF Site Summary,简易内容聚合。和Atom一样,使用XML的形式发布信息,通过特定的RSS阅读器阅读。

常见Web攻击方式

根本原因:HTTP本身没有必要的安全机制。

输出值转义相关攻击方式

  • XSS,跨站脚本攻击,主要出现在动态拼接HTML的场景中,用户恶意注入的script代码段埋下陷阱,诱导用户误操作触发。盗取用户密码或Cookie信息
  • SQL注入,通过URL注入的方式,制造恶意SQL语句,出现在动态拼接SQL语句的场景下。可以绕过认证、甚至破坏整个数据库
  • OS命令注入,类似SQL注入,出现在动态拼接OS语句的场景下。
  • HTTP首部攻击,出现在服务端响应头部使用了用户侧输入场景下,比如302响应中的Location头部可能存在的query部分。攻击者可以通过添加换行符,恶意添加新的首部字段,甚至篡改原有的响应主体
  • 邮箱首部注入攻击,类似HTTP首部攻击

类似地还有目录遍历漏洞、远程文件引用漏洞。

通过上面几种攻击方式,可以看到,永远不要信任用户侧输入使用白名单机制,禁止动态拼接用户输入的语句

设计缺陷相关攻击方式

  • 强制浏览,在服务器公开目录下,浏览开发者本非自愿公开的文件。
  • 不正确的系统错误处理方式,数据库等内部系统抛出的错误,对用户毫无帮助,反倒能让攻击者看到服务背后的一些细节。包括,数据库错误、PHP等脚本错误、Web服务器的错误
  • 开放重定向,网站有诸如?redirect=xxx的path可以重定向时,一定要对redirect后的网址进行白名单控制,防止成为钓鱼攻击的跳板

session相关

  • XSS盗取cookie,伪装用户登录
  • 发送恶意链接,强制用户使用攻击者指定的session ID
  • CSRF,跨站信息伪造,在带有用户信息的domain里留下恶意的网络请求,伪造用户发起请求,伪造请求可以通过<img src="xx" />, <video src="xxx></video>等多种形式

其他

  • 穷举法破解密码,暴力破解。使用图片验证码、手机验证码、机器检测等方式限制同IP的访问频率。
    • 彩虹表。使用salt,增加破解难度
  • 撞库。建议用户在不同域内使用不一样的密码
  • 点击劫持,使用透明元素覆盖在目标网页上。在18+网页中最常出现(😂)。
  • DoS(Denial of Service)拒绝服务攻击,构造大量合法的网络请求,导致服务器超负荷。通常都是DDoS(Distributed Denial of Service)的形式。需要在IP层去过滤攻击的IP。
  • 后门程序