前端安全问题梳理

170 阅读6分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第N天,点击查看活动详情 >>

浏览器安全

沙箱:浏览器的多进程

浏览器的进程分为:浏览器进程、渲染进程、插件进程、拓展进程

浏览器架构分成两部分:浏览器内核 和 渲染进程,二者如果需要通信,则要通过IPC channel,在其中会进行安全检查

网络资源的内容存在着各种可能性,所以浏览器会默认所有的网络资源都是不可信的,都是不安全的。但谁也不能保证浏览器不存在漏洞,只要出现漏洞,黑客就可以通过网络内容对用户发起攻击。

我们认为一般的攻击都是发生在渲染进程上的,让渲染进程在执行过程中无法访问或者修改操作系统中的数据,在渲染进程需要访问系统资源的时候,需要通过浏览器内核来实现,然后将访问的结果通过 IPC 转发给渲染进程。

CSP(Content Security Policy)

由服务端返回一个HTTP头,并在其中描述页面应该遵守的安全策略

X-Content-Security-Policy: allow 'self';*.mydomain.com;img-src;media-src;script-src;

XSS

Xss 的全称是 Cross Site Scripting 跨站脚本攻击,值黑客往HTML文件中或者DOM中注入恶意脚本,控制浏览器。

最开始的时候,这种攻击是通过跨域来实现的,所以叫“跨域脚本”。但是现在代表一种统称。

具体体现

  • 可以窃取 Cookie 信息。然后通过 XMLHttpRequest 或者 Fetch 加上 CORS 功能将数据发送给恶意服务器;恶意服务器拿到用户的 Cookie 信息之后,就可以在其他电脑上模拟用户的登录,然后进行转账等操作。
  • 可以监听用户行为。恶意 JavaScript 可以使用“addEventListener”接口来监听键盘事件,比如可以获取用户输入的信用卡等信息,将其发送到恶意服务器。黑客掌握了这些信息之后,又可以做很多违法的事情。
  • 可以通过修改 DOM伪造假的登录窗口,用来欺骗用户输入用户名和密码等信息。
  • 还可以在页面内生成浮窗广告,这些广告会严重地影响用户体验。

分类 / 是怎么实现的

反射型XSS攻击

恶意 JavaScript 脚本属于用户发送给网站请求中的一部分,随后网站又把恶意 JavaScript 脚本返回给用户。

比如搜索 xxx ,页面显示 xxx 的搜索结果如下,直接转发 xxx

<body>
    <div>xxx 的搜索结果如下</div>
</body>

如果搜索 <script>alert('HHH')</script>

<body>
    <div><script>alert('HHH')</script>的搜索结果如下</div>
</body>

此刻这一段 JS 代码就会被执行

再比如有一个 a链接的 src

  • 直接被使用花样的 引号隔断,添加回调
<a href="http://www.xxx.com?test=" onclick="xxx">
  • 被构造协议
<a href="javascript:alear(1)"/>

存储型XSS攻击

  • 首先黑客利用站点漏洞将一段恶意 JavaScript 代码提交到网站的数据库中;
  • 然后用户向网站请求包含了恶意 JavaScript 脚本的页面;

其实本质上和 反射型的差不多,比如搜索结果里有 你想知道<script>alert('HHH')</script>吗

<body>
    <div><script>alert('HHH')</script>的搜索结果如下</div>
    <ul>
    <li>你想知道<script>alert('HHH')</script></li>
    </ul>
</body>

此刻有害的代码来自于服务端,就是存储型 XSS 攻击了

富文本安全

  • 过滤回调事件
  • 只允许 a img div 这种稍微比较安全的标签

基于 DOM 的 XSS 攻击

基于 DOM 的 XSS 攻击是不牵涉到页面 Web 服务器的。或许也能归到反射型XSS,因为他也不走服务器过。

通过修改页面的DOM节点形成的XSS

  • 在 Web 资源传输过程:通过网络劫持在页面传输过程中修改 HTML 页面的内容,这种劫持类型很多,有通过 WiFi 路由器劫持的,有通过本地恶意软件来劫持的,
  • 在用户使用页面的过程中修改 Web 页面的数据

