The rise of the Serverless Application Architecture allows organizations to focus on building valuable features while offloading the work of provisioning and scaling hardware to their cloud computing providers.
Serverless applications often use technologies like AWS Lambda for compute and Amazon API Gateway for accessing that compute functionality. As you are building these serverless applications, you can and should automatically test for security issues during development. Catching security issues early makes it much easier and cheaper to fix them.
As you add more functionality to an application, the attack surface increases. Just like with other automated tests, it is important to keep your test coverage high. Every API path and corresponding compute function could potentially expose a security related mistake. Modern security testing tools can be used to assess the application for security related bugs during development and before production traffic is sent to new features and functionality.
Common API Security Tests
There are a few common types of security tests you can run on your serverless applications:
Dynamic Application Security Testing (DAST): with DAST you are testing all or part of the running application, like a functional integration test would. The DAST scanner will send various predefined inputs to your application and look for evidence of a security vulnerability in the response.
Static Application Security Test (SAST): this test will look at your source code and find vulnerabilities related to insecure coding patterns and mistakes.
Software Composition Analysis (SCA): this type of test will look at your project manifest files and detect the use of any dependencies with known security vulnerabilities.
It’s a good idea to add a tool that implements each of these test types in your application codebase, ideally in an automated fashion that runs during development and before you release code.
Dynamic Application Security Testing
This type of testing finds bugs that attackers are most likely to exploit. The tools in this category basically send exploit payloads at a running application and measure the response to determine if the exploit was successful or not. Historically, these types of tests were run on production servers, but for obvious reasons it is better to do these exploits in development or CI/CD where they won’t do any harm to your applications.
You can set up automated dynamic application security tests using a GitHub Action and the OWASP ZAP tool, or with a product like StackHawk.
on: [push]
jobs:
zap_scan:
runs-on: ubuntu-latest
name: Scan the webapplication
steps:
- name: Checkout
uses: actions/checkout@v2
with:
ref: master
- name: ZAP Scan
uses: zaproxy/action-full-scan@v0.2.0
with:
token: ${{ secrets.GITHUB_TOKEN }}
docker_name: 'owasp/zap2docker-stable'
target: 'https://www.zaproxy.org/'
rules_file_name: '.zap/rules.tsv'
cmd_options: '-a'
Static Application Security Testing
The most lightweight and popular SAST tools are language specific linters and simple pattern matching scripts that leverage regular expressions.
For linters, many JavaScript projects use the ESLint project and its ecosystem of plugins to automatically test for security best practices and common mistakes. Some teams write simple regular expressions and scan the code using grep during development and before release.
There are some open source tools that take the idea of linters and pattern matching to the next level. For example, Semgrep is a fast static analysis tool that enforces coding standards and detects common security bugs.
Scanning your Lambda functions with tools like ESLint, grep, or Semgrep will allow you to detect all types of security vulnerabilities, such as: Cross-Site Scripting, SQL Injection, Server-side Request Forgery, and many other common security bugs.
You can automate these types of tests by adding a GitHub Action that runs on each pull request.
name: Semgrep
on: [pull_request]
jobs:
semgrep:
runs-on: ubuntu-latest
name: Check
steps:
- uses: actions/checkout@v1
- name: Semgrep
id: semgrep
uses: returntocorp/semgrep-action@v1
with:
config: p/r2c
Software Composition Analysis
If you are using third-party libraries in your application (…you probably are), then you should run a software composition analysis tool to make sure that you’re not bringing in any security bugs via your dependencies. The JavaScript ecosystem has npm audit
which is open source and uses a database of known vulnerabilities to check for issues in the libraries you are using in your code base.
You can scan the dependencies of your serverless application by running individual tools like npm audit
, OWASP Dependency-Check, or Snyk.
It is easy to automate software composition analysis tests with GitHub Actions. You can run this type of test on interval, pull request, or every branch push.
name: npm audit
on:
pull_request:
push:
branches:
- master
- 'releases/*'
# on:
# schedule:
# - cron: '0 10 * * *'
jobs:
scan:
name: npm audit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: install dependencies
run: npm ci
- uses: oke-py/npm-audit-action@v1.7.1
with:
audit_level: moderate
github_token: ${{ secrets.GITHUB_TOKEN }}
issue_assignees: oke-py
issue_labels: vulnerability,test
dedupe_issues: true
Automating API Security Testing for Serverless
One of the challenges when running scans against any API is tuning the scan to increase coverage. A major advantage of serverless applications that use Amazon’s API Gateway is that it is possible to export the entire API path documentation as an OpenAPI specification.
aws apigatewayv2 export-api \
--api-id api-id \
--output-type YAML \
--specification OAS30 \
--stage-name prod \
Stage-definition.yaml
You can use the OpenAPI specification file to configure dynamic applications security scanners, such as OWASP ZAP or a more developer focused tool like StackHawk. In StackHawk, for example, you can simply add the OpenAPI spec to the configuration file. Then, when the scanner starts, it will automatically test the API endpoints on your serverless application.
app:
openApiConf:
# Specify the path relative to the host
path: "/openapi.yaml"
→ If you’re interested in reading more, check out the StackHawk Docs.
The results generated by scanners like StackHawk’s can be used to break builds or alert developers to issues that should be fixed before a release is made. If a finding is found, it is simple to reproduce with a cURL command generator, equipping anyone on the development team to debug and fix the vulnerability.
Wrap Up
After you configure these automatic security tests to run alongside the rest of your code’s tests, you will have a new level of assurance about the security of the code you are shipping to production. In the future, and as new developers join the team, the best practices for secure coding will be built into the applications tests. Any regressions will be caught quickly and automatically.
Getting started with serverless security testing is easy, with many open source projects and free tools available. We’re biased, but we think the best place to start is a free account with StackHawk. Sign up today or reach out to us at support@stackhawk.com if you have any questions.