Chromium sanbox技术
Author:zhoulujun Date:
在linux运行Puppeteer的时候,终于搞定了chrome安装问题,但是
No usable sandbox! Update your kernel or see chromium.googlesource.com/chromium/sr… for more information on developing with the SUID sandbox. If you want to livedangerously and need an immediate workaround, you can try using --no-sandbox.
需要加上
const browser = await puppeteer.launch({args: ['--no-sandbox', '--disable-setuid-sandbox']});
那么既然--no-sandbox,那--disable-setuid-sandbox是什么鬼?
Chromium沙箱
安全是Chromium最重要的目标之一,但 Chromium 渲染引擎涉及大量C++编写的组件,出现漏洞的概率不小。因此,基于纵深防御理念浏览器引入了涉及三层结构。
Chromium涉及的组件众多,使用的C++语言天然决定了会潜在不少安全问题。例如:一个V8中的内存安全问题(如:CVE-2021-21220、CVE-2019–5782),组合Web Assembly将Shellcode写入RWX Pages,在未受沙箱保护的情况下,就能实现远程代码执行。
沙箱机制组合使用了OS相关的隔离能力(如:Linux平台上的namespace、Seccomp-BPF机制),限制了被沙箱保护进程的资源访问以及syscall能力,能很好的防止出现在渲染引擎中的漏洞,被用于直接实现RCE :但沙箱机制也存在一些不足,历史上也出现过沙箱逃逸的漏洞,例如:Google Project Zero团队曾发布的《Virtually Unlimited Memory: Escaping the Chrome Sandbox》一文。
在无法100%预防Chromium渲染进程出现内存安全问题的情况下,开启沙箱保护是一项必须落地的最佳安全实践。
渲染引擎等组件不直接与系统交互,而是通过一个被称为MOJO的IPC组件与浏览器引擎通讯(也被称为:broker),再与系统交互。进而可以实现:即便沙箱中的进程被攻破,但无法随意调用系统API产生更大的危害。
有点类似:即便攻破了一个容器实例,在没有逃逸或提权漏洞的情况下,宿主机安全一定程度上不受影响(实际上,浏览器的Sandbox和容器隔离的部分技术原理是相似的)。
http://src.chromium.org/viewvc/chrome/trunk/src/sandbox/
不要重新发明轮子: 用更好的安全模型扩展操作系统内核很有诱惑力。但不要这样做。让操作系统在所控制的对象上应用它的安全策略。另一方面,创建有自定义安全模型的应用程序层级对象(抽象)是可以的。
最小权限原则: 这既应该用于沙箱代码也应该用于控制沙箱的代码。换言之,即使用于不能提升权限到超级用户,沙箱也需要能够工作。
假定沙盒代码是恶意代码: 出于威胁建模的目的,我们认为沙箱中的代码一旦执行路径越过了一些main()函数的早期调用,那么它是有害的(即,它会运行有害代码),实践中,在第一外部输入被接收时,或者在进入主循环前,这就可能发生。
敏感: 非恶意代码不会尝试访问它不能获得的资源。在这种情况下,沙箱产生的性能影响应该接近零。一旦敏感资源需要以一种控制行为访问时,一点性能损失是必要的。这是在操作系统安全合适事情情况下的常见例子。
仿真不是安全: 仿真和虚拟机方案本身不能提供安全。沙箱不会出于安全目的,依赖于代码仿真,或者代码转换,或者代码修复。
浏览器的哪些部分是运行在沙箱中的?
浏览器渲染引擎、GPU、PPAPI插件以及语音识别服务等进程是运行在沙箱中的。此外不同系统平台下的部分服务也会受沙箱保护,例如Windows下打印时调用的PDF转换服务、icon浏览服务;MacOS下NaCl loader、需要访问IOSurface的镜像服务等。
更多细节可查阅Chromium项目文件sandbox_type.h和sandbox_type.cc中的源码定义
Windows和Linux下沙箱实现的技术细节
Windows
在Windows平台上,Chrome组合使用了系统提供的Restricted Token、Integrity Level、The Windows job object、The Windows desktop object机制来实现沙盒。其中最重要的一点是,把写操作权限限制起来,这样攻击这就无法通过写入文件或注册表键来攻击系统。
Linux
Chrome在Linux系统上使用的沙箱技术主要涉及两层:
第一层沙箱采用setuid sandbox方案
其主要功能封装在二进制文件chrome_sandbox内,在编译项目时需要单独添加参数“ninja -C xxx chrome chrome_sandbox”编译,可以通过设置环境变量CHROME_DEVEL_SANDBOX指定Chrome调用的setuid sandbox二进制文件。
setuid sandbox主要依赖两项机制来构建沙盒环境:CLONE_NEWPID和CLONE_NEWNET方法。
CLONE_NEWPID一方面会借助chroots,来限制相关进程对文件系统命名空间的访问;另一方面会在调用clone()时指定CLONE_NEWPID选项,借助PID namespace,让运行在沙盒中的进程无法调用ptrace()或kill()操作沙盒外的进程。
CLONE_NEWNET则用于限制在沙盒内进程的网络请求访问,值得一提的是,使用该方法需要CAP_SYS_ADMIN权限。
这也使得当Chrome组件在容器内运行时,沙箱能力所需的权限会和容器所管理的权限有冲突;我们无法用最小的权限在容器里启动Chrome沙箱,本文4.2.2部分会详细阐述此处的解决之道。
Chrome/Chromium沙箱 - 安全架构设计 https://cloud.tencent.com/developer/article/1009457
* 更多详参见Linux Namespace及cgroups介绍说明:
"Resource management: Linux kernel Namespaces and cgroups"
-https://sites.cs.ucsb.edu/~rich/class/cs293b-cloud/papers/lxc-namespace.pdf
由于setuid sandbox方案存在一定短板。自Chrome 44版本起已推荐namespaces sandbox来替代setuid sandbox方案,其主要依赖于Linux内核提供的user namespaces机制,相关逻辑可在项目的如下行代码看到:
第二层沙箱采用Seccomp-BPF方案,用来限制进程访问内核特定攻击面
其原理是:通过将Seccomp和BPF规则结合,实现基于用户配置的策略白名单,对系统调用及其参数进行过滤限制。
// sandbox/policy/linux/sandbox_linux.cc
Line 413 StartSeccompBPF(sandbox_type, std::move(hook), options)
参考文章:
攻防启示:Chromium组件风险剖析与收敛 https://www.secrss.com/articles/32671
puppeteer填坑指南 https://zhangzippo.github.io/posts/2019/04/25/_25puppteererror.html
Puppeteer 通用 SSR 服务端渲染 https://blog.cjw.design/blog/frontend/puppeteer-ssr
Chrome/Chromium沙箱 - 安全架构设计 https://cloud.tencent.com/developer/article/1009457
转载本站文章《Chromium sanbox技术》,
请注明出处:https://www.zhoulujun.cn/html/webfront/browser/Puppeteer/9443.html