比如上述的两个“攻击”,如果其中的JS脚本是关于修改DOM的,那也是基于DOM的XSS攻击了

产生的危害

  • 窃取cookie: document.cookie
  • 直接使用 XHR 伪造 POST/GET
  • DOM Base:插入form表单,伪造POST/GET
  • 读取 UserAgent 中的个人信息

如何防范

  1. 服务器对输入脚本进行过滤或转码
  2. 客户端输出过滤/转译
  3. 充分利用 CSP
  • 限制加载其他域下的资源文件,这样即使黑客插入了一个 JavaScript 文件,这个 JavaScript 文件也是无法被加载的;
  • 禁止向第三方域提交数据,这样用户数据也不会外泄;
  • 禁止执行内联脚本和未授权的脚本;
  • 还提供了上报机制,这样可以帮助我们尽快发现有哪些 XSS 攻击,以便尽快修复问题。
  1. 使用 HttpOnly 属性,
  • 让 JS 脚本获取不到 cookie

从React看XSS

保证安全:输出自动转译

在 渲染HTML的时候,对于" ' & < > 自动转译,达到结果 -> 在本质上是转译后的字符串,比如 &lt;script&gt;但是显示在页面上是

可能引起漏洞的途径

  1. dangerouslySetInnerHTML: return props.dangerouslySetInnerHTML.__html

解决思路:服务端 校验 / 前端 白名单, 可以过滤/清洗 类HTML 文本

jsxss.com/zh/index.ht…

  1. 直接使用用户输入的值,作为 HTMLElement 的属性
    1. 注入 dangerouslySetInnerHTML
    2. javascript / data:
// DIV

// 用户的输入
const userProvidePropsString = `{"dangerouslySetInnerHTML":{"__html":"<img onerror='alert(\"xss\");' src='empty.png' />"}}"`;
// 经过 JSON 转换
const userProvideProps = JSON.parse(userProvidePropsString);
// userProvideProps = {
//   dangerouslySetInnerHTML: {
//     "__html": `<img onerror='alert("xss");' src='empty.png' />`
//      }
// };
render() {
     // 出于某种原因解析用户提供的 JSON 并将对象作为 props 传递
    return <div {...userProvideProps} />
}

//IMG
const userWebsite = "javascript:alert('xss');";
<a href={userWebsite}></a>

CSRF攻击

全称 Cross-site request forgery ,又称为“跨站请求伪造”,指黑客引诱用户打开黑客的网站,在黑客的网站中,利用用户的登录状态发起的跨站请求。简单来讲,CSRF 攻击就是黑客利用了用户的登录状态,并通过第三方的站点来做一些坏事

案例 1

<img src="http://xxx.com/api/delete?id=12">

用户浏览器一旦解析到这个 img 标签,就会发出一个 get 请求,此刻因为是来自用户的站点发起的同一个域下的请求还会携带 Cookie,这样用户数据就会被删除了

Cookie

分类:

  1. 临时 Cookie:Session Cookie, 指的是服务端没有设置 cookie 的 expires
  2. 本地 Cookie:Third-party Cookie,指的是 设置了有效时间的 Cookie

对于资源标签的请求,不同浏览器有不同的策略:

不可以发送 Third-party Cookie 的:IE 6 7 8、Safari;

可以发送 Third-party Cookie 的:Firefox 、Chrome;

如何防范

  1. 人机交互验证码
  2. 充分利用好 Cookie 的 SameSite 属性

strict:是的在同域下,才可以携带Cookie

  1. 验证请求的来源站点

检查请求报文的 Referer 和 Origin,但是Referer精确的 URL 可以被取消携带【浏览器隐私政策】,Origin 只是域名不能达到目的, 并且可以被伪造,在比如通过 XMLHttpRequest、Fecth 发起跨站请求或者通过 Post 方法发送请求时修改 head

  1. 使用Token,验明身份

但是Token,可以先被XSS从浏览器端读出,然后再构造 CSRF

下面介绍跨域的解决方案