《图灵程序设计丛书:图解HTTP》对互联网基盘——HTTP协议进行了全面系统的介绍。作者由HTTP协议的发展历史娓娓道来,严谨细致地剖析了HTTP协议的结构,列举诸多常见通信场景及实战案例,最后延伸到Web安全、全新技术动向等方面。
《图解HTTP》的特色为在讲解的同时,辅以大量生动形象的通信图例,更好地帮助读者深刻理解HTTP通信过程中客户端与服务器之间的交互情况。读者可通过《图灵程序设计丛书:图解HTTP》快速了解并掌握HTTP协议的基础,前端工程师分析抓包数据,后端工程师实现REST API、实现自己的HTTP服务器等过程中所需的HTTP相关知识点本书均有介绍。
《图灵程序设计丛书:图解HTTP》适合Web开发工程师,以及对HTTP协议感兴趣的各层次读者。
¶ 书籍信息
出版社 | ISBN | 出版时间 | 分类 |
---|---|---|---|
人民邮电出版社 | 9787115351531 | 2014-05-01 | 计算机/网络与通信 |
¶ 作者简介
上野·宣 ,OWASP 日本分会会长,TRICORDER株式会社董事长。
主要从事安全咨询、风险评估、信息安全教育等工作。著有《今晚我们一起学习邮件协议》(今夜わかるメールプロトコル)、《今晚我们一起学习TCP/IP》(今夜わかるTCP/IP)、《今晚我们一起学习HTTP》(今夜わかるHTTP)。担任The Tangled Web:A Guide to Securing Modern Web Application日文版的审校工作。
于均良(译者),上海交通大学硕士,高级软件工程师,马拉松跑者,四点网创始人。
¶ 读书笔记
¶ 使用HTTP协议访问Web
¶ TCP/IP协议与Http协议的区别
TPC/IP协议是传输层协议,主要解决数据如何在网络中传输,而HTTP是应用层协议,主要解决如何包装数据。
我们在传输数据时,可以只使用(传输层)TCP/IP协议,但是那样的话,如果没有应用层,便无法识别数据内容,如果想要使传输的数据有意义,则必须使用到应用层协议,应用层协议有很多,比如HTTP、FTP、TELNET等,也可以自己定义应用层协议。WEB使用HTTP协议作应用层协议,以封装HTTP 文本信息,然后使用TCP/IP做传输层协议将它发到网络上。
术语TCP/IP代表传输控制协议/网际协议,指的是一系列协议。“IP”代表网际协议,TCP和UDP使用该协议从一个网络传送数据包到另一个网络。把IP想像成一种高速公路,它允许其它协议在上面行驶并找到到其它电脑的出口。TCP和UDP是高速公路上的“卡车”,它们携带的货物就是像HTTP,文件传输协议FTP这样的协议等。
你应该能理解,TCP和UDP是FTP,HTTP和SMTP之类使用的传输层协议。虽然TCP和UDP都是用来传输其他协议的,它们却有一个显著的不同:TCP提供有保证的数据传输,而UDP不提供。这意味着TCP有一个特殊的机制来确保数据安全的不出错的从一个端点传到另一个端点
,而UDP不提供任何这样的保证。
HTTP(Hypertext Transfer Protocol,超文本传输协议)是利用TCP在两台电脑(通常是Web服务器和客户端)之间传输信息的协议。客户端使用Web浏览器发起HTTP请求给Web服务器,Web服务器发送被请求的信息给客户端。
¶ 三次握手(three-way handshaking)确保数据能到达目标
¶ HTTP报文传递过程
¶ URL和URI的区别
URL(Uniform Resource Locator)是使用web浏览器访问web页面时所输入的网页地址。
URI(Uniform Resource Identifier)是由某个协议方案表示的资源的定位标识符。协议方案是指访问资源所使用的协议类型名称。采用HTTP协议时,协议方案就是HTTP。
在充分理解的基础上,也可以用URL替换URI。
http://user:pass@www.example.com:80/dir/index.html?uid=1#ch1
- http:// 协议方案名
- user:pass 登录信息(认证)
- www.example.com 服务器地址
- 80 服务器端口号
- dir/index.html 带层次的文件路径
- uid=1 查询字符串
- ch1 片段标识符
URI举例
- ftp://ftp.example.com/rfc/1808.txt
- http://www.example.com/rfc/1808.txt
- ldap://[2001:db8::7]/c=GB?objectClass?one
- mailto:test@example.com
- news:comp.infosystems.www.servers.unix
- tel:+86-010-37768899
- telnet://192.168.1.168:80
- urn:oasis:names:specification:docbook:dtd:xml:4.1.2
¶ HTTP请求和响应的报文内容
¶ HTTP请求方法
方法 | 说明 |
---|---|
GET | 获取资源 |
POST | 传输实体主体 |
PUT | 传输文件 |
HEAD | 获取报文首部 |
DELETE | 删除文件 |
OPTIONS | 询问支持的方法 |
TRACE | 追踪路径 |
CONNECT | 要求用隧道协议连接代理 |
¶ HTTP协议不保存状态
HTTP协议自身不对请求和响应之间的通信状态进行保存。也就是说在HTTP这个级别,协议对于发送过的请求和响应都不做持久化处理。
但是要求认证的页面本身无法进行状态管理,每次跳转新页都要再次登录,或者加参数来管理登录状态。于是HTTP协议中引入了Cookie技术来解决这个问题。
¶ HTTP持久连接
HTTP协议的初始版本中,每进行一次HTTP通信就要断开一次TCP连接,但是浏览一个包含多张图片的html页面时,在发送访问请求html页面资源的同时,也会请求html页面中包含的其他资源。每次请求每次断开就会造成无谓的通信开销。所以HTTP/1.1协议中加入了持久连接(HTTP Persistent Connections,也被称为HTTP keep-alive或HTTP connectionreuse),只要任意一端没有明确提出断开连接,则保持TCP连接状态。
持久连接使多数请求以管线化(pipelining)方式发送。即同时并发多个请求,而不需要一个接着一个等待响应。比如:当请求一个包含10张图片的html web页面,与挨个连接相比,用持久连接可以让请求更快结束。而管线化技术则比持久连接还要快。请求数越多,时间差就越明显。
¶ HTTP响应状态码
状态码的职责是当客户端向服务端发送请求时,描述返回的请求结果。
根据规范,大约有60余种状态码,实际上常用的大概只有14种,下表只列举常用的。
类别/原因短语 | 说明 | |
---|---|---|
1xx | Informational(信息状态码) | 接收的请求正在处理 |
2xx | Success(成功状态码) | 请求正常处理完毕 |
200 | OK | |
204 | No Content | 请求成功了,但是没有资源可返回 |
206 | Partial Content | 响应报文中包含Content-Range指定的范围的实体内容 (资源的部分内容) |
3xx | Redirection(重定向状态码) | 需要进行附加操作以完成请求 |
301 | Moved Permanently | 永久重定向 |
302 | Found | 临时重定向 |
303 | See Other | 请求对应的资源存在另一个URI, 应使用GET方法定向获取请求的资源 |
304 | Not Modified | 资源已找到,但是未符合条件请求 |
307 | Temporary Redirect | 临时重定向 |
4xx | Client Error(客户端错误状态码) | 服务器无法处理请求 |
400 | Bad Request | 请求报文中存在语法错误 |
401 | Unauthorized | 请求需要通过认证 |
403 | Forbidden | 请求访问资源被拒绝了 |
404 | Not Found | 无法找到资源(也可以在服务端 拒绝请求且不想说明理由时使用) |
5xx | Server Error(服务器错误状态码) | 服务器处理请求出错 |
500 | Internal Server Error | 服务端执行请求时发生了错误 |
503 | Service Unavailable | 服务器暂时处于超负载或正停机维护 |
¶ HTTP首部字段
通用首部字段(General Header Fields)
首部字段名 | 说明 |
---|---|
Cache-Control | 控制缓存的行为 |
Connection | 逐跳首部、连接的管理 |
Date | 创建报文的日期时间 |
Pragma | 报文指令 |
Trailer | 报文末端的首部一览 |
Transfer-Encoding | 指定报文主体的传输编码方式 |
Upgrade | 升级为其他协议 |
Via | 代理服务器的相关信息 |
Warning | 错误通知 |
请求首部字段(Request Header Fields)
首部字段名 | 说明 |
---|---|
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客户端程序的信息 |
响应首部字段(Response Header Fields)
首部字段名 | 说明 |
---|---|
Accept-Ranges | 是否接受字节范围请求 |
Age | 推算资源创建经过实践 |
ETag | 资源的匹配信息 |
Location | 令客户端重定向至指定的URI |
Proxy-Authenticate | 代理服务器对客户端的认证信息 |
Retry-After | 对再次发起请求的时机要求 |
Server | HTTP服务器的安装信息 |
Vary | 代理服务器缓存的管理信息 |
WWW-Authenticate | 服务器对客户端的认证信息 |
实体首部字段(Entity Header Fields)
首部字段名 | 说明 |
---|---|
Allow | 资源可支持的HTTP方法 |
Content-Encoding | 实体主体适用的编码方式 |
Content-Language | 实体主体的自然语言 |
Content-Length | 实体主体的大小(单位:字节) |
Content-Location | 替代对应资源的URI |
Content-MD5 | 实体主体的报文摘要 |
Content-Range | 实体主体的位置范围 |
Content-Type | 实体主体的媒体类型 |
Expires | 实体主体过期的日期时间 |
Last-Modified | 资源的最后修改日期时间 |
其他首部字段
首部字段名 | 说明 |
---|---|
X-Frame-Options | 控制网站内容是否能在其他web网站的Frame标签内显示。 DENY(拒绝)SAMEORIGIN(同源) |
X-XSS-Protection | 控制浏览器XSS防护机制的开关 0:无效 1:有效 |
DNT | Do not Track的简称,意为拒绝个人信息被收集 0:同意被追踪 1:拒绝被追踪 |
P3P | 通过利用P3P(The Platform for Privacy Preferences)技术, 让网站上的个人隐私变成一种仅供程序可理解的形式 |
¶ HTTP缓存
缓存是指代理服务器或客户端本地磁盘内保存的资源副本。理由缓存可以减少对源服务器的访问,因此也就节省了通信流量和通信时间。
缓存不仅可以存在于缓存服务器内,还可以存在客户端浏览器中。浏览器缓存如果有效,就不必再向服务器请求相同的资源了,可以直接从本地磁盘内读取。
Cache-Control的参数说明:Cache-Control: private, max-age=0, no-cache
缓存请求指令
指令 | 参数 | 说明 |
---|---|---|
no-cache | 无 | 强制向源服务器再次验证 |
no-store | 无 | 不缓存请求或响应的任何内容 |
max-age = [秒] | 必需 | 响应的最大Age值 |
max-stale( = [秒]) | 可省略 | 接收已过期的响应 |
min-fresh = [秒] | 必需 | 期望在指定时间内的响应仍有效 |
no-transform | 无 | 代理不可更改媒体类型 |
only-if-cached | 无 | 从缓存获取资源 |
cache-extension | - | 新指定标记(token) |
缓存响应指令
指令 | 参数 | 说明 |
---|---|---|
public | 无 | 可向任意方提供响应的缓存 |
private | 可省略 | 仅向特定用户返回响应 |
no-cache | 可省略 | 缓存前必须先确认其有效性 |
no-store | 无 | 不缓存请求或响应的任何内容 |
no-transform | 无 | 代理不可更改媒体类型 |
must-revalidate | 无 | 可缓存但必须再向源服务器进行确认 |
proxy-revalidate | 无 | 要求中间缓存服务器对缓存的响应有效性再进行确认 |
max-age = [秒] | 必需 | 响应的最大Age值 |
s-maxage = [秒] | 必需 | 公共缓存服务器响应的最大Age值 |
cache-extension | - | 新标记指令(token) |
Cookie服务的首部字段
首部字段名 | 说明 | 首部类型 |
---|---|---|
Set-Cookie | 开始状态管理所使用的Cookie信息 | 响应首部字段 |
Cookie | 服务器接收到的Cookie信息 | 请求首部字段 |
Set-Cookie字段的属性
属性 | 说明 |
---|---|
NAME=VALUE | 赋予Cookie的名称和值(必需项) |
expires=DATE | Cookie的有效期(若不明确指定则默认为浏览器关闭前为止) |
path=PATH | 将服务器的文件目录作为Cookie的适用对象 (若不指定则默认为文档所在的文件目录) |
domain=域名 | 作为Cookie适用对象的域名 (若不指定则默认为创建Cookie的服务器的域名) |
Secure | 仅在HTTPS安全通信时才会发送Cookie |
HttpOnly | 加以限制,使Cookie不能被Javascript脚本访问 |
¶ 确保WEB安全的HTTPS
HTTP的不足:
- 通信使用明文(不加密),内容可能会被窃听
- 不验证通信方的身份,因此有可能遭遇伪装
- 无法证明报文的完整性,所以有可能已遭篡改
HTTP + 加密 + 认证 + 完整性保护 = HTTPS(HTTP Secure)
HTTPS的通信步骤:
- 客户端通过发送Client Hello报文开始SSL通信。报文中包含客户端支持的SSL的指定版本、加密组件(Cipher Suite)列表(所使用的加密算法及密钥长度等)
- 服务器可进行SSL通信时,会以Server Hello报文作为应答。和客户端一样,在报文中包含SSL版本以及加密组件。服务器的加密组件内容是从接收到的客户端加密组件内筛选出来的。
- 之后服务器发送Certificate报文。报文中包含公开密钥证书。
- 最后服务器发送Server Hello Done报文通知客户端,最初阶段的SSL握手协商部分结束。
- SSL第一次握手结束后,客户端以Client Key Exchange报文作为回应。报文中包含通信加密中使用的一种被称为Pre-master secret的随机密码串。该报文已使用步骤3中的公开密钥进行加密。
- 接着客户端继续发送Change Cipher Spec报文。该报文会提示服务器,在此报文之后的通信会采用Pre-master secret密钥加密。
- 客户端发送Finished报文。该报文包含连接至今全部报文的整体校验值。这次握手协商是否能够成功,要以服务器是否能够正确解密该报文作为判定标准。
- 服务器同样发送Change Cipher Spec报文。
- 服务器同样发送Finished报文。
- 服务器和客户端的Finished报文交换完毕之后,SSL连接就算建立完成。当然,通信会受到SSL的保护。从此处开始进行应用层协议的通信,即发送HTTP请求。
- 应用层协议通信,即发送HTTP响应。
- 最后由客户端断开连接。断开连接时,发送close_notify报文。这步之后再发送TCP FIN报文来关闭与TCP的通信。
在以上的流程中,应用层发送数据时会附加一种叫做MAC(Message Authentication Code)的报文摘要。MAC能够查知报文是否遭到篡改,从而保护报文的完整性。
HTTPS存在的问题:
- 与纯文本通信相比,加密通信会消耗更多的CPU及内存资源,交互过程会占用更多资源,导致HTTPS会比HTTP可能会慢2到100倍。
- 购买证书成本也比较高。
¶ WEB的攻击技术
- 跨站脚本攻击(Cross-Site Scripting,XSS)是指通过存在的安全漏洞的Web网站注册用户的浏览器内运行非法的HTML标签或Javascript进行的一种攻击。动态创建的html部分有可能隐藏着安全漏洞。
- SQL注入攻击(SQL Injection)是指针对Web应用使用的数据库,通过运行非法的SQL而产生的攻击。
- OS命令注入攻击(OS Command Injection)是指通过web应用,执行非法的操作系统命令达到攻击目的。
- HTTP首部注入攻击(HTTP Header Injection)是指通过响应首部字段内插入换行,添加任意响应首部或主体的一种攻击。
- 邮件首部注入攻击(MAIL Header Injection)是指Web应用中的邮件发送功能,攻击者通过向邮件首部To或Subject内任意添加非法内容发起的攻击。
- 目录遍历攻击(Directory Traversal)是指对无意公开的文件目录,通过非法截断其目录路径后,达成访问目的的一种攻击。
- 强制浏览(Forced Browsing)从安置在web服务器的公开目录下的文件中,浏览那些原本非自愿公开的文件。
- 不正确的错误消息处理(Error Handling Vulnerability)
- 开放重定向(Open Redirect)
- 会话劫持(Session Hijack)
- 会话固定攻击(Session Fixation)
- 跨站点请求伪造(Cross-Site Request Forgeries,CSRF)是指攻击者通过设置好的陷阱,强制对已完成认证的用户进行非预期的个人信息或设定信息等某些状态更新。
- 密码破解攻击(Password Cracking)
- 点击劫持(Clickjacking)
- DoS攻击(Denial of Service attack)是一种让运行中的服务呈现停止状态的攻击。