产品战略专家梁宁确认出席AICon北京站,分享AI时代下的商业逻辑与产品需求 了解详情
写点什么

谷歌开源 Sandboxed API,可对单个软件库进行安全保护

  • 2019-03-25
  • 本文字数:2681 字

    阅读完需:约 9 分钟

谷歌开源Sandboxed API,可对单个软件库进行安全保护

很多软件项目需要处理外部生成的数据,因此不能被完全信任。 例如,将用户提供的图片文件转换为不同的格式,或者是执行由用户生成的软件代码等。



如果软件库对这类数据的解析过程特别复杂的话,它很有可能会成为某些特定安全漏洞的受害者:安全漏洞诸如内存损坏,又或者是跟解析逻辑相关的的问题(路径遍历问题)。这些安全漏洞可能会造成很严重的安全问题。


为了缓解这些问题,开发人员通常使用软件隔离的方法,这种方法又被称作沙箱技术。 通过使用沙盒的方式,开发人员可以限制那些需要解析外部数据的代码,确保它们只能访问特定的文件、网络连接和其他操作系统资源。 这样最坏的情形就是,即使潜在的攻击者获取了这些代码的执行权限,他们也只能访问沙箱范围内的资源,沙箱技术将它们一并隔离了,这有效保护了其余的软件基础设施。


沙箱技术必须对攻击具有高度的防御性,能够充分保护操作系统的其它部分,同时又需要容易使用,从而让软件开发人员快速上手。 对于当前很多流行的软件隔离工具来说,它们要么无法充分隔离操作系统的其余部分,要么需要额外消耗大量时间来为每个项目重新定义安全边界。

实现一次,到处运行

为帮助这个目标的实现,谷歌开源了项目Sandboxed API(沙箱 API),该项目已在谷歌内部广泛使用,久经考验。通过 Sandboxed API,开发者可以为单个软件库创建安全策略,也就是说我们能够在软件类库内部为功能创建可重用的和安全的实现,而它的隔离粒度又刚好能保护其它被使用的软件基础设施。


Sandboxed API 主要用于访问沙箱类库中的某个软件函数,我们还开源了沙箱项目的核心 Sandbox2。 Sandox2 现在已经是 Sandboxed API 的一部分,提供了底层沙箱原语。它又被认为是一种底层 API,可以单独使用来隔离任意的 Linux 进程。

实现机制

目前 Sandboxed API 主要用于 C 语言编写的软件类库(或提供 C 绑定),未来可能会实现对更多编程语言的支持。


从全局的角度看,Sandboxed API 把沙箱里的库以及库的调用者分离到两个不同的系统进程中:宿主机二进制进程和 Sandboxee(沙箱)进程。 宿主机端的 API 对象重新封装了实际的库调用,并通过进程间通信发送到 Sandboxee,然后由 Sandboxee 中的 RPC Stub(存根)对调用重组并把它转发到原始库。


API 对象(SAPI 对象)和 RPC Stub 都由项目本身提供,前者由接口生成器自动生成。 用户只需要提供一个沙箱策略,一组允许底层库使用的系统调用,以及允许访问和使用的资源。 一旦这些条件就绪,基于 Sandboxed API 的库就可以很容易地在其他项目中重用了。



SAPI 对象的 API 同原始库的 API 非常类似。 例如,当使用流行的压缩库 zlib 时,如下代码片段实现了一个数据块的压缩(为简洁起见,我们在这里忽略了错误处理) :


void Compress(const std::string& chunk, std::string* out) {  z_stream zst{};  constexpr char kZlibVersion[] = "1.2.11";  CHECK(deflateInit_(&zst, /*level=*/4, kZlibVersion, sizeof(zst)) == Z_OK);

zst.avail_in = chunk.size(); zst.next_in = reinterpret_cast<uint8_t*>(&chunk[0]); zst.avail_out = out->size(); zst.next_out = reinterpret_cast<uint8_t*>(&(*out)[0]); CHECK(deflate(&zst, Z_FINISH) != Z_STREAM_ERROR); out->resize(zst.avail_out);

deflateEnd(&zst);}
复制代码


而如果使用 Sandboxed API,代码将会变成:


void CompressSapi(const std::string& chunk, std::string* out) {  sapi::Sandbox sandbox(sapi::zlib::zlib_sapi_embed_create());  CHECK(sandbox.Init().ok());  sapi::zlib::ZlibApi api(&sandbox);

sapi::v::Array<uint8_t> s_chunk(&chunk[0], chunk.size()); sapi::v::Array<uint8_t> s_out(&(*out)[0], out->size()); CHECK(sandbox.Allocate(&s_chunk).ok() && sandbox.Allocate(&s_out).ok()); sapi::v::Struct<sapi::zlib::z_stream> s_zst; constexpr char kZlibVersion[] = "1.2.11"; sapi::v::Array<char> s_version(kZlibVersion, ABSL_ARRAYSIZE(kZlibVersion)); CHECK(api.deflateInit_(s_zst.PtrBoth(), /*level=*/4, s_version.PtrBefore(), sizeof(sapi::zlib::z_stream).ValueOrDie() == Z_OK));

CHECK(sandbox.TransferToSandboxee(&s_chunk).ok()); s_zst.mutable_data()->avail_in = chunk.size(); s_zst.mutable_data()->next_in = reinterpet_cast<uint8_t*>(s_chunk.GetRemote()); s_zst.mutable_data()->avail_out = out->size(); s_zst.mutable_data()->next_out = reinterpret_cast<uint8_t*>(s_out.GetRemote()); CHECK(api.deflate(s_zst.PtrBoth(), Z_FINISH).ValueOrDie() != Z_STREAM_ERROR); CHECK(sandbox.TransferFromSandboxee(&s_out).ok()); out->resize(s_zst.data().avail_out);

CHECK(api.deflateEnd(s_zst.PtrBoth()).ok());}
复制代码


