DEV Community

Misha Bragin
Misha Bragin

Posted on • Originally published at netbird.io

Serverless Security Vulnerabilities and Best Practices to Mitigate Them

The cloud has revolutionized application development, and serverless computing is its latest evolution. It offers an entire paradigm shift, allowing developers to focus solely on code functionality without having to manage servers. However, this convenience comes with a twist: new security challenges.

Traditional security practices are centered on securing underlying infrastructure, but serverless computing lacks dedicated servers and introduces a new attack surface. Malicious actors can exploit vulnerabilities in code, permissions, and event data to compromise serverless applications. This can lead to data breaches, unauthorized access, and financial loss.

In this article, you'll learn all about security vulnerabilities that can occur in serverless environments and how to prevent them. By the end of the article, you'll be able to build and deploy secure serverless applications confidently.

Why You Need to Secure Your Serverless Functions

Serverless security goes beyond traditional application security. It focuses on protecting the code within your serverless functions, the data those functions handle, and the overall execution environment provided by the cloud platform. This shift in focus is crucial because serverless functions often become the primary targets for attackers due to accessibility, heavy reliance on third-party code/services, shared resources, and limited control over infrastructure.

If your serverless functions process any personally identifiable information (PII), financial transactions, or health information or manage intellectual property, even a minor security breach can have devastating consequences. Strong serverless security safeguards this sensitive information and ensures the integrity of your functions. Additionally, many applications must comply with regulations, such as the General Data Protection Regulation (GDPR) or the California Consumer Privacy Act (CCPA). That means securing your functions and your data is a necessity.

In addition, serverless applications often interact with data residing outside the cloud platform, such as on-premise databases or storage systems. This hybrid environment creates additional security considerations. For example, a function might need to securely access a customer database located in your corporate data center. Mitigating unauthorized access to this data requires robust security measures at the function level to ensure proper authentication and authorization protocols are followed during communication.

Data migration projects are another compelling reason to prioritize serverless security. Imagine a scenario where you're migrating a workload (functions) to the cloud while the data (database) remains on-premise. In this case, ensuring secure communication between the functions and the on-premise data is critical. Serverless security best practices, such as least privilege access and data encryption, can help prevent unauthorized access during the migration process.

Best Practices to Secure Your Serverless Functions

Now that you know why you need to secure your serverless functions, let's take a look at a few best practices that you can implement to help you secure them.

Implement an Authentication and Authorization Solution That Integrates with Your Function

Authentication (authn) and authorization (authz) are the cornerstones of web application security. Authentication verifies a user's identity, while authorization determines their access rights to specific functions or resources. In a serverless environment, these mechanisms are typically integrated via an API gateway, which acts as the entry point for your functions, or through identity and access management (IAM) rules specific to a cloud platform that allow the functions to interact with other cloud resources.

Without proper controls, any person or service could trigger your functions and steal data or disrupt operations. Authentication ensures that only authorized users can interact with your functions, while authorization restricts their actions based on predefined roles or permissions.

Depending on the cloud platform, there are multiple ways you could set up authn/authz for your serverless functions. For instance, Amazon Web Services (AWS) provides user authentication through Amazon Cognito. The API gateway can be configured to integrate with Cognito to require users to sign in before invoking any Lambda functions. Cognito verifies user identities and passes relevant tokens to your functions for authorization decisions.

Additionally, AWS IAM allows you to define roles with specific permissions. You can associate an IAM role with your Lambda function, granting it access to specific resources, such as Amazon Simple Storage Service (Amazon S3) buckets or DynamoDB tables.

Perform Input Validation and Sanitization

Serverless functions often accept input from various sources, including user requests, API calls, and event triggers. Malicious actors can exploit improperly validated or sanitized input to inject code or manipulate data. This is why input validation and sanitization are critical security practices.

Unvalidated or unsanitized input can lead to vulnerabilities, such as SQL injection, cross-site scripting (XSS), and command injection. These attacks can compromise your functions, steal data, and disrupt operations.

Following are a few ways you can implement proper input sanitization and validation in your serverless functions:

  • Validate input types and formats: Ensure user input conforms to expected data types (eg integer or string) and formats (eg email address or date). AWS Lambda supports libraries such as Ajv or native JavaScript functions for data type validation.
  • Sanitize user input: Remove potentially harmful characters or code from user input before processing it. You can consider setting up a security handler using Vanadium to add custom, reusable logic for handling input validation and sanitization.
  • Encode special characters: Make sure to encode special characters when sending user input to prevent them from being misinterpreted. For instance, if you're sending input to functions through HTTP parameters, then you need to encode & and = characters because they have special meanings in URLs. JavaScript's encodeURIComponent and encodeURI functions can be used for this purpose.

Validate Third-Party Library Dependencies in Your Code

When writing serverless apps, developers often use third-party libraries to implement commonly used solutions and logic. However, the convenience of third-party libraries can come with hidden security risks. If not carefully vetted and maintained, these libraries can introduce vulnerabilities and create openings for attackers. A compromised library can be used to steal data, inject malicious code, or disrupt your functions. Validating your third-party dependencies is essential for robust serverless security.

