《WebKit 技术内幕》学习之十二(2):安全机制

2 沙箱模型

2.1 原理

        一般而言,对于网络上的网页中的JavaScript代码和插件是不受信的(除非是经过认证的网站),特别是一些故意设计侵入浏览器运行的主机代码更是非常危险,通过一些手段或者浏览器中的漏洞,这些代码可能获取了主机的管理权限,这对主机系统来说是非常危险的。所以,除了保证网页本身之外,还需要保证浏览器和浏览器所在的系统不存在危险。

        对于网络上的网页,浏览器认为它们是不安全的,因为网页总是存在各种可能性,也许是无意的或有意的攻击。如果有一种机制,将网页的运行限制在一个特定的环境中,也就是一个沙箱中,使它只能访问有限的功能。那么,即使网页工作的渲染引擎被攻击,它也不能够获取渲染引擎工作的主机系统中的任何权限,这一思想就是沙箱模型。

        WebKit中并没有提供沙箱机制的支持,所以后面的介绍主要以Chromium为基础来介绍在多进程架构中,沙箱模型的实现方式。

        Chromium是以多进程为基础的,网页的渲染在一个独立的Renderer进程中进行,这为实现沙箱模型提供了基础,因为可以相对容易地使用一些技术将整个网页的渲染过程放在一个受限的进程中来完成,如图12-7所示,受限环境只能被某些或者很少的系统调用而且不能直接访问用户数据。而沙箱模型工作的基本单位就是进程。

                                        图12-7 使用沙箱模型的渲染引擎的示意图

        Chromium的沙箱模型是利用系统提供的安全技术,让网页在执行过程中不会修改操作系统或者是访问系统中的隐私数据,而需要访问系统资源或者说是系统调用的时候,通过一个代理机制来完成。下面详细介绍沙箱模型的实现方式和工作原理。

2.2 实现机制

        因为沙箱模型严重依赖操作系统提供的技术,而不同操作系统提供的安全技术是不一样的,这样也就意味着不同操作系统上的实现是不一致的,需要分别针对不同平台展开来讨论。不过,不管是Linux还是Windows,或者是其他平台,Chromium都是在进程的粒度下来实现沙箱模型,也就是说需要运行在沙箱下的操作都在一个单独的进程中。所以,对于使用沙箱模型至少需要两个进程,如图12-8所示。

                                        图12-8 应用沙箱模型的进程模型

        图中右侧的是目标进程,也就是需要在沙箱中运行的代码,左侧的是代理进程,它需要负责创建目标进程并为目标进程设置各种安全策略,同时建立IPC连接,接受目标进程的各种请求,因为目标进程是不能访问过多资源的。下面主要讨论Linux和Windows平台上沙箱模型的实现和涉及的技术。

