同源策略
如果两个 URL 的协议、域名和端口都相同,我们就称这两个 URL 同源。
- 可以相互访问资源。
- 操作 DOM。在另一个页面中操作这一个页面的dom。
同源策略主要表现在 DOM、Web 数据和网络这三个层面。
- dom层面。同源的页面,可以相互操作dom。
- 数据层面。同源策略限制了不同源的站点读取当前站点的 Cookie、IndexDB、LocalStorage 等数据。
- 网络层面。同源策略限制了通过 XMLHttpRequest 等方式将站点的数据发送给不同源的站点。
如果让不同源的资源绝对隔离,那么一定是最安全的,但是这样会使web项目难以开发。所以就需要做权衡。
在不同源的两个页面中,为了解决这两个问题。又引入了:
- 跨域资源共享(CORS)。
- 跨文档消息机制。window.postMessage。
- 页面中可以引用第三方资源,不过这也暴露了很多诸如 XSS 的安全问题,因此又在这种开放的基础之上引入了 CSP 来限制其自由程度。
同源策略、CSP 和 CORS 之间的关系?
- 因为有了同源策略的限制,在不同源的页面之间不能直接操作dom。但是可以通过window.postMessage操作。
- 浏览器都是支持外部引用资源文件的,所以为了安全,浏览器中引入了内容安全策略,称为 CSP。CSP 的核心思想是让服务器决定浏览器能够加载哪些资源,让服务器决定浏览器是否能够执行内联 JavaScript 代码。
- 为了可以在不同源的之间发送网络请求,引入了cors。
页面是可以自由引入第三方资源的,浏览器不会对其做限制,但是返回的html可以引入csp机制,即Content-Security-Policy header 头来告诉浏览器哪些js和图片资源可以加载执行,需要符合什么样的规则。
xss: 跨站脚本攻击
我们默认页面中可以引用任意第三方资源,然后又引入 CSP 策略来加以限制;默认 XMLHttpRequest 和 Fetch 不能跨站请求资源,然后又通过 CORS 策略来支持其跨域。
不过支持页面中的第三方资源引用和 CORS 也带来了很多安全问题,其中最典型的就是 XSS 攻击。
跨站脚本攻击是指通过存在安全漏洞的Web网站注册用户的浏览器内运行非法的HTML标签或JavaScript进行的一种攻击。
如果页面被注入了恶意 JavaScript 脚本,恶意脚本都能做哪些事情。
- 可以窃取 Cookie 信息。恶意 JavaScript 可以通过“document.cookie”获取 Cookie 信息,然后通过 XMLHttpRequest 或者 Fetch 加上 CORS 功能将数据发送给恶意服务器;恶意服务器拿到用户的 Cookie 信息之后,就可以在其他电脑上模拟用户的登录,然后进行转账等操作。
- 可以监听用户行为。 恶意 JavaScript 可以使用“addEventListener”接口来监听键盘事件,比如可以获取用户输入的信用卡等信息,将其发送到恶意服务器。黑客掌握了这些信息之后,又可以做很多违法的事情。
- 可以通过修改 DOM 伪造假的登录窗口,用来欺骗用户输入用户名和密码等信息。
- 还可以在页面内生成浮窗广告,这些广告会严重地影响用户体验。
那些方式可以注入非法的js脚本呢?
存储型 XSS 攻击、反射型 XSS 攻击和基于 DOM 的 XSS 攻击三种方式来注入恶意脚本。
反射型
在url中存放恶意代码。然后服务器获取到恶意代码,将其渲染在页面中,用户访问页面,他将被执行。
Web 服务器不会存储反射型 XSS 攻击的恶意脚本,这是和存储型 XSS 攻击不同的地方。
存储型
将内容经正常功能提交进入数据库持久保存,当前端页面获得后端从数据库中读出的注入代码时,恰好将其渲染执行。
基于 DOM 的 XSS 攻击
在 Web 资源传输过程或者在用户使用页面的过程中修改 Web 页面的数据。
如何预防xss攻击呢?
存储型 XSS 攻击和反射型 XSS 攻击都是需要经过 Web 服务器来处理的,因此可以认为这两种类型的漏洞是服务端的安全漏洞。
而基于 DOM 的 XSS 攻击全部都是在浏览器端完成的,因此基于 DOM 的 XSS 攻击是属于前端的安全漏洞。
它们都有一个共同点,那就是首先往浏览器中注入恶意脚本,然后再通过恶意脚本将用户信息发送至黑客部署的恶意服务器上。
所以要阻止 XSS 攻击,我们可以通过阻止恶意 JavaScript 脚本的注入和恶意消息的发送来实现。
- 服务器对输入脚本进行过滤或转码。
- 充分利用 CSP
- 限制加载其他域下的资源文件,这样即使黑客插入了一个 JavaScript 文件,这个 JavaScript 文件也是无法被加载的;
- 禁止向第三方域提交数据,这样用户数据也不会外泄;
- 禁止执行内联脚本和未授权的脚本;
- 还提供了上报机制,这样可以帮助我们尽快发现有哪些 XSS 攻击,以便尽快修复问题。
- 使用 HttpOnly 属性。在浏览器端禁止获取cookie。
csrf:跨站请求伪造
CSRF 攻击就是诱导用户点击黑客连接,然后黑客在自己的站点设置相应网站的请求连接,利用了用户的登录状态,并通过第三方的站点来做一些坏事。
mdn上有一个很好的例子
和 XSS 不同的是,CSRF 攻击不需要将恶意代码注入用户的页面,仅仅是利用服务器的漏洞和用户的登录状态来实施攻击。
如何预防csrf攻击
发起 CSRF 攻击的三个必要条件:
- 第一个,目标站点一定要有 CSRF 漏洞;
- 第二个,用户要登录过目标站点,并且在浏览器上保持有该站点的登录状态;
- 第三个,需要用户打开一个黑客的站点。 所以说对于 CSRF 攻击我们主要的防护手段是提升服务器的安全性。
- 充分利用好 Cookie 的 SameSite 属性。禁止用户通过连接跳转的方式发送cookie。完全禁止第三方 Cookie。
- 验证请求的来源站点。 通过http请求头中的Origin 和 Referer。
Origin: 只显示请求的域名。Referer: 显示请求方的完整路径。从哪个页面链接过来的。
但在某些情况下如从https跳转到http,浏览器处于安全考虑,不会发送referer,服务器就无法进行referer验证了。
- CSRF Token。 同一个浏览器打开两个相同页面,那么服务器为这两个页面生成的csrf token都是不同的。
由于CSRF的本质在于攻击者欺骗用户去访问自己设置的地址,所以如果要求在访问敏感数据请求时,要求用户浏览器提供不保存在cookie中,并且攻击者无法伪造的数据作为校验,那么攻击者就无法再执行CSRF攻击。这种数据通常是窗体中的一个数据项。服务器将其生成并附加在窗体中,其内容是一个伪随机数。当客户端通过窗体提交请求时,这个伪随机数也一并提交上去以供校验。正常的访问时,客户端浏览器能够正确得到并传回这个伪随机数,而通过CSRF传来的欺骗性攻击中,攻击者无从事先得知这个伪随机数的值,服务端就会因为校验token的值为空或者错误,拒绝这个可疑请求。
就是不适用cookie做身份认证。
SQL注入
就是利用输入的参数将查询结果永远为true。SQL注入的本质:数据和代码未分离,即数据当做了代码来执行。
SQL注入的必备条件: 1.可以控制输入的数据 2.服务器要执行的代码拼接了控制的数据。
危害
- 获取数据库信息
- 管理员后台用户名和密码
- 获取其他数据库敏感信息:用户名、密码、手机号码、身份证、银行卡信息……
- 整个数据库:脱裤
- 获取服务器权限
- 植入Webshell,获取服务器后门
- 读取服务器敏感文件
如何防御
- 严格限制Web应用的数据库的操作权限,给此用户提供仅仅能够满足其工作的最低权限,从而最大限度的减少注入攻击对数据库的危害
- 后端代码检查输入的数据是否符合预期,严格限制变量的类型,例如使用正则表达式进行一些匹配处理。
- 对进入数据库的特殊字符(',",\,<,>,&,*,; 等)进行转义处理,或编码转换。基本上所有的后端语言都有对字符串进行转义处理的方法,比如 lodash 的 lodash._escapehtmlchar 库。
- 所有的查询语句建议使用数据库提供的参数化查询接口,参数化的语句使用参数而不是将用户输入变量嵌入到 SQL 语句中,即不要直接拼接 SQL 语句。例如 Node.js 中的 mysqljs 库的 query 方法中的 ? 占位参数。
XST:跨站追踪攻击
XST 的全称是 Cross-Site Tracing,中文译作“跨站式追踪攻击”。具体而言,是客户端发 TRACE 请求至服务器,如果服务器按照标准实现了 TRACE 响应,则在 response body 里会返回此次请求的完整头信息。通过这种方式,客户端可以获取某些敏感的 header 字段,例如 httpOnly 的 Cookie 等。
首先你需要了解一下trace请求的作用是什么?
显示出请求-响应的传输路径。多用于http链路的测试或者诊断。
XST 攻击的条件:
- 需要目标 Web 服务器允许接受 Trace、Track 方法的请求。
- 客户端可以发送 Trace 方法的请求。(如今浏览器环境下已经杜绝这种请求)。