Web安全 - 明文传输等于裸奔

  • 作者:KK

  • 发表日期:2019.09.06


初步了解

HTTP 请求发出去的时候,整片数据是这样的:

POST http://www.kkh86.com/http-test.do HTTP/1.1
Host: www.kkh86.com
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Content-Length: 15
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.104 Safari/537.36 Core/1.53.3368.400 QQBrowser/9.6.11974.400
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8
Cookie: auto-login=1

name=Jay&age=33

关于 HTTP 报文的浅析可以看我的 这套文章

上面报文数据的最后一行“name=Jay&age=33”就是 POST 请求的数据,如果换成密码的话就是“password=123456”之类的,而这些数据会经过路由器、城市网络转发节点、国际网络节点等,这条链路往往加起来会有很多个节点,任何一个节点都看着这片数据经过,所以别人也就能知道你在发什么请求,传什么数据,密码是什么。

为了证实这一点,你可以通过 抓包软件 把请求数据抓下来看看,将抓包软件设为代理时,抓包软件也是其中一个传输节点,它也能把你的数据记下来,这就是现实。


加密关键数据

大概在2016年以前,还是很多很多网站用 HTTP 协议的,那时候大家解决问题的手段普遍是在发送数据前将一些关键的请求参数加密,服务端再解密。

服务端与第三方服务对接的时候还好,那毕竟是服务端对服务端,加密算法都不知道,抓到包也不会解。但是如果是浏览器与服务端的请求,那别人抓到数据后还是能去浏览器那里看JS代码的逻辑来反推加密过程的,然而JS代码又可以被混淆,增加破解难度,所以如果花很长时间破解JS逻辑换来的经济收益不值得的话,那破译者还是会放弃的,所以加密关键数据提高了破译门槛,增加了破译者的时间成本,也使得很多网站基本保证了自身的安全。

然而 Cookie 这些没法在发送前加密,收到时再解密,只能真的明文发出去了,而且很多网站是通过 Cookie 来储存登录口令的,所以只要抓到数据包里的 Cookie 有登录口令,那就可以伪造登录身份了,这时候有些网站就会祭出下一招:来个复杂的口令更新和校验机制,比如每次请求都换一个口令,每个口令只能用一次,校验的时候要结合 IP 和 UserAgent 等,然而最终还是会被破解的。


更恐怖的是网络节点可以伪造响应给你

比如你发转账请求,为了表达转账行为、转多少钱、转给谁,报文大致会这样体现数据:

地址: /money/转账

amount=1000&to=383

to 参数是转账的目标账号ID,如果我的账号是888,那我如果入侵了网络节点,抓到这种数据的时候,可以将383修改成888再往目标服务器转发,而自己又返回转账失败或者转账成功的虚假数据给浏览器,这样就实现了一次欺骗。这种情况往往叫做“篡改报文”(想亲自体验伪造响应的话,可以看看 这篇文章)。


使用 HTTPS 吧

HTTPS 其实是 HTTP + SSL,访问网站的时候,服务器会下发一个公钥给浏览器,浏览器与该网站域名的任何通讯数据都会使用这个公钥进行加密再发出去,如果中途被篡改,则另一方收到数据后会解密失败,这里不具体详述,其实我也不是这方面的专家和研究者,只是知道浅层的知识。

HTTPS 虽然加密了数据传输,但它也不能防止中间节点抓包破译,它能防止的就是篡改报文,起码保证了客户端与服务端之间互发的数据是可信的,确定是对方发过来并且没有任何一个数据被修改掉的。

在防破译方面,其实它只是破译的成本高了,使得只要做破译的往往就是有针对性的破译,比如我今天就是要搞淘宝,那它再来 HTTPS 再来 JS 加密,我也会努力冲破这些障碍去破译它。但如果没有针对性的话,我尽管入侵了一个网络节点,甚至我就是这个网络节点的管理员(拥有者居心不良),一般情况下都懒得对所有抓到的包进行破译,因为可能破译出来后看到的数据是没有什么价值的。