2.2.1 Linux

        在Linux上,沙箱模型分成两个层,第一层是阻止某个或者某些进程通常能够访问的资源,Chromium中称为“语义层”,这里使用的系统技术主要是“setuid”,详情稍后介绍。第二层是防止进程访问能够攻击内核的接口或者攻击面(Attack Surface,这里主要是内核可能会被未授权的用户调用),这里使用的系统技术主要是“Seccomp”(具体到这里是Seccomp-BPF,它是Seccomp的一个扩展)。

        在讨论具体的两层实现和相关技术之前,笔者这里先介绍一下如何在Linux系统中编译和启动沙箱机制。在Linux系统上,读者如果想尝试启用Chromium的沙箱机制,需要按照以下三个步骤来进行:第一,先单独编译目标“chrome_sandbox”,它是独立于编译目标“chrome”的,所以在编译“chrome”目标的时候并不会编译“chrome_sandbox”;第二,运行脚本“build/update-linux-sandbox.sh”,它会将编译完的文件安装到合适的位置;第三,在“.bashrc”中假如“export CHROME_DEVEL_SANDBOX=/usr/local/sbin/chrome-devel-sandbox”即可。这样,Chromium浏览器就能够使用沙箱机制了。

        启动沙箱机制之后,如果运行Chromium程序,读者就可以看出如图12-9所给出的进程层次结构树。这是一棵树结构,树的根节点就是“browser”进程,该进程启动后,会孵化出多个子进程,包括图中的“GPU”、“chrome_sandbox”等进程。而对于沙箱模型来说,这里主要关注“chrome_sandbox”进程,它的目的主要是使用“setuid”技术来实现模型的第一层,生成了“zygote”子进程。其中“chrome_sandbox”进程使用的是上面介绍的目标“chrome_sandbox”生成的二进制可执行文件,而其他的是目标“chrome”生成的结果,二者是不一样的。

                                图12-9 使用沙箱机制后的进程和进程层次树

        生成第一个“zygote”之后,该进程会生成两个子进程,第一个是“nacl-helper”进程,是为了支持NaCl插件进程服务的。第二个又是一个“zygote”,这个不同于它的父亲,它主要是为了生成各种“Renderer”进程服务。这样,每个“Renderer”进程经过上面的过程后都会使用沙箱机制进行处理,网页在“Renderer”中的运行就受到了严格地限制。

        读者可能疑惑,既然“Renderer”进程根本不能访问各种资源,也不能调用各种系统调用,那么需要使用一些功能怎么办呢(如访问文件系统)?答案是使用一个代理来完成,代理进程和这些“Renderer”进程之间通过进程间通信机制来交互,所有的请求都发送给代理进程,代理进程将结果返回给“Renderer”进程,这里的代理进程就是“Browser”进程,“Browser”进程拥有访问这些资源和系统调用的权限。

        首先讨论一下第一层是如何支持的,其中主要使用两种技术。

  • 使用“setuid”来为新进程设置新用户ID和组ID,根据Linux的规定,两个不同用户ID之间的数据是隔离开的,这自然将“Renderer”进程同“Browser”进程分开,后者拥有访问很多关键数据的能力,如各个网页的Cookie。在现在的Chromium实现中,不再使用“setuid”来实现,而是使用“CLONE_NEWPID”标记,该标记是在Linux系统调用“clone”时设置,从而为新进程创建一个新的名空间,也就是上面描述的文件系统等。
  • 限制网络访问,Chromium使用标记“CLONE_NEWNET”设置在调用“clone”系统调用的参数中。使用了这些技术之后,克隆出来的进程就同父进程分离开来,包括新文件系统(类似于chroot)等和限制网络的访问等。

        接下来是第二层的讨论,这里使用的主要技术是“Seccomp”和“Seccomp-BPF”。Seccomp是Linux内核提供的一种简单的沙箱机制,它能够允许进程进入一种不可逆的安全状态,进入该状态的进程只能够调用4个系统调用,包括“exit”、“sigreturn”、“read”和“write”,而且最后两个系统调用只能操作已经打开的文件描述符。如果该进程尝试调用其他的系统调用,那么内核会通过“SIGKILL”信号来杀死该进程。进入该安全状态的方法就是使用系统调用prctl设置标记位PR_SET_SECCOMP就可以了,前提是系统的内核在编译的时候就加入了对“Seccomp”的支持,这一点很重要,因为不是所有使用Linux内核的操作系统都能打开该机制。

        “Seccomp-BPF”是“Seccomp”技术的一个扩展,它允许使用BPF所定义的方法来将系统调用转变成BPF格式的小程序。BPF(Berkeley Packet Filter)原是Berkeley开发的一种用来过滤网络包的技术,现在被应用在“Seccomp”。“Seccomp-BPF”将系统调用转变成BPF格式的小程序,这些小程序能够被内核所解释,这样每个系统调用的次数和参数都能够被重新评估或者被限制。

对于开发者来说,如果想要关闭第二层的沙箱技术也很简单,在命令行中加入参数“--disable-seccomp-filter-sandbox”就可以了。

        以上的技术不仅应用在Linux系统之上,而且也被应用在ChromeOS中。过去还有些技术用来实现第一层和第二层,如SELinux,Seccomp-legacy,因为上面介绍的技术更加合适,所以现在它们已经被丢弃了。

        对于Android系统来讲,虽然Android是基于Linux内核开发出来的,但还是有些区别的。目前沙箱机制的第二层在Android上并没有得到支持,只是第一层得到了支持。但是,在Android上,系统支持的安全机制都已经在Chrome的Android版上得到了启用,主要体现在两个方面,第一是SUID,Android系统上稍微有些不同,它是UID isolation(UID隔离技术),Android可以为每一个进程设置一个新的UID,这样每个进程之间就不能随意修改和访问数据,这是有Linux内核机制来保证的,其实是上面讨论的沙箱机制的第一层。第二是Android的权限机制,每个进程只能访问授权的权限列表中的数据,如地理位置信息、通讯录等,这个是用户数据的隐私管理,不在Chromium的沙箱机制范围内,这里不再讨论。

