Open ArthurWangCN opened 2 years ago
HTTP协议规定,请求从客户端发出,最后服务器端响应该请求并返回。换句话说,肯定是先从客户端开始建立通信的,服务器端在没有接收到请求之前不会发送响应。
一个请求报文的内容:
GET /index.htm HTTP/1.1
Host: hackr.jp
GET表示请求访问服务器的类型,称为方法(method)。随后的字符串/index.htm指明了请求访问的资源对象,也叫做请求URI(request-URI)。最后的HTTP/1.1,即HTTP的版本号,用来提示客户端使用的HTTP协议功能。
综合来看,这段请求内容的意思是:请求访问某台HTTP服务器上的/index.htm页面资源。
响应报文:
HTTP/1.1 200 OK
Date: Tue, 10 Jul 2012 06:50:15 GMT
Content-Length: 362
Content-Type: text/html
<html>
……
HTTP/1.1表示服务器对应的HTTP版本。紧挨着的200 OK表示请求的处理结果的状态码(status code)和原因短语(reason-phrase)。 下一行显示了创建响应的日期时间,是首部字段(header field)内的一个属性。 接着以一空行分隔,之后的内容称为资源实体的主体(entity body)。
HTTP是一种不保存状态,即无状态(stateless)协议。HTTP协议自身不对请求和响应之间的通信状态进行保存。也就是说在HTTP这个级别,协议对于发送过的请求或响应都不做持久化处理。
这是为了更快地处理大量事务,确保协议的可伸缩性,而特意把HTTP协议设计成如此简单的。
HTTP/1.1虽然是无状态协议,但为了实现期望的保持状态功能,于是引入了Cookie技术。
HTTP协议使用URI定位互联网上的资源。正是因为URI的特定功能,在互联网上任意位置的资源都能访问到。
向请求URI指定的资源发送请求报文时,采用称为方法的命令。方法的作用在于,可以指定请求的资源按期望产生某种行为。
持久连接节省通信量
持久连接的特点是,只要任意一端没有明确提出断开连接,则保持TCP连接状态。
持久连接的好处在于减少了TCP连接的重复建立和断开所造成的额外开销,减轻了服务器端的负载。另外,减少开销的那部分时间,使HTTP请求和响应能够更早地结束,这样Web页面的显示速度也就相应提高了。
在HTTP/1.1中,所有的连接默认都是持久连接。
持久连接使得多数请求以管线化(pipelining)方式发送成为可能。从前发送请求后需等待并收到响应,才能发送下一个请求。管线化技术出现后,不用等待响应亦可直接发送下一个请求。
Cookie技术通过在请求和响应报文中写入Cookie信息来控制客户端的状态。
HTTP请求报文和响应报文的内容如下:
①请求报文(没有Cookie信息的状态)
GET /reader/ HTTP/1.1
Host: hackr.jp
*首部字段内没有Cookie的相关信息
②响应报文(服务器端生成Cookie信息)
HTTP/1.1200 OK
Date: Thu, 12 Jul 2012 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
③请求报文(自动发送保存着的Cookie信息)
GET /image/ HTTP/1.1
Host: hackr.jp
Cookie: sid=1342077140226724
用于HTTP协议交互的信息被称为HTTP报文。请求端(客户端)的HTTP报文叫做请求报文,响应端(服务器端)的叫做响应报文。HTTP报文本身是由多行(用CR+LF作换行符)数据构成的字符串文本。
HTTP报文大致可分为报文首部和报文主体两块。两者由最初出现的空行(CR+LF)来划分。通常,并不一定要有报文主体。
请求报文和响应报文的首部内容由以下数据组成:
HTTP在传输数据时可以按照数据原貌直接传输,但也可以在传输过程中通过编码提升传输速率。
HTTP协议中采纳了多部分对象集合,发送的一份报文主体内可含有多类型实体。通常是在图片或文本文件等上传时使用。
在HTTP报文中使用多部分对象集合时,需要在首部字段里加上Content-type。
内容协商机制是指客户端和服务器端就响应的资源内容进行交涉,然后提供给客户端最为适合的资源。内容协商会以响应资源的语言、字符集、编码方式等作为判断的基准。
包含在请求报文中的某些首部字段(如下)就是判断的基准。
状态码的职责是当客户端向服务器端发送请求时,描述返回的请求结果。借助状态码,用户可以知道服务器端是正常处理了请求,还是出现了错误。
2xx 成功
3XX重定向
3XX响应结果表明浏览器需要执行某些特殊的处理以正确处理请求。
4XX客户端错误
4XX的响应结果表明客户端是发生错误的原因所在。
5XX服务器错误
5XX的响应结果表明服务器本身发生错误。
即使物理层面只有一台服务器,但只要使用虚拟主机的功能,则可以假想已具有多台服务器。
在互联网上,域名通过DNS服务映射到IP地址(域名解析)之后访问目标网站。可见,当请求发送到服务器时,已经是以IP地址形式访问了。
所以,如果一台服务器内托管了www.tricorder.jp和www.hackr.jp这两个域名,当收到请求时就需要弄清楚究竟要访问哪个域名。
在相同的IP地址下,由于虚拟主机可以寄存多个不同主机名和域名的Web网站,因此在发送HTTP请求时,必须在Host首部内完整指定主机名或域名的URI。
HTTP通信时,除客户端和服务器以外,还有一些用于通信数据转发的应用程序,例如代理、网关和隧道。它们可以配合服务器工作。
这些应用程序和服务器可以将请求转发给通信线路上的下一站服务器,并且能接收从那台服务器发送的响应再转发给客户端。
代理: 代理是一种有转发功能的应用程序,它扮演了位于服务器和客户端“中间人”的角色,接收由客户端发送的请求并转发给服务器,同时也接收服务器返回的响应并转发给客户端。
代理服务器的基本行为就是接收客户端发送的请求后转发给其他服务器。代理不改变请求URI,会直接发送给前方持有资源的目标服务器。
网关: 网关是转发其他服务器通信数据的服务器,接收从客户端发送来的请求时,它就像自己拥有资源的源服务器一样对请求进行处理。
利用网关能提高通信的安全性,因为可以在客户端与网关之间的通信线路上加密以确保连接的安全。
隧道: 隧道是在相隔甚远的客户端和服务器两者之间进行中转,并保持双方通信连接的应用程序。
隧道可按要求建立起一条与其他服务器的通信线路,届时使用SSL等加密手段进行通信。隧道的目的是确保客户端能与服务器进行安全的通信。
缓存是指代理服务器或客户端本地磁盘内保存的资源副本。利用缓存可减少对源服务器的访问,因此也就节省了通信流量和通信时间。
缓存服务器是代理服务器的一种,并归类在缓存代理类型中。换句话说,当代理转发从服务器返回的响应时,代理服务器将会保存一份资源的副本。
缓存服务器的优势在于利用缓存可避免多次从源服务器转发资源。因此客户端可就近从缓存服务器上获取资源,而源服务器也不必多次处理相同的请求了。
即使存在缓存,也会因为客户端的要求、缓存的有效期等因素,向源服务器确认资源的有效性。若判断缓存失效,缓存服务器将会再次从源服务器上获取“新”资源。
HTTP协议的请求和响应报文中必定包含HTTP首部。首部内容为客户端和服务器分别处理请求和响应提供所需要的信息。
HTTP请求报文
在请求中,HTTP报文由方法、URI、HTTP版本、HTTP首部字段等部分构成。
示例:
GET / HTTP/1.1
Host: hackr.jp
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Gecko/=>
20100101 Firefox/13.0
Accept: text/html, application/xhtml+xml, application/xml; q=0.9, =>
*/*; q=0.8
Accept-Language: ja,en-us;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
Connection: keep-alive
If-Modified-Since: Fri, 31 Aug 2007 02:02:20 GMT
If-None-Match: "45bae1-16a-46d776ac"
Cache-Control: max-age=0
HTTP响应报文
在响应中,HTTP报文由HTTP版本、状态码(数字和原因短语)、HTTP首部字段3部分构成。
示例:
HTTP/1.1304 Not Modified
Date: Thu, 07 Jun 2012 07:21:36 GMT
Server: Apache
Connection: close
Etag: "45bae1-16a-46d776ac"
使用首部字段是为了给浏览器和服务器提供报文主体大小、所使用的语言、认证信息等内容。
HTTP首部字段是由首部字段名和字段值构成的,中间用冒号“:”分隔。
如:Content-Type: text/html
。
字段值对应单个HTTP首部字段可以有多个值,如:Keep-Alive: timeout=15, max=100
。
若HTTP首部字段重复,根据浏览器内部处理逻辑的不同,结果可能并不一致。
4种HTTP首部字段类型:
通用首部字段
通用首部字段是指,请求报文和响应报文双方都会使用的首部。
请求首部字段
请求首部字段是从客户端往服务器端发送请求报文中所使用的字段,用于补充请求的附加信息、客户端信息、对响应内容相关的优先级等内容。
响应首部字段
响应首部字段是由服务器端向客户端返回响应报文中所使用的字段,用于补充响应的附加信息、服务器信息,以及对客户端的附加要求等信息。
实体首部字段
实体首部字段是包含在请求报文和响应报文中的实体部分所使用的首部,用于补充内容的更新时间等与实体相关的信息。
为Cookie服务的首部字段
Cookie的工作机制是用户识别及状态管理。Web网站为了管理用户的状态会通过Web浏览器,把一些数据临时写入用户的计算机内。接着当用户访问该Web网站时,可通过通信方式取回之前存放的Cookie。
Set-Cookie
Set-Cookie: status=enable; expires=Tue, 05 Jul 2011 07:26:31 GMT; =>
path=/; domain=.hackr.jp;
Cookie
Cookie: status=enable;
首部字段Cookie会告知服务器,当客户端想获得HTTP状态管理支持时,就会在请求中包含从服务器接收到的Cookie。接收到多个Cookie时,同样可以以多个Cookie形式发送。
其他首部字段
HTTP的不足:
加密:
通信的加密:
通信使用明文(不加密),内容可能会被窃听;不验证通信方的身份,因此有可能遭遇伪装;无法证明报文的完整性,所以有可能已遭篡改。
用SSL建立安全通信线路之后,就可以在这条线路上进行HTTP通信了。与SSL组合使用的HTTP被称为HTTPS(HTTP Secure,超文本传输安全协议)或HTTP over SSL。
内容的加密:把HTTP报文里所含的内容进行加密处理。
验证通信方的身份:
HTTP协议的实现本身非常简单,不论是谁发送过来的请求都会返回响应,因此不确认通信方。
虽然使用HTTP协议无法确定通信方,但如果使用SSL则可以。SSL不仅提供加密处理,而且还使用了一种被称为证书的手段,可用于确定方。
完整性:
所谓完整性是指信息的准确度。若无法证明其完整性,通常也就意味着无法判断信息是否准确。
请求或响应在传输途中,遭攻击者拦截并篡改内容的攻击称为中间人攻击(Man-in-the-Middle attack,MITM)。
虽然有使用HTTP协议确定报文完整性的方法,但事实上并不便捷、可靠。其中常用的是MD5和SHA-1等散列值校验的方法,以及用来确认文件的数字签名方法。
HTTP+加密+认证+完整性保护=HTTPS
在HTTP上再加入加密处理和认证等机制,我们把添加了加密及认证机制的HTTP称为HTTPS(HTTP Secure)。
HTTPS并非是应用层的一种新协议。只是HTTP通信接口部分用SSL(Secure Socket Layer)和TLS(Transport Layer Security)协议代替而已。
通常,HTTP直接和TCP通信。当使用SSL时,则演变成先和SSL通信,再由SSL和TCP通信了。简言之,所谓HTTPS,其实就是身披SSL协议这层外壳的HTTP。
SSL采用一种叫做公开密钥加密(Public-key cryptography)的加密处理方式。
HTTPS采用共享密钥加密和公开密钥加密两者并用的混合加密机制。在交换密钥环节使用公开密钥加密方式,之后的建立通信交换报文阶段则使用共享密钥加密方式。
为了保证收到的公开密钥就是原本预想的那台服务器发行的公开密钥,可以使用由数字证书认证机构(CA,Certificate Authority)和其相关机关颁发的公开密钥证书。
HTTP/1.1使用的认证方式如下所示:
BASIC认证:
BASIC认证虽然采用Base64编码方式,但不是加密处理。认证使用上不够便捷灵活,且达不到多数Web网站期望的安全性等级,因此它并不常用。
DIGEST认证:
DIGEST认证同样使用质询/响应的方式(challenge/response),但不会像BASIC认证那样直接发送明文密码。
SSL客户端认证:
为达到SSL客户端认证的目的,需要事先将客户端证书分发给客户端,且客户端必须安装此证书。
在多数情况下,SSL客户端认证不会仅依靠证书完成认证,一般会和基于表单认证(稍后讲解)组合形成一种双因素认证(Two-factor authentication)来使用。
基于表单认证:
基于表单的认证方法并不是在HTTP协议中定义的。客户端会向服务器上的Web应用程序发送登录信息(Credential),按登录信息的验证结果认证。
基于表单认证的标准规范尚未有定论,一般会使用Cookie来管理Session(会话)。
HTTP的瓶颈:
Google在2010年发布了SPDY(取自SPeeDY,发音同speedy),其开发目标旨在解决HTTP的性能瓶颈,缩短Web页面的加载时间(50%)。
SPDY没有完全改写HTTP协议,而是在TCP/IP的应用层与传输层之间通过新加会话层的形式运作。同时,考虑到安全性问题,SPDY规定通信中使用SSL。
SPDY以会话层的形式加入,控制对数据的流动,但还是采用HTTP建立通信连接。因此,可照常使用HTTP的GET和POST等方法、Cookie以及HTTP报文等。
使用SPDY后,HTTP可以:
使用浏览器进行全双工通信的WebSocket
一旦Web服务器与客户端之间建立起WebSocket协议的通信连接,之后所有的通信都依靠这个专用协议进行。通信过程中可互相发送JSON、XML、HTML或图片等任意格式的数据。
WebSocket特点:推送功能、减少通信量
握手请求:为了实现WebSocket通信,需要用到HTTP的Upgrade首部字段,告知服务器通信协议发生改变,以达到握手的目的。
握手响应:对于之前的请求,返回状态码101 Switching Protocols的响应。
示例:
var socket = new WebSocket('ws://xxx');
socket.onopen = function () {
// ...
}
HTTP/2.0
HTTP/2.0的目标是改善用户在使用Web时的速度体验。
WebDAV:是一个可对Web服务器上的内容直接进行文件复制、编辑等操作的分布式文件系统。
HTML是为了发送Web上的超文本(Hypertext)而开发的标记语言。
动态HTML(Dynamic HTML),是指使用客户端脚本语言将静态的HTML内容变成动态的技术的总称。动态HTML技术是通过调用客户端脚本语言JavaScript,实现对HTML的Web页面的动态改造。利用DOM(Document Object Model,文档对象模型)可指定欲发生动态变化的HTML元素。
Web应用是指通过Web功能提供的应用程序。比如购物网站、网上银行、SNS、BBS、搜索引擎和e-learning等。
CGI(Common Gateway Interface,通用网关接口)是指Web服务器在接收到客户端发送过来的请求后转发给程序的一组机制。在CGI的作用下,程序会对请求内容做出相应的动作,比如创建HTML等动态内容。
Servlet是一种能在服务器上创建动态内容的程序。Servlet是用Java语言实现的一个接口,属于面向企业级Java(JavaEE,Java Enterprise Edition)的一部分。
可扩展标记语言XML是一种可按应用目标进行扩展的通用标记语言。旨在通过使用XML,使互联网数据共享变得更容易。
JSON(JavaScript Object Notation)是一种以JavaScript(ECMAScript)的对象表示法为基础的轻量级数据标记语言。能够处理的数据类型有false/null/true/对象/数组/数字/字符串,这7种类型。
从整体上看,HTTP就是一个通用的单纯协议机制。因此它具备较多优势,但是在安全性方面则呈劣势。
在Web应用中,从浏览器那接收到的HTTP请求的全部内容,都可以在客户端自由地变更、篡改。所以Web应用可能会接收到与预期数据不相同的内容。
对Web应用的攻击模式有以下两种:主动攻击、被动攻击。
主动攻击(active attack)是指攻击者通过直接访问Web应用,把攻击代码传入的攻击模式。由于该模式是直接针对服务器上的资源进行攻击,因此攻击者需要能够访问到那些资源。
主动攻击模式里具有代表性的攻击是SQL注入攻击和OS命令注入攻击。
被动攻击(passive attack)是指利用圈套策略执行攻击代码的攻击模式。在被动攻击过程中,攻击者不直接对目标Web应用访问发起攻击。
实施Web应用的安全对策可大致分为以下两部分:
跨站脚本攻击(Cross-Site Scripting,XSS)是指通过存在安全漏洞的Web网站注册用户的浏览器内运行非法的HTML标签或JavaScript进行的一种攻击。动态创建的HTML部分有可能隐藏着安全漏洞。XSS是攻击者利用预先设置的陷阱触发的被动攻击。
SQL注入(SQL Injection)是指针对Web应用使用的数据库,通过运行非法的SQL而产生的攻击。该安全隐患有可能引发极大的威胁,有时会直接导致个人信息及机密信息的泄露。
OS命令注入攻击(OS Command Injection)是指通过Web应用,执行非法的操作系统命令达到攻击的目的。只要在能调用Shell函数的地方就有存在被攻击的风险。
HTTP首部注入攻击(HTTP Header Injection)是指攻击者通过在响应首部字段内插入换行,添加任意响应首部或主体的一种攻击。属于被动攻击模式。
邮件首部注入(Mail Header Injection)是指Web应用中的邮件发送功能,攻击者通过向邮件首部To或Subject内任意添加非法内容发起的攻击。利用存在安全漏洞的Web网站,可对任意邮件地址发送广告邮件或病毒邮件。
目录遍历(Directory Traversal)攻击是指对本无意公开的文件目录,通过非法截断其目录路径后,达成访问目的的一种攻击。
远程文件包含漏洞(Remote File Inclusion)是指当部分脚本内容需要从其他文件读入时,攻击者利用指定外部服务器的URL充当依赖文件,让脚本读取之后,就可运行任意脚本的一种攻击。
跨站点请求伪造(Cross-Site Request Forgeries,CSRF)攻击是指攻击者通过设置好的陷阱,强制对已完成认证的用户进行非预期的个人信息或设定信息等某些状态更新,属于被动攻击。
密码破解攻击(Password Cracking)即算出密码,突破认证。
点击劫持(Clickjacking)是指利用透明的按钮或链接做成陷阱,覆盖在Web页面之上。然后诱使用户在不知情的情况下,点击那个链接访问内容的一种攻击手段。
DoS攻击(Denial of Service attack)是一种让运行中的服务呈停止状态的攻击。有时也叫做服务停止攻击或拒绝服务攻击。DoS攻击的对象不仅限于Web网站,还包括网络设备及服务器等。
后门程序(Backdoor)是指开发设置的隐藏入口,可不按正常步骤使用受限功能。利用后门程序就能够使用原本受限制的功能。
第一章