CHAPTER 12: SECURITY AND FUNCTION AS A SERVICE

In this chapter, I describe how the security services defined within the SRM, and depicted in Figure 7, may be delivered by consumers implementing a service using a FaaS Cloud.

FaaS is the latest evolution of the Cloud model and it takes abstraction to its ultimate form: the running of individual ephemeral functions. With FaaS, there is no monolithic application constantly running in the background, instead, functions are triggered and executed on demand. In many ways, FaaS is similar to PaaS: consumers must still code the individual functions that make up their service, but the ephemeral nature of functions drives a number of different considerations (explored in this chapter).

There are currently three main providers offering FaaS:

1.AWS Lambda (https://aws.amazon.com/lambda/)

2.Azure Functions (https://azure.microsoft.com/en-gb/services/functions/)

3.Google Cloud Functions (https://cloud.google.com/functions/)

Of the above, AWS Lambda remains by far the best known

and most commonly deployed.

FaaS and the SRM

The rest of this chapter is dedicated to explaining how the services described within the SRM can be delivered when deploying services on an FaaS Cloud.

In order to provide some context for these discussions, it is worth considering a sample FaaS architecture such as that shown in Figure 45.

image

Figure 45: Example FaaS application architecture

Figure 45 shows an example of how a simple web application could be delivered using FaaS and other serverless technologies such as S3 and DynamoDB (a NoSQL database).235

I have split the AWS-hosted application into different zones; this is purely for the convenience of this discussion and is not driven by the network zoning that you may expect to see in a traditional n-tier architecture. All of these technologies are serverless, and consumers do not need to concern themselves with traditional network segregation issues; however, zones of trust remain relevant.

On the left of the diagram is the user's browser; it runs JavaScript that interacts with the various APIs exposed as Lambda functions by the hosted application. The web application itself is presented to the Internet via the AWS CloudFront Content Delivery Network (CDN) service and protected by the AWS WAF service. Static website content is held within, and presented by, S3. The ‘control’ zone includes AWS Cognito, for the provision of user identities and access rights,236 and the API Gateway, which controls access to the APIs offered by the various Lambda functions in the ‘application’ zone. These Lambda functions are triggered on demand by HTTPS invocations via the API Gateway – there is no continually running application per se.

However, Lambda functions are ephemeral and, consequently, there is a requirement for a mechanism237 to store items like user state – DynamoDB acts as this mechanism in the ‘persistence’ zone of our example architecture. The Google Cloud Functions service has a similar requirement for state information to be stored externally. It should be noted that Azure has an option of using Durable Functions238 which removes this restriction for users of that platform.

I will frequently refer to this example application in this chapter, so it is worth familiarising yourself with it before we move on.

Secure development

The FaaS environment shares multiple qualities with the PaaS environment in relation to development: the consumer codes their own application and so has the freedom – and responsibility – to develop as they choose. However, the FaaS paradigm does impose some constraints in terms of maximum execution times and ‘cold-start’ speed, i.e. the time it takes to spin up the micro-VM239 and run-time within which your function will run. Applications must be correctly coded to limit the number of cold starts, otherwise user experience will suffer due to poor response times.

It is worth noting that a serverless function will stay active (i.e. ‘hot’) as long as it is executing an application call and for a short period afterwards, in which it remains ready and available for another execution. However, after a period of inactivity, the Cloud container/run-time environment will timeout and your function will become inactive. The next function call will require another cold start. Users for whom performance is a key concern can ‘warm up’ their functions by calling them in advance of user needs and by continuing to call them on a regular basis to ensure that the functions stay active.

The situation is more complicated when working with multiple chained functions, such as AWS, because they can reuse a container for different functions; functions must, therefore, be called in the right order, e.g. CloudWatch Event ‘pings’ could be used to maintain the right functions in the right state. There are tools available to help keep functions warm (e.g. https://github.com/jeremydaly/lambda-warmer), but pinging functions at the wrong time or in the wrong order can have an adverse performance impact. Testing is important, though these approaches do, of course, incur a degree of cost as FaaS charges per execution.

Significantly, FaaS consumers do not have access to the underlying host, so many traditional security tools cannot be used, e.g. host-based intrusion prevention systems (IPSs) and most runtime application self-protection (RASP) products.240 RASP is in an interesting area as there are different deployment models available, and some may be suitable for use with FaaS whereas others will not; as ever, the nature of the application and supporting architecture will also impact upon the suitability of a specific RASP approach. An illustrative RASP architecture is shown in Figure 46.

image

Figure 46: RASP architecture

At a high level, RASP products can be viewed as providing WAF capabilities within the protected application, as opposed to these being abstracted out to a separate WAF capability. RASP can protect against common vulnerabilities such as SQL injection, cookie tampering, cross-site scripting as well as more generic (i.e. not just web application) issues. Figure 46 illustrates how and where RASP tools can provide security capability. RASPs can either be included, within the function requiring protection, through the provided RASP libraries or by instrumenting the run-time (e.g. the Java Virtual Machine), with the latter option providing more general protection to all hosted functions. RASP products are often designed to call out to Cloud-hosted machine learning based decision engines, which require such functionality to complement the necessarily more basic controls provided locally.

Now, a type of RASP tooling – one that simply allows security controls to be compiled into the functions through the inclusion of the provided libraries – may well be suitable for use in FaaS environments to provide some simple security capabilities. For example, Puresec provide a free security library for AWS Lambda and Google Cloud Functions, called FunctionShield241; this offers some basic security capabilities, such as the ability to disable outbound Internet access and to execute child processes. More complex RASP solutions also include the ability to make decisions based on anomaly detection, but this will often require a call-out to a Cloud-hosted decision-engine and this comes with two disadvantages from an FaaS application perspective:

1.A performance hit due to the latency associated with traversing the Internet and awaiting a synchronous response; and

2.A need to open outbound Internet access for each protected function.

The other RASP deployment mechanism illustrated in Figure 46 relates to instrumentation of the run-time itself, e.g. the Java Virtual Machine. This mechanism is clearly not available where the Cloud service provider controls the run-time and the provider has no capability to add in the required instrumentation. However, this is a rapidly evolving area, with the RASP vendors evolving their products to provide better support for FaaS offers; for example, the Twistlock RASP Defender tool can be deployed as a Lambda Layer which allows it to be reused across functions.242

Developers building with FaaS need to be cognisant of the security controls that they can implement within their application via RASP-like functionality and those which they must abstract outside of their application, for example, through the use of API gateways and WAF capabilities.

Integrity

With a FaaS approach, you are buying into the integrity of the run-time and storage services offered by the Cloud provider. FaaS architectures will typically be adopting the microservices paradigm, i.e. adhering to the following design principles243:

Autonomy

Loose coupling

Reuse

Composability

Fault tolerance

Discoverability

APIs alignment with business processes

FaaS consumers need to concern themselves with the integrity of the overall application, the individual functions and any orchestration capabilities, e.g. API gateways or service mesh components. Individual functions should be subject to signed cryptographic hashing so that their integrity can be assured. The maintenance of service integrity will be explored further in the next section, on availability.

With respect to content checking, FaaS consumers should follow the approaches outlined earlier for PaaS services, i.e. they should consider using third-party content checking tools for files and WAFs for web traffic to preserve service integrity.

Availability

For organisations adopting FaaS, one major driver is the ability to handoff the responsibility for service availability – both infrastructure and run-times scale up automatically, albeit subject to the cold start concerns described earlier.

Using the microservices approach and its associated design principles – in particular those relating to reuse, autonomy and loose coupling – developers are able to update each microservice as they see fit as long as they do not make any breaking changes to the API (unless these are carefully managed). However, the overall application functionality can be affected by changes within the individual functions that comprise the service. This being the case, it is recommended that updates to individual functions are introduced via the canary approach, i.e. organisations should run both the old and new versions of the function in production by diverting a small percentage of traffic to the new API; in addition, performance should be tracked until sufficient confidence has been established to withdraw the older version of the function. In the FaaS model, the canary approach can be implemented via the API gateway or a service mesh (see the ‘control’ section of Figure 45).

Where response times are of critical importance, it may be possible to run functions closer to the user. The AWS Lambda@Edge244 capability allows Lambda functions to be executed via Lambda infrastructures co-located with their CloudFront content distribution network; this significantly increases response times when the main Lambda service is hosted in a region geographically remote from the end user. In this model, the Lambda functions are triggered by specific CloudFront events.

Cryptography

The delivery of the services within the cryptography grouping is split between the provider (responsible for the encryption services offered by the underlying serverless platform) and the consumer (who will maintain joint responsibility for key management if they choose to implement using their own keys).

In general, FaaS consumers will rely upon the encryption services offered by the underlying platform, e.g. the encryption of access control tokens, network encryption via TLS and storage encryption via default encryption (e.g. S3 encryption or Azure Storage encryption) will all be performed by the platform. Application developers may need to be careful when passing information via HTTP headers if they choose not to enable encryption on the safe side of any API gateway. Developers may wish to encrypt such information so that it does not pass in the clear even if the HTTP traffic itself is unencrypted at the network level.

Access management

The identity management approach for applications delivered through FaaS is similar to that for PaaS applications: FaaS developers can make use of the identity services provided by the Cloud platforms, such as AWS Cognito or Azure AD, to control access to their applications. However, developers must be aware that they retain responsibility for the provision of appropriate access rights for the functions themselves, e.g. they must ensure that they grant appropriate access rights for the functions to call the platform services that they require – and only the platform services that they require. The principle of ‘least privilege’ is as applicable to FaaS as it is to any other IT delivery model: functions should only be able to access the data and services that they require.

Functions can be triggered in a variety of ways, e.g. AWS Lambda functions can be triggered synchronously, asynchronously or via scheduling.245 The full list of triggers can be found here:

https://docs.aws.amazon.com/lambda/latest/dg/lambda-services.html.

AWS services that can send events directly to Lambda include:

Amazon Kinesis

Amazon DynamoDB

Amazon Simple Queue Service

AWS services that can trigger Lambdas synchronously include:

Elastic Load Balancing (Application Load Balancer)

Amazon Cognito

Amazon Lex

Amazon Alexa

Amazon API Gateway

Amazon CloudFront (Lambda@Edge)

Amazon Kinesis Data Firehose

Whilst those AWS services that can trigger Lambdas asynchronously include:

Amazon Simple Storage Service

Amazon Simple Notification Service

Amazon Simple Email Service

AWS CloudFormation

Amazon CloudWatch Logs

Amazon CloudWatch Events

AWS CodeCommit

AWS Config

Each of these different scenarios for triggering a Lambda function requires a slightly different approach to granting access. For example, if developers are reading events from a stream or a queue, they must ensure that the Lambda function’s execution role246 can access the relevant source. Conversely, if the Lambda function is being triggered by another AWS service, such as S3, then it is the service that must be granted access to call the Lambda function via the relevant Lambda resource-based policy.247 For example, should a developer wish to trigger an AWS Lambda function when an item is uploaded to an S3 bucket, then that Lambda function must be configured to allow S3 to invoke it.

In summary, if Lambda is actively monitoring a stream for a trigger event, it must have access to that stream; conversely, if Lambda is passively awaiting the notification to execute, the notifying service must be given the permission to trigger that execution.

Azure Functions take a slightly different approach and uses the concepts of both triggers and bindings. Each Azure function must have only one trigger, and this must be selected from the various options available. The available triggers include:

Timer

HTTP

Blob

Queue

Azure Cosmos DB

Event Hub

Bindings are different to triggers: Azure functions can have multiple bindings, and these allow data to be exchanged with Azure services on either an inbound or an outbound basis (depending on their function). Functions can establish bindings with the services listed at:

https://docs.microsoft.com/en-us/azure/azure-functions/functions-triggers-bindings.

The mechanism that launches the execution of Google Cloud Functions relies upon events and triggers. Cloud Functions supports events from:

HTTP

Cloud Storage

Cloud Pub/Sub

Cloud Firestore

Firebase (Realtime Database, Storage, Analytics, Auth)

Stackdriver Logging

A trigger is the means to tell functions to execute in response to an event of interest. For example, the command below could be used to create an HTTP trigger which would execute the function ‘helloworld’ when the function's URL receives an HTTP request:

gcloud functions deploy helloworld --runtime nodejs8 --trigger-http

The Google Functions identity model is quite blunt by default: all functions operate under the service account ([email protected]). This approach makes it more straightforward for the function to obtain the security credentials it requires to operate (the service identity has ‘Editor’ permissions by default); however, it makes it harder to implement least privilege because it is a shared account. Fortunately, it is possible to choose non-default identities and, consequently, to have a different identity for each function. This approach is more secure but it does require more effort in terms of provisioning the right permissions per identity.

Cloud Functions identity is described more fully here:

https://cloud.google.com/functions/docs/securing/function-identity.

For the purposes of this book, we are focussing on the hosting of a web application (illustrated in Figure 45). In this case, the functions – whether Lambda, Azure Functions or Cloud Functions – would most likely be triggered by HTTP requests, so some traditional capabilities will be available to secure access, namely web application firewalls and API gateways. For example, in the case of AWS and Figure 45, you would potentially have AWS WAF in the ‘presentation zone’, alongside CloudFront, acting as the first line of defence. Should an HTTP request be deemed valid by AWS WAF, and be unfulfillable by CloudFront, then the request would be passed to the API Gateway which would then check whether the request is authorised, potentially by using the Cognito identity services. Both API Gateway and Cognito sit in the ‘control’ zone. Interestingly, API Gateway can also use custom authorisers (now known as Lambda authorisers) that call out to specific Lambda functions designed to provide authorisation decisions – so you may find yourself using Lambda functions to control access to other Lambda functions.

If the request is authorised, the API Gateway will call the Lambda functions with the relevant parameters and return the results post-execution. This example illustrates the power of the serverless model: basic web applications can be up and running in short order, with no need to procure hardware security devices or security services with all elements delivered natively on the Cloud platform.

Security governance

From a security governance perspective, there are few specifics to worry about when it comes to using FaaS platforms, with the notable exception of those areas relating to maintaining cohesiveness of the overall application, i.e. the security architecture, coordination and ownership services. FaaS applications should be stateless and decoupled: organisations should be able to update each function independently of the other elements of the application. This approach relies on organisations having an agreed and tightly managed set of APIs that front each individual function and that may be registered with a relevant API gateway.

Providing that the interface for interacting with each individual function remains unchanged, the code delivering the functionality can be updated or replaced as required. This allows each function to be owned by different project teams, with the responsibility for maintaining the overall API sitting with an adequately empowered architect/owner. The maintenance of tightly controlled APIs also reduces the amount of work needed to secure the application as it does not require regular updates to any API gateways or WAFs protecting the service.

Control of the API is vital: it is easy to introduce breaking changes by making API updates without informing the project teams that use that API. Amazon’s overall philosophy regarding the management of APIs is that "two is better than none"; however, this is balanced by the view that "none is better than five."248 Accordingly, there may be a ‘Goldilocks zone’ somewhere between one and five. The point is that teams should not feel pressured to immediately deprecate an old API upon the introduction of a new version, although regular clean-ups should be performed to prevent the sprawl of different APIs providing the same capability. FaaS is the ideal service model for using canary deployments in combination with workloads that are easily distributed via an API gateway.

Security operations

DevSecOps and FaaS go hand in hand: both the application and the relevant security controls should be articulated as code, enabling the application to be deployed as a whole with embedded security (e.g. WAF rule sets).

The ephemeral nature of functions makes the security monitoring of FaaS a potentially problematic capability to provide; enterprises do not get to implement host-based intrusion detection systems (HIDS) or similar. As an underlying principle, FaaS seeks to limit the number of dependencies that must be incorporated into the application at launch (due to the cold start problem described earlier); consequently, using security agents is rarely the right answer, particularly if they require registration with any central management station as a result of the short-lived nature of their functions. This leaves FaaS consumers with the following options for security monitoring:

Concentrating on the instrumentation of the application itself, i.e. making certain that the functions emit the security events required to provide observability;

Using a lightweight RASP-type capability, such as FunctionShield;

Closely monitoring the security support services, e.g. the API gateways and WAFs; and

Closely monitoring the other serverless services being accessed by the FaaS platform, e.g. storage services, pub-sub services, notification/messaging services, et cetera.

Ideally, all of these options should be considered and implemented so as to provide a cohesive and comprehensive approach towards security monitoring. Each of those elements can be configured to log to a central repository which can then be analysed and reported upon as per other service models.

As discussed in the governance section, change management is an important element of operating an FaaS-based application – whilst the underlying functions can be changed by the owning project teams, the APIs those functions provide must only be changed via a formal change management process so that relying services do not find themselves facing breaking changes. Handling the change management process correctly is critical: enterprises do not want to find themselves reintroducing waterfall-style governance gateways and inhibiting agility.

There are approaches better suited to the DevOps ways of working; these include coupling the multiple API approach with an adherence to a versioning scheme, such as Semantic Versioning (SemVer),249 and performing contract testing on each release. Clients should be able to hit a specific version of a published end point, such as v2, knowing that behind the scenes there are a number of minor releases, e.g. v2.x.x. In this scenario, v2.6.2, for example, is guaranteed to be backwards compatible with v2.5.4, with breaking changes only being introduced when the end point moves to v3. (The latest ~2.x.x behind the v2 end point would be kept available for a documented and agreed time.)

As with all utility services, asset management is key with respect to delivering cost control. Organisations using serverless technologies need to keep track of their use of any relevant technologies and make sure that they perform regular housekeeping duties, e.g. deleting old S3 buckets when they are no longer needed rather than paying for unnecessary storage.

Integration

Integration is key to the successful implementation of FaaS approaches. The use of triggers to launch the execution of functions, and the potential use of WAFs and API gateways to mediate access, were all discussed in the access control section of this chapter. Cloud workload protection platforms may become more relevant to functions as the technology matures, but these technologies are currently much more focussed on securing containerised microservices than FaaS offerings.

CASBs are not particularly applicable in the FaaS space; they may be used to control access to the management plane, though this may add an extra level of complexity for little security gain.

Conclusion

The FaaS service model is probably the Cloud service model with the most potential for future growth. As the various offers mature (e.g. as cold start times decrease and security product vendors take a greater interest), FaaS may well become a threat to the current Kubernetes-dominated on-premises world of containerised microservices. In the meantime, functions are an excellent means for automating discrete pieces of functionality and for gluing together other serverless components (e.g. for acting on a security log event to update a firewall rule) as part of a move towards a true DevSecOps approach.

235 https://aws.amazon.com/dynamodb/.

236 https://docs.aws.amazon.com/cognito/latest/developerguide/role-based-access-control.html.

237 AWS has provided a method of passing state through a series of Lambda Functions, using Step Functions to describe a state machine: https://docs.aws.amazon.com/step-functions/latest/dg/tutorial-creating-lambda-state-machine.html.

238 https://docs.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-overview.

239 https://firecracker-microvm.github.io/ in the case of AWS Lambda.

240 Custom run-times can provide FaaS consumers with more control, enabling support for some of these technologies, see https://docs.aws.amazon.com/lambda/latest/dg/runtimes-custom.html.

241 www.puresec.io/function-shield.

242 www.twistlock.com/2018/11/29/introducing-lambda-layers/.

243 Taken from the NIST document: "Security Strategies for Microservices-based Application Systems", https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-204-draft.pdf.

244 https://aws.amazon.com/lambda/edge/.

245 https://docs.aws.amazon.com/lambda/latest/dg/services-cloudwatchevents.html.

246 https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html.

247 https://docs.aws.amazon.com/lambda/latest/dg/invocation-eventsourcemapping.html.

248 www.theregister.co.uk/2019/05/14/amazons_away_teams/?page=3.

249 https://semver.org/.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.219.36.41