1、产生的背景
为了保障我们在网站上数据安全,浏览器使用了一种安全策略。如果两个 URL 的协议、域名和端口都相同,那么它们就可以相互访问资源和操作 DOM 的,否则会有同源策略的限制。
同源策略限制具体表现在:
- dom层面,同源策略限制了不同源的js脚本对DOM对象的读写操作。就是
js代码执行环境的域名与要操作的dom的域名不相同。 - 数据层面,同源策略限制了不同源的站点读取 Cookie、IndexDB、LocalStorage 等数据。就是
js代码执行读取数据的域名与站点的域名不相同。 - 网络层面。同源策略限制了通过 XMLHttpRequest 等方式将站点的数据发送给不同源的站点。就是
a网站的js向b服务请求数据,但是a与b是不同的域名。
但是还是存在如下问题:
- 允许可以嵌入第三方资源,这是为了开发方便,不然只能用同源下的js,这也太操蛋了,但是这种方式也引入了网站常见的两种攻击方式
xss和csrf
2、xss
2.1、产生背景
页面中可以嵌入第三方资源,所以黑客就想方设法的在你页面中尝试注入恶意js脚本,执行恶意操作,因为此时恶意脚本执行环境的域名与当前站点相同。恶意操作如下:
- 可以窃取 Cookie 信息。
恶意 JavaScript 可以通过“document.cookie”获取 Cookie 信息,然后通过 XMLHttpRequest 或者 Fetch 加上 CORS 功能将数据发送给恶意服务器;恶意服务器拿到用户的 Cookie 信息之后,就可以在其他电脑上模拟用户的登录,然后进行转账等操作。 - 可以
监听用户行为。恶意 JavaScript 可以使用“addEventListener”接口来监听键盘事件,比如可以获取用户输入的信用卡等信息,将其发送到恶意服务器。黑客掌握了这些信息之后,又可以做很多违法的事情。 - 可以通过
修改 DOM 伪造假的登录窗口,用来欺骗用户输入用户名和密码等信息。 - 还可以在页面内生成
浮窗广告,这些广告会严重地影响用户体验。
2.2 xss的攻击类型
明白黑客注入js脚本的方式
- 存储型 XSS 攻击
- 反射型 XSS 攻击
- 基于 DOM 的 XSS 攻击
2.2.1 存储型 XSS 攻击
攻击流程
- 首先黑客利用站点漏洞将一段恶意 JavaScript 代码提交到网站的数据库中;
- 然后用户向网站请求包含了恶意 JavaScript 脚本的页面;
- 当用户浏览该页面的时候,恶意脚本就会将用户的 Cookie 信息等数据上传到服务器。
2.2.2 反射型 XSS 攻击
攻击流程
- 寻找某些网页一些数据的显示是用url上的参数来显示的。
- 将回显的url参数变成js脚本
- 在微信群或者qq群群发带有脚本url的参数。
2.2.3 基于 DOM 的 XSS 攻击
攻击流程
- 通过网络劫持在页面传输过程中修改 HTML 页面的内容,这种劫持类型很多,有通过 WiFi 路由器劫持的,有通过本地恶意软件来劫持的,它们的共同点是在 Web 资源传输过程或者在用户使用页面的过程中修改 Web 页面的数据。
2.3 解决方法
- 服务器对输入脚本进行过滤或转码
- 充分利用 CSP,CSP 的核心思想是让服务器决定浏览器能够加载哪些资源,让服务器决定浏览器是否能够执行内联 JavaScript 代码。
- 使用 HttpOnly 属性,很多 XSS 攻击都是来盗用 Cookie 的,服务器可以将某些 Cookie 设置为 HttpOnly 标志,使用 HttpOnly 标记的 Cookie 只能使用在 HTTP 请求过程中,所以无法通过 JavaScript 来读取这段 Cookie。
3 csrf
3.1 产生背景
cookie不能跨域访问(除非是在cookie的domain允许的子域),但是可以跨站点共享,这两个概念要区分开来。
在同一浏览器,当前打开的多个Tab页网站,无论是否为同一站点,cookie都是共享可见的。这个共享不是说每个网站的脚本可以访问别的网站的cookie,而是说,你向同一服务器发送请求时,会带上浏览器保存的对于那个服务器的所有cookie,而不管你从哪个网站发起的请求。
3.2 csrf的攻击例子
明白csrf是如何攻击的。
- 用户a登陆
网站A,此时获取到了cookie,这时候不关闭网站A。 - 用户a访问黑客
网站B, 此时网站B向网站A的服务发送了请求,这时候会网站B的请求会带上网站A的cookie。
3.3 解决方法
3.3.1 使用SameSite
响应头中可以设置set-cookie,其中SameSite 选项通常有 Strict、Lax 和 None 三个值。
- Strict 最为严格, 浏览器会完全禁止第三方 Cookie。简言之,如果你从极客时间的页面中访问 InfoQ 的资源,而 InfoQ 的某些 Cookie 设置了 SameSite = Strict 的话,那么这些 Cookie 是不会被发送到 InfoQ 的服务器上的。只有你从 InfoQ 的站点去请求 InfoQ 的资源时,才会带上这些 Cookie。
意思是只有相同域名才会发送cookie么?准备测试呢 - Lax 相对宽松一点。在跨站点的情况下,从第三方站点的链接打开和从第三方站点提交 Get 方式的表单这两种方式都会携带 Cookie。但如果在第三方站点中使用 Post 方法,或者通过 img、iframe 等标签加载的 URL,这些场景都不会携带 Cookie。
- 而如果使用 None 的话,在任何情况下都会发送 Cookie 数据。
3.3.2 服务端查看Origin和Referer
请求的请求头中会带上Origin和Referer两个字断,Origin代表请求来源的域名, Referer代表请求来源的路径(前端可改),因此,服务器的策略是优先判断 Origin,如果请求头中没有包含 Origin 属性,再根据实际情况判断是否使用 Referer 值。
3.3.3 利用token
因为cookie会根据域名自动发送,故此不使用cookie来验证身份了,使用token来验证身份,因为请求携带token是需要前端开发在请求中写入的。