《图解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响应只包含了部分数据时使用
- multipart/form-data 表单文件上传,用boundary字符
- 部分发送
- 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建立连接的过程包括:
- 协商决定秘钥组件
- 服务端发送公开密钥、证书
- 客户端检查证书合法性,以确认服务端身份,并拿到公钥
- 客户端发送pre-master secret随机字符串
- 服务端使用私钥加密pre-master secret hash值,返回加密的hash值(避免黑客尝试破解私钥)
- 客户端使用公钥解密hash,对比自己之前生成的pre-master secret字符串hash,若一致,及证明服务端身份的合法性
- 客户端生成一个对称加密算法和秘钥master-secret,使用公钥加密,发送给服务端
- 双方使用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。
- 后门程序