通过对比我们可以发现,在使用 Sandboxed API 时,需要额外的代码来设置沙箱本身以及将内存传入或传出到 Sandboxee,但除此之外,代码流保持不变。

安装测试

我们只需要几分钟时间就可以启动并运行 Sandboxed API。假设已经安装了 Bazel:


sudo apt-get install python-typing python-clang-7 libclang-7-dev linux-libc-devgit clone github.com/google/sandboxed-api && cd sandboxed-apibazel test //sandboxed_api/examples/stringop:main_stringop
复制代码


上述操作会自动安装必要的依赖项,并运行测试项目。 更详细内容可查阅入门指南,尤其是关于 Sandboxed API 的使用示例

未来计划

Sandboxed API 以及 Sandbox2 已经被谷歌内部的很多团队所使用。虽然这个项目已经很成熟,但开发团队对其未来发展仍然充满期待,而不仅仅限于维护:


  • 支持更多的操作系统—目前为止,只支持 Linux。 开发团队将研究如何把 Sandboxed API 引入到类 Unix 系统,如 BSD(FreeBSD、OpenBSD),macOS 以及 Windows 系统。移植到 Windows 系统是一项更复杂的任务,需要更多的基础工作。

  • 新的沙盒技术—随着硬件虚拟化技术的普及,通过沙盒将代码限制在虚拟机中变成了可能。

  • 系统构建—我们目前使用 Bazel 构建项目,包括处理依赖项。 但这并不是每个人都想要的方式,对 CMake 编译的支持是我们的首要任务。

  • 推广—用 Sandboxed API 来保护开源项目,该项目属于补丁奖励计划,参与者将有机会获得开发奖励。

参与进来

除了对 Sandboxed API 和 Sandbox2 的优化,该项目开发团队一直致力于增加更多的功能:支持更多的编程运行时、不同的操作系统以及可替代的容器技术。


源码码请查看Sandboxed API GitHub仓库。欢迎大家积极参与,贡献代码或任何关于项目改进和扩展的建议。


2019-03-25 17:213294

评论

发布
暂无评论
发现更多内容

跨平台的键鼠共享工具 synergy mac 中文激活版

Rose

数据结构 - 散列表,三探之代码实现

不在线第一只蜗牛

数据结构

如何通过指标驱动研发体系建设

思码逸研发效能

DevOps 研发效能 效能度量 研发效能管理 思码逸

程序员提效的 10 个方法,建议收藏

秃头小帅oi

如何成为一名优秀的程序员,进来看看

伤感汤姆布利柏

实时特征框架的生产实践|得物技术

得物技术

flink 性能优化 数据平台 特征框架

CAD迷你看图 Mac破解版 v4.4.5免激活版

Rose

指标平台在企业数据管理中的定位及其如何与BI、数仓的协同工作?

Aloudata

数据分析 指标体系 指标平台 指标开发

最大程度降低“去O”的迁移风险

NineData

数据库 复制 迁移 同步 NineData

能操控电脑的 Computer Use 究竟是什么?万能胶水、旧世界操作员,还是无所不在的智能?| 播客《编码人声》

声网

全新HUAWEI MatePad 11.5发布:搭载华为教育中心,做更好的学习神器

最新动态

什么是无代码?无代码开发平台又是什么?

积木链小链

无代码 无代码平台

通义灵码知识库问答增强:知识库构建与管理指南

阿里巴巴云原生

阿里云 云原生 通义灵码

这10种分布式ID,太绝了!

EquatorCoco

分布式

指标预警归因分析,及时发现业务问题,快速定位问题根因

Aloudata

数据分析 指标平台 指标开发

鸿蒙开发案例:打地鼠

zhongcx

知识管理系统是什么?

ServiceDesk_Plus

知识管理系统 知识管理软件

从人员外包到测试工具、测试平台,提供全方位的测试解决方案~

霍格沃兹测试开发学社

OmniGraffle Pro:绘图巅峰,设计卓越!

Rose

AI 原生时代,更要上云:百度智能云云原生创新实践

百度Geek说

LeetCode题解:2648. 生成斐波那契数列,迭代+递归,超详细解析

Lee Chen

薅羊毛了!百万度算力免费申领活动狂欢继续!

九章云极DataCanvas

One Switch for Mac(系统功能快速开关工具) v1.33.1中文版

Rose

Alfred 5中文安装包 Mac 上的效率瑰宝!

Rose

老好人无法成为好的管理者

老张

团队管理 技术管理 绩效管理

电子签软件是什么?概念以及主流产品分析

爱吃小舅的鱼

软件

ElevenLabs Voice Design:文本生成个性化语音;科学家用 AI 解读猪叫声背后情绪和压力丨RTE 开发者日报

声网

软件测试学习笔记丨Flask框架-请求与响应

测试人

flask 软件测试

spring-关于组件的注入及获取流程

快乐非自愿限量之名

Java Spring Boot 后端

通义灵码知识库问答增强:知识库构建与管理指南

阿里云云效

阿里云 云原生 通义灵码

立足云南,面向“两亚”,翻开普惠算力新篇章

九章云极DataCanvas

谷歌开源Sandboxed API,可对单个软件库进行安全保护_安全_Google Security_InfoQ精选文章