【AICon】探索RAG 技术在实际应用中遇到的挑战及应对策略!AICon精华内容已上线73%>>> 了解详情
写点什么

谷歌开源 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:213107

评论

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

Databend x HuggingFace,海量数据,随心分析

Databend

开发一个体育直播软件和网站平台需要哪些东西

软件开发-梦幻运营部

X Winner受邀出席泰国政府加密峰会,上演未来独角兽的独角戏

股市老人

听GPT 讲Rust源代码--compiler(24)

fliter

2024年了,为什么我还是舍弃不掉 RSS?

伤感汤姆布利柏

POKT Network 开启周期性通缩,该计划将持续至 2025 年

股市老人

听GPT 讲Rust源代码--compiler(27)

fliter

图像处理-Java-去噪/高斯模糊/套红

alexgaoyh

Java 图像处理 去噪 高斯模糊 套红

微服务架构设计模式PDF

程序员李木子

云原生微服务:现代化应用开发的支柱

不在线第一只蜗牛

微服务 云原生 架构开发

技术分享| 利用 Google MFA 实现 Amazon linux 2023 身份校验

伊克罗德信息科技

怎么在Solana区块链发币?这篇教程让你5分钟学会Sol一键发币

加密先生

区块链、 Solana

2023 IoTDB Summit:湖南大唐先一科技有限公司主任架构师舒畅《IoTDB 在发电领域的应用实践》

Apache IoTDB

“元”启未来 · 万象“新”生!合肥少荃湖畔等你来

声网

C# 数据类型与类型转换:包含教程与示例

小万哥

C# 程序人生 编程语言 软件工程 后端开发

Java核心技术·卷I(原书第12版)PDF

程序员李木子

跨境电商的税收政策:卖家需关注的合规问题

技术冰糖葫芦

听GPT 讲Rust源代码--compiler(26)

fliter

奶茶上云,原生的更好喝

阿里巴巴云原生

阿里云 云原生

稳定币智能分析:未来加密领域策略的关键!

Footprint Analytics

区块链 Token 稳定币

基于 Hologres+Flink 的曹操出行实时数仓建设

Apache Flink

听GPT 讲Rust源代码--compiler(25)

fliter

《Java解惑》PDF

程序员李木子

图像处理锐化-Java-Prewitt算子叠加

alexgaoyh

图像处理 锐化 prewitt算子 噪点 叠加

【智驾未来】低代码开发:加速创新交融的利器

快乐非自愿限量之名

人工智能 车联网 低代码 智能驾驶

Java语言程序设计(基础篇 原书第10版)PDF

程序员李木子

阿里云云原生弹性方案:用弹性解决集群资源利用率难题

阿里巴巴云原生

阿里云 云原生 弹性

首次公开发声,OpenAI CEO 奥特曼回忆“宫斗门”丨 RTE 开发者日报 Vol.129

声网

用过都说好!FigJam在线白板使用技巧&替代软件推荐!

彭宏豪95

效率工具 在线白板 办公效率 在线协作 boardmix

为什么在数学的意义上GraphQL严格的优于REST?

canonical

DDD 低代码 graphql

海外项目管理工具 Jira 宣布Data Center版涨价5%-15%,6年内第8次提价

PingCode

Atlassian Jira

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