以下内容为阅读《图解HTTP》的时候整理的关键性信息,用以加深理解
首先总所周知,HTTP是建立在TCP/IP之上的,也就是说,HTTP是TCP/IP的一个子集。
TCP/IP分四层:应用层、传输层、网络层、数据链路层。
而网络是分七层协议:7 应用层 6 表示层 5 会话层 4 传输层 3 网络层 2 数据链路层 1 物理层
IP协议:把各种数据包传送给对方,而要保证确认一定能传送到对方。需要满足各类条件。其中最重要的就是IP地址和MAC地址
TCP协议:TCP位于传输层,提供可靠的字节流服务。字节流就是为了方便的传输,将大块的数据分割成以报文的方式传输,而可靠的传输服务就是把数据准确的可靠的传输给对方。总结就是TCP协议为了更容易传送大数据才把数据分割,而且TCP协议能够确认数据最终是否送达对方。
此处主要是HTTP/1.1版本
HTTP 协议规定,请求从客户端发出,最后服务器端响应该请求并返回。换句话说,肯定是先从客户端开始建立通信的,服务器端在没有接收到请求之前不会发送响应。
POST /form/entry HTTP/1.1 # 分别表示 方法、URL、协议版本
Host: xxx.com #host、connection、content-type、content-length请求体
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 16
name #内容实体
HTTP/1.1 200 OK
Date: Tue, 10 Jul 2012 06:50:15 GMT
Content-Length: 362
Content-Type: text/html
...
HTTP协议是无状态的。HTTP协议自身不对请求和响应的状态进行保存。
登陆状态其实是基于Cookie或者Session的,Cookie是客户端的,而Session是服务器端的。
请求/响应 | 描述 |
---|---|
请求 | GET /index.html HTTP/1.1 Host: www.hackr.jp If-Modified-Since: Thu, 12 Jul 2012 07:30:00 GMT |
响应 | 仅返回2012年7 月12日7 点30分以后更新过的index.html页面资源。如果未有内容更新,则以状态码304 Not Modified作为响应返回 |
请求/响应 | 描述 |
---|---|
请求 | POST /submit.cgi HTTP/1.1 Host: www.hackr.jp Content-Length: 1560(1560字节的数据) |
响应 | 返回 submit.cgi 接收数据的处理结果 |
PUT:传输数据,提交数据,推送数据,传输文件等
HEAD:获取报文头部
HEAD 方法和 GET 方法一样,只是不返回报文主体部分。用于确认URI 的有效性及资源更新的日期时间等。
DELETE:删除数据
DELETE 方法用来删除文件,是与 PUT 相反的方法。DELETE 方法按请求 URI 删除指定的资源。
OPTIONS:询问支持的方法
请求/响应 | 描述 |
---|---|
请求 | OPTIONS * HTTP/1.1 Host: www.hackr.jp |
响应 | HTTP/1.1 200 OK Allow: GET, POST, HEAD, OPTIONS(返回服务器支持的方法) |
整理各个方法在HTTP/1.0和HTTP/1.1支持情况
方法 | 说明 | 支持的 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 |
每个请求都是一个 建立TCP连接 -> HTTP请求/响应 -> 断开TCP连接
,而随着网页越来越多请求,带宽和响应时间都加大了,那么需要持久连接HTTP keep-alive
。特点是:只要任意一端没有明确断开连接,则保持TCP连接状态
为了让HTTP保存状态信息,引入了Cookie概念
GET /reader/ HTTP/1.1
Host: xxx.com
HTTP/1.1 200 OK
Date: Thu, 12 Jul 2018 07:12:20 GMT
Server: Apache
<Set-Cookie: sid=1342077140226724; path=/; expires=Wed,
10-Oct-12 07:12:20 GMT>
Content-Type: text/plain; charset=UTF-8
GET /image/ HTTP/1.1
Host: xxx.com
Cookie: sid=1342077140226724
请求报文和响应报文的头部内容由以下数据组成。
请求行
包含用于请求的方法,请求URI和HTTP版本
状态行
包含表明响应结果的状态码,原因短语和HTTP版本
头部字段
包含表示请求和响应的各种条件和属性的各类头部。
一般有4种头部,分别是:通用头部、请求头部、响应头部和实体头部
其他
可能包含HTTP的RFC里面未定义的头部(Cookie等)
可以通过编码的方式提升传输速率,但是编码的时候,会消耗CPU的资源
内容编码,主要有以下几种编码方式:
HTTP协议中采用了多部分对象集合,发送一份报文主体可能含有多类型实体。用的最多的就是图片和文本文件中的上传中使用
当需要请求一个很大的图片,或者文件的时候。如果下载过程中遇到网络中断,原则上是必须重新开始。为了解决上面的问题,需要一种可恢复的机制。所谓恢复是指能从之前下载中断处恢复下载。
要实现这种功能,需要指定下载的实体范围。范围请求
byte范围的指定形式:
Range: bytes=5001-10000
Range: bytes=5001-
Range: bytes=-3000, 5000-7000
HTTP状态码负责表示客户端的HTTP请求的返回结果、标记服务器端的处理是否正常、通知出现的错误等工作。借助状态码,用户可以知道服务器端是正常处理了请求,还是出现错误。
状态码的类别
|状态码| 类别| 描述说明|
|1XX|信息性状态码|接收的请求正在处理|
|2XX|成功状态码|请求正常处理完毕|
|3XX|重定向状态码|需要进行附加操作以完成请求|
|4XX|客户端错误状态码|服务器无法处理请求|
|5XX|服务器错误状态码|服务器处理请求出错|
HTTP头部字段结构
HTTP头部字段是由头部字段名和字段值构成的,中间用冒号:
分隔
头部字段名:字段值
如:Coontent-Type: text/html
、Keep-Alive: timeout=15, max=100
4种HTTP头部字段类型
HTTP头部根据实际用途分为四种类型
头部字段名 | 说明 |
---|---|
Cache-Control | 控制缓存的行为 |
Connection | 逐跳头部、链接的管理 |
Date | 创建报文的日期时间 |
Pragma | 报文指令 |
Trailer | 报文末端的头部一览 |
Transfer-Encoding | 指定报文body的传输编码方式 |
Upgrade | 升级为其他协议 |
Via | 代理服务器的相关信息 |
Warning | 错误通知 |
头部字段名 | 说明 |
---|---|
Accept | 用户代理可处理的媒体类型 |
Accept-Charset | 优先的字符集 |
Accept-Encoding | 优先的内容编码 |
Accept-Language | 优先的语言 |
Authorization | Web认证信息 |
Expect | 期待服务器的特定行为 |
From | 用户所在的电子邮箱地址 |
Host | 请求资源所在服务器 |
If-Match | 比较实体标记(ETag) |
If-Modified-Since | 比较资源的更新时间 |
If-None-Match | 比较实体标记 |
If-Range | 资源未更新的时候发送实体Byte的范围请求 |
If-Unmodified-Since | 比较资源的更新时间 |
Max-Forwards | 最大传输跳数 |
Proxy-Authorization | 代理服务器要求客户端的认证信息 |
Range | 实体的字节范围请求 |
Referer | 对请求中URI的原始获取方 |
TE | 传输编码的优先级 |
User-Agent | HTTP客户端程序的信息 |
头部字段名 | 说明 |
---|---|
Accept-Ranges | 是否接受字节范围请求 |
Age | 推算资源创建经过时间 |
ETag | 资源的匹配信息 |
Location | 令客户端重定向至指定URI |
Proxy-Authenticate | 代理服务器对客户端的认证信息 |
Retry-After | 对再次请求的时机要求 |
Server | HTTP服务器的安装信息 |
Vary | 代理服务器缓存的管理信息 |
WWW-Authenticate | 服务器对客户端的认证信息 |
Allow | 资源科支持的HTTP方法 |
Content-Encoding | 实体主体使用的编码方式 |
Content-Language | 内容主体的语言 |
Content-Length | 内容主体的大小 |
Content-Location | 替代对应资源的URI |
Content-MD5 | 主体的报文摘要 |
Content-Range | 主体的位置范围 |
Content-Type | 主体媒体类型 |
Expires | 过期时间 |
Last-Modified | 资源的最后修改日期 |
缓存请求指令
指令 | 参数 | 说明 |
---|---|---|
no-cache | 无 | 强制向源服务器再次验证 |
no-store | 无 | 不缓存请求或者响应的任何内容 |
max-age=[秒] | 必需 | 响应的最大Age值 |
max-fresh=[秒] | 必需 | 期望在指定时间内的响应仍然有效 |
no-transform | 无 | 代理不可更改媒体类型 |
only-if-cached | 无 | 从缓存获取资源 |
cache-extension | - | 新指令标记 |
缓存响应指令
指令 | 参数 | 说明 |
---|---|---|
public | 无 | 可向任意方提供响应的缓存 |
private | 可省略 | 仅向特定用户返回响应 |
no-cache | 可省略 | 缓存前必须先确认其有效性 |
no-store | 无 | 不缓存请求或响应的任何内容 |
no-transform | 无 | 代理不可更改媒体类型 |
must-revalidate | 无 | 可缓存但必须再向源服务器进行确认 |
max-age=[秒] | 必需 | 响应的最大Age值 |
s-maxage=[秒] | 必需 | 公共缓存服务器响应的最大Age值 |
cache-extension | - | 新指令标记 |
在HTTP协议中有可能存在信息窃听和身份伪装等安全问题。使用HTTPS通信机制可以有效防止这些问题。
HTTP主要有这些不足,例举如下:
可以使用抓包工具Wireshark
,可以获取HTTP协议的请求和响应的内容,对其进行解析
加密处理防止被窃听
可以使用HTTPS,通过使用SSL的HTTP成为HTTPS
不验证通信方的身份可能遭遇伪装
HTTP的协议中的请求和响应不会对通信方进行确认。也就是说存在服务器是否就是发送请求中的URI真正指定的主机,可能出现任何人都可以发起请求
,无法判断请求是来自何方、出自谁手
无法证明报文完整性,有可能已经被篡改
如果防止篡改,可以通过MD5或者SHA-1等散列值校验的方法,用来确认文件的数字签名方法
WebSocket,即Web浏览器与Web服务器之间全双工通信标准。WebSocket技术主要是为了解决Ajax和Comet里面的XMLHttpREquest附带的缺陷所引起的问题
特点
推送功能
支持由服务器向客户端推送数据的推送功能,这样服务器可直接发送数据,而不需要等客户端的请求
减少通信量
只要建立起WebSocket,就希望一直保持连接状态
WebSocket API
下面是调用WebSocket API,每50ms发送一次数据:
var socket = new WebSocket('ws://xxx.com:12010/xxx');
socket.onopen = function() {
setInterval(function() {
if(socket.bufferedAmount == 0) {
socket.send(getUpdateData());
}
}, 50);
}
HTTP协议本身并不存在安全性问题,因为协议本身不会成为攻击的对象。但是HTTP比较简单,所以运用广泛,所以很多人用来攻击
从攻击手段来说,有两个,主动攻击
和被动攻击
主动攻击:主动攻击是通过直接访问WEB应用,把攻击代码传入的攻击模式。由于该模式是直接针对服务器上的资源进行攻击,因此攻击者需要能够访问到那些资源,比如最常见的SQL注入攻击
、OS命令攻击
http://xxx.com/login?ID=
用户还可以通过脚本窃取到Cookie信息,用来攻击
Web应用通常会用到数据库,当需要对数据库表内的数据进行检索或者添加、删除等操作的时候,会使用SQL语句链接数据库进行特定的操作
如最典型的登录,SQL注入如下:
select id,user_name from sys_user where user_name='xxx' and password= ' ' or '1'='1'
用户在浏览器只需要在用户名那里随便输入什么东西,密码输入' or '1'='1
即可达到SQL注入的效果
OS命令注入攻击
OS命令注入是指当调用某些特定的程序的时候,系统触发了系统命令,导致严重的后果,如程序直接调用了rm
命令,造成非常严重的后果。
HTTP头部攻击
头部攻击就是用户自己输入任意的地址,这个地址触发了后台功能,比如我们有个删除功能是/sysuser?delete=1
,如果后台没有设置权限校验,用户自己输入某个id,这个id是另外的用户,而业务上本身用户不应该具备这个能力,这个时候数据直接删了,后果很严重
主要有这些影响:设置任何Cookie信息
、重定向至任意URL
正常情况:
http://xxx.com/xxx.jsp?log=0401.log
攻击者攻击如下:
http://xxx.com/xxx.jsp=log=.././etc/passwd
如果这个用户有权限的话,刚好就有公开的风险!
http://xxx.com/?redirect=http://www.xxxx.com
如果用户发现了,那么可以改成另外的:
http://xxx.com/?redirect=http://aaa.com