2.2.2 Windows

        Windows的沙箱模型也是基于图12-8的多进程结构,不同于Linux的是它们依赖的操作系统的安全机制不同,在Windows系统中,沙箱模型依赖于三个方面的技术:令牌(Token)、Windows Job对象和Windows Desktop对象。

        在Windows中,令牌是进程访问资源的证件,每个进程都有一个令牌,令牌里面包含了一个SID和多个组的SID。而对于资源来说,每个资源都包含一个安全描述符,里面包含了一个列表称为ACL(Access control list),表中的每个项ACE标记了一个访问规则,描述了SID是否允许访问、读写、执行等操作。Chromium为Renderer进程设置了极为严格的令牌,如下面所示。

    Regular GroupsLogon SID : mandatoryAll other SIDs : deny only, mandatoryRestricted GroupsS-1-0-0 : mandatoryPrivilegesNone

        使用了上面设置的令牌,读者基本上找不到一个Windows上的资源可以访问,这一令牌就是沙箱模型在Windows上使用的令牌。但是,由于Windows认为网络和系统的磁盘卷不是一个安全问题,这也就是意味着Renderer进程或者其他目标进程仍然能够发送和接收网络消息,读写磁盘卷信息。

        但是,令牌还是不能够对某些方面做出限制的,所以接下来介绍的是Windows的Job对象。当一个进程运行在Job对象中的时候,更多方面受到了限制。

        禁止进程通过系统调用“SystemParametersInfo”修改系统设置,如设置屏保时间和鼠标左右键设置等,禁止进程创建更多桌面或在不同桌面间来回切换等,禁止读写剪切板,禁止修改屏幕分辨率等相关设置。

        还有非常多的功能可以通过Job对象被禁止,更多的详情请读者查阅“http://www.chromium.org/developers/design-documents/sandbox”来了解。不仅如此,Job对象还能够防止对CPU、内存和IO等资源的无限制使用。

        最后是使用Windows的“Desktop”对象来为所有Renderer进程(或者其他进程如NaCl)构建一个新桌面。因为在桌面内发送或者接收消息是允许的,而且没有受到任何安全策略的限制。Chromium为了阻止这种事情的发生,为所有的目标进程创建一个新桌面,这也意味这这些目标进程没有办法向其他桌面的进程任意发送消息。

        在Windows Vista上,还需要使用完整性级别(Integrity Levels),它规定了5种资源访问的级别,包括untrusted、low、medium、high和system,这个级别依次从低到高。如果一个资源的访问级别高于令牌访问的级别,那也会被禁止。

        从上面的讨论可以看出,Chromium引入的沙箱机制极大地降低了网页中各种破坏操作系统的潜在风险,将网页的执行置于一个孤立(Isolated)和受限制(Strict)的环境中。安全问题始终是一个重要议题,笔者认为,这必将是浏览器或者Web运行环境中的一个发展方向。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/644001.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

每日一道算法题 16(2023-12-29)

