题目: TrustJS: Trusted Client-side Execution of JavaScript
作者: David Goltzsche, Colin Wulf, Divya Muthukumaran, Konrad Rieck, Peter R. Pietzuch, Rüdiger Kapitza
单位: TU Braunschweig and Imperial College London
出版: EUROSEC 2017
阅读前的思考:
- 从目前来看,就结合对象上来看,SGX和Windows结合的有Haven,和Linux结合的有Graphene,和Docker结合的有SCONE,和Web Browser结合的尚且没有。
- 就保护的具体目标上看:可以保护系统,也可以保护驱动,可以保护程序,甚至可以只保护数据(如V3)。SGX可以保护代码,也可以保护数据。就前端来看,我们可以保护浏览器不被恶意JS破坏,也可以保护数据不被浏览器窃取。
- 从另一个侧面来说,SGX目前保护的都是C程序。语言运行时支持的不足是一个局限性。百度Xlab有一个团队专门做SGX对Rust应用的支持。本文是不是可以给JS代码做支持呢?
附:https://github.com/baidu/rust-sgx-sdk
解决问题:
- 服务提供商认为前端客户端不可信,前端的输入很容易被修改,后端要做重复校验工作;
- JS代码的IP专利从未被保证,客户端可以很容易看到算法和商业逻辑。
贡献点:
- 第一个借助SGX保护JS代码的工作。
做法:
- 编写Firefox扩展,同时在浏览器内部添加可信JS之执行引擎(一个独立的解释器),负责在运行时做保护。
挑战:(本文提到的SGX的局限性)
- Enclave不支持系统调用(我在试用Linux版本SGX SDK时候深有体会);
- Enclave不支持内存管理,目前1代和2代在Enclave启动后就杜绝一切重定位,即不支持动态加载;
- EPC的物理大小限制在128MB,但支持虚拟内存,可是性能开销十分巨大!
假设:
- 用户不相信JS代码,因此要把执行限制在Enclave内,因为其余的JS对其都是可见的;
- 攻击者可获取客户端的全控制权(CPU以外),可以终止Enclave运行,但无法获取信息;
- 不考虑旁路;
- Enclave的代码没有bug;
- SGX设计与实现无误。
设计:
- 和Ryoan一样,每个Enclave是双向沙盒。服务提供者SP提供代码,浏览器内interpreter enclave (IE)负责执行,需提供可信通道(可信路径);
- 不提供eval(),因为不支持动态技术;
- 局限点:依赖用户判断和选择是否对某个页面启用插件,因为不可信服务提供商可以借此隐藏信息。
实现:
- 使用js-ctypes,类似JNI,实现JS和C代码的交互;
- 轻量级解释器MuJS(14KLOC),不支持JIT,类似LibOS之于Haven。
实验:
- 延迟:使用Keyed-Hash Message Authentication Code (HMAC)后,服务器不进行重复计算可减少延迟,但Enclave本身引入远程验证时间。延迟取决于协议。当前HTTP协议下RTT往返时间从原来的109ms到现在的343ms。(该模型和多方计算很类似。)
- 可扩展性:一些重复校验的工作在服务器端就不必要了,全CPU负载下,从原来的可同时服务250个客户端到700个左右。
未来工作:
- 支持JIT即时编译;
- 支持NodeJS的丰富API。
体会:
- TrustJS目前还属于原型阶段,在前端还有不少工作可以结合和突破。
- 文章虽然只有短短的6页纸,但图片十分丰富。所谓“一图胜千言”。
- 一个很好的思路是:保持原浏览器的沙盒模型,保证标签页之间的强隔离。由于浏览器会将大量数据缓存在内存中(可能由于虚拟内存部分数据会转移到外存储中),可见其是个内存密集型应用,因此用dune(直接访问内存)外加SUVM(高效用户态内存管理器)助力是个不错的选择。另外,JS程序可能有些逻辑会借助传统密码学的方式保护用户信息(在线支付、电子交易记录或医疗信息等),这里我们假设浏览器可能会被tamper,导致秘密泄露。JS翻译后的指令直接调用sgx进行保护可以很好地保护自己。另外,Enclave的启动需要远程验证,B/S模型是很自然的迁移。