Following are a few tips you can implement to help you carefully validate and pick the right library dependencies for your serverless app:

  • Use trusted sources and stay updated: Download libraries only from official repositories, such as npm, or maintain them in private repositories with proper access controls. Additionally, keep your libraries up-to-date to benefit from security patches.
  • Review library security reports: Many popular libraries have publicly available security reports detailing known vulnerabilities. Review these reports before using the library and consider alternatives if critical vulnerabilities exist.
  • Leverage dependency scanning tools: Several tools, such as Snyk or npm-audit, can scan your Lambda function dependencies for known vulnerabilities. These tools can identify potential security risks and recommend mitigation steps.

While libraries offer convenience, make sure you use only essential libraries to reduce your attack surface and simplify security management. Additionally, consider building custom functionality if a readily available library has a questionable security track record and there are no secure alternatives.

Enable Centralized Monitoring and Logging

Centralized monitoring and logging provide a comprehensive view of your functions' health and security posture and can help you maintain a watchful eye over your serverless functions. Without proper monitoring, you could miss critical security events, such as unauthorized access attempts or function errors. Centralized logs allow you to analyze function behavior, identify anomalies, and detect potential threats.

Most cloud platform vendors offer services to help you with active monitoring and alerts. For instance, Amazon CloudWatch provides a centralized logging service for your AWS Lambda functions. You can configure your Lambda functions to send logs to CloudWatch, allowing you to aggregate and analyze logs from all your functions in one place.

Several third-party tools, such as Splunk or Sumo Logic, can be integrated with CloudWatch to provide advanced log analytics and visualization. These tools can help you identify trends, filter logs for specific events, and set up alerts for suspicious activity.

CloudWatch also provides monitoring capabilities. Lambda automatically reports metrics related to basic performance, duration, and resource utilization through CloudWatch, and you can configure Lambda functions to emit custom metrics that provide insights into statistics local to the app domain. You can then use these metrics to identify potential performance bottlenecks and diagnose function errors.

Review Your Security Configurations to Remove Overly Permissive or Stale Configurations

A large part of web security hinges on proper configuration management. Permissions granted to functions and access controls for resources need to be continuously reviewed and adjusted to minimize the attack surface.

Overly permissive configurations or outdated permissions can create security gaps. An unused function with excessive IAM permissions or an API gateway endpoint with unrestricted access can be exploited.

Here's how you can ensure your serverless functions benefit from secure and up-to-date configurations:

  • Implement least privilege: Grant your serverless functions only the minimum permissions required to perform their tasks. Avoid using wildcards or overly broad IAM policies. The principle of least privilege minimizes the potential damage if a function is compromised.
  • Review and remove unused resources: Periodically review IAM roles, API gateway permissions, and other security configurations associated with your serverless functions. Identify and remove unused resources to eliminate potential attack vectors and streamline your security posture.
  • Utilize infrastructure as code (IaC): Leverage IaC tools, such as Terraform or AWS CloudFormation (in the case of AWS), to manage your serverless infrastructure configurations. IaC allows you to version control your configurations, track changes, and automate deployments. This ensures consistency and reduces the risk of manual configuration errors.
  • Enable security best practices: Many cloud providers offer security best practices recommendations for serverless functions. In AWS, the AWS Security Hub can identify potential security issues in your Lambda function configurations and suggest remediation steps.

Consult the OWASP Serverless Top Ten Documentation

The Open Worldwide Application Security Project (OWASP) is a renowned community for web application security. The OWASP Serverless Top Ten project addresses specific security challenges for serverless environments. This resource catalogs the ten most critical security risks specific to serverless functions. Understanding these threats allows you to prioritize your security efforts and implement effective mitigation strategies.

The documentation discusses the various ways in which injection attacks can impact a serverless app and lists ways that you can safeguard your functions against them. Similarly, it talks about broken authentication, sensitive data exposure, XML external entities, broken access control, security misconfiguration, XSS, insecure deserialization, use of components with known vulnerabilities, and insufficient logging and monitoring in depth.

Conclusion

Serverless security demands a proactive approach. You need to understand the unique threat landscape and implement best practices, such as robust authentication/authorization, meticulous input validation, and secure coding practices, to help you reduce your attack surface. Remember to leverage cloud provider security features, monitor your functions vigilantly, and keep configurations up-to-date.

For a deeper dive into serverless vulnerabilities, explore the OWASP Serverless Top Ten documentation. When you prioritize serverless security, you can build and deploy applications with confidence, ensuring the integrity of your data and the smooth operation of your serverless environment.

NetBird secures access and connectivity to serverless functions on platforms like AWS and Microsoft Azure. NetBird leverages netstack from the gVisor Go package (part of wireguard-go) and enables WireGuard to run entirely in the user space. This method alleviates the need for network-level or kernel-level access.

To learn how to configure NetBird, check out this Python database access example on Azure functions.

Top comments (0)