package com.tarena.test.B20; import java.util.Arrays; import java.util.Scanner; /** * * 题目描述: 输入一个由n个大小写字母组成的字符串,按照Ascii码从小到大的排序规则,查找字符串中第k个最小ascii码值的字母(k>…

计算机设计大赛 交通目标检测-行人车辆检测流量计数 - 计算机设计大赛

文章目录 0 前言1\. 目标检测概况1.1 什么是目标检测?1.2 发展阶段 2\. 行人检测2.1 行人检测简介2.2 行人检测技术难点2.3 行人检测实现效果2.4 关键代码-训练过程 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 毕业设计…

Vue 的 事件修饰符and按键修饰符

1、事件修饰符概览 修饰符说明 .prevent阻止默认事件 .stop阻止冒泡.once事件只触发一次 .capture 添加事件侦听器时使用事件捕获模式.self只有点击当前元素本身时才会触发回调.passive事件的默认行为立即执行,无需等待事件回调执行完毕(不常用).native 将vue组件…

uniapp开发过程一些小坑

问题1、uniapp使用scroll-view的:scroll-into-view“lastChatData“跳到某个元素id时候,在app上不生效,小程序没问题 使用this.$nextTick或者 setTimeout(()>{that.lastChatData 元素id },500) 进行延后处理就可以了。 问题2:uniapp开…

c#算法(10)——求点到直线的距离

前言 在上位机软件开发领域,特别是机器视觉领域,经常会遇到尺寸测量的场景,比如让我们求一个点到一条直线的距离,我们已知了直线上的两个点的坐标,然后又已知了直线外的一个点的坐标,那么如何求出该直线外的一点到直线的距离呢?本文就是来讲解如何求点到直线的距离的,…

ssh登录失败:connection closed by foreign host

问题1: ssh登录不上,连接上就断掉 inetd.conf显示2277已打开,ip也没有冲突。 但是这两个文件是空的(size 0k): dropbear_dss_host_key dropbear_rsa_host_key 把/etc/dropbear里面的东西删掉,重新生成秘钥文件: …

2024年制造业展望

制造业是国民经济的主体,其重要性不言而喻。就2023年而言,制造业在技术创新、数字化转型和可持续发展方面都取得了重要的进展。以下是对于2024年制造业的发展进行的分析与预测。 1 保持业务平衡仍将是一项挑战 在过去的四年里,制造业高管人…

【STM32CubeMX串口通信详解】USART2 -- DMA发送 + DMA空闲中断 接收不定长数据

( 本篇正在编写、更新状态中.....) 文章目录: 前言 前言 本篇,详细地用截图解释 CubeMX 对 USART2 的配置,HAL函数使用,和收发程序的编写。 收、发机制:DMA发送 DAM空闲中断接收。 DMA空…

142基于matlab的移动力过简支梁程序

基于matlab的移动力过简支梁程序,算法采用newmark-belta法,输出简支梁,求解静力位移,自振特性,动力特性。可调节简支梁参数。程序已调通,可直接运行。 142 matlab简支梁自振特性 (xiaohongshu.com)

企业IT基础资源管理的“帮帮团”上线啦——源启云原生基础设施管理平台

为助力企业提升基础资源一体化管理和交付效率,以更先进的基础设施管理方式来满足现代企业业务持续扩展和复杂化的需要,中电金信运用基础设施即代码(Infrastructure as Code,简称IaC)技术,研发推出源启云原生…

【Python】01快速上手爬虫案例一

文章目录 前言一、VSCodePython环境搭建二、爬虫案例一1、爬取第一页数据2、爬取所有页数据3、格式化html数据4、导出excel文件 前言 实战是最好的老师,直接案例操作,快速上手。 案例一,爬取数据,最终效果图: 一、VS…

光流估计概念和算法

什么是光流? 光流就是物体和观测者之间的互相运动,亮度变化的速度矢量,下图两张图片表示了光流的原理。 光流的算法有几个基本不变的假设: 1,光强不变假设; 一元的n阶泰勒公式: 在这里插入图…

HTTP与HTTPS的工作流程

HTTP与HTTPS的工作流程 http知识点回顾1、HTTP访问的过程2、HTTP常见状态码3、HTTP 协议一共五大特点 https的工作流程1、对称加密2、非对称加密3、https工作流程 http知识点回顾 1、HTTP访问的过程 (1)解析url,获取 url 中包含的域名&…

C语言第七弹---循环语句

✨个人主页: 熬夜学编程的小林 💗系列专栏: 【C语言详解】 【数据结构详解】 循环语句 1、while循环1.1、if和while的对比1.2、while语句的执行流程1.3、while循环的实践1.4、练习 2、for循环2.1、语法形式2.2、for循环的执行流程2.3、for循…

沃通服务器密码机(WTHSM)

概述 沃通服务器密码机(WTHSM)由沃通CA自主设计开发,严格遵照国密局颁布技术规范,获得国密局颁发《商用密码产品认证证书》,是一款多安全功能、高稳定性、可扩展和快速部署的软硬件集成化安全设备,为应用提…

【手撕C语言 第八集】函数栈帧的创建与销毁

文章目录 一、什么是函数栈帧?二、函数栈帧能解决什么问题呢?(1)局部变量是如何创建的?(2)为什么局部变量不初始化内容是随机的?(3)函数调用时参数是如何传递…

电磁兼容设计要点

电磁兼容的问题往往发生于高频状态下,个别情况除外(Dips电压暂降与中断)除外。高频思维,总而言之,就是器件的特性、电路的特性,在高频情况下和常规中低频状态下是不一样的,如果仍然按照普通的控…

Go 定时器:如何避免潜在的内存泄漏陷阱

这篇文章将探讨的是 Go 中如何高效使用 timer,特别是与select 一起使用时,如何防止潜在的内存泄漏问题。 引出问题 先看一个例子,我们在 Go 中的 select 使用定时器,实现为消息监听加上超时能力。 核心代码,如下所示…

已解决Error:AttributeError: module ‘numpy‘ has no attribute ‘bool‘.

文章目录 引言报错分析解决方案1:降低NumPy版本解决方案2:更改NumPy源码 结尾 引言 在Python编程的世界里,NumPy无疑是一个不可或缺的库。它不仅在处理大规模数值计算中发挥着核心作用,而且为众多开发者提供了强大的支持。然而&a…

无刷电机学习-方波电调 程序篇1(AM32)

一、AM32简介 AM32 固件专为 ARM 处理器设计,用于控制无刷电机 (BLDC)。该固件旨在安全、快速、平滑、快速启动和线性油门。它适用于多种车辆类型和飞行控制器。 AM32具有以下特点: 可通过 betaflight 直通、单线串行或 arduino 升级固件伺服 PWM、Dsh…