Insecure Serverless Plugins: Why You Should Inspect the Source Code
The Serverless Framework supports numerous plugins and they save so much time, but this convenience can come with a negative downside.
The Serverless Framework support numerous plugins—and they are great! They save so much time in deploying our serverless applications. Why reinvent the wheel? This convenience comes with a downside: not all plugins are written securely. We must choose our plugins wisely, which means we should inspect the source code.
What are Serverless Framework plugins?
The Serverless Framework allow us to use plugins (or create one) that hook into the lifecycle events during the deploy process. We can hook into the "before:deploy:deploy" event to setup files and variables before the deploy begins. We can hook into the "deploy:finalize" hook to save some information about the deployment. There are numerous possibilities that plugins enable.
There are plugins that:
- Create a serverless web site
- Enabling AWS CloudFormation stack termination protection
- Configure AWS IAM policies per function
And many more.
To use a plugin, we install the npm package:
npm install --save-dev serverless-iam-roles-per-function
Add the plugin to our Serverless configuration file (serverless.yml):
plugins:
- serverless-iam-roles-per-function
And, follow any instructions and settings the plugin requires.
We have now improved and simplifies our serverless deployment.
Not all plugins have the same level of security
The plugins are built by the Serverless community. Anyone can create a plugin. The Serverless Framework company lists plugins, but only a subset are "approved." This means we should be cognizant of what we are using.
One plugin, allows us to add if-else statements in our serverless.yml file: Serverless Plugin IfElse plugin. This plugin is useful because we can adjust our Serverless configuration depending on the deployment scenario.
For example, we can deploy functions specific to our dev
stage, and exclude them from the others.
service: insecure-plugins
provider:
name: aws
runtime: nodejs12.x
stage: ${opt:stage, 'dev'}
region: us-east-1
functions:
dev:
handler: dev.handler
plugins:
- serverless-plugin-ifelse
custom:
serverlessIfElse:
- If: '"${self:provider.stage}" != "dev"'
Exclude:
- functions.dev
Our dev
stage will deploy the dev
function to the dev
stage and all other stages will not have it. Nice!
After inspecting the code, I saw something interesting on line 27 for how it evaluate the if statement.
if (eval(item.If)) {
Let's see if this works as we expect.
Launching an exploit using the plugin
I updated my serverless.yml to include some Node code.
service: insecure-plugins
provider:
name: aws
runtime: nodejs12.x
stage: ${opt:stage, 'dev'}
region: us-east-1
functions:
dev:
handler: dev.handler
plugins:
- serverless-plugin-ifelse
custom:
serverlessIfElse:
# - If: '"${self:provider.stage}" != "dev"'
- If: 'const cp = require("child_process"); cp.execSync("touch hello.txt");'
Exclude:
- functions.dev
I deployed the configuration and noticed the following:
- It deleted the
dev
function because the if statement does not return a truthy value. - I found an empty file named
hello.txt
in the folder.
This is an example how a plugin can reduce our security posture. Granted, someone would have to insert a rogue command and get it past us in the code review process for this exploit to work. Keep in mind, the plugin code could do something malicious because it has access to the AWS services permitted by the IAM policies used to deploy the Serverless configuration.
Conclusion
Serverless Framework plugins are great, but we need to understand what they do by inspecting the source code. We must be careful to understand whether they can potentially do something malicious.
View the source code at https://github.com/miguel-a-calles-mba/secjuice/tree/master/insecure-plugins.
A Note from the Author
Join my mailing list to get updates on my writings, my short stories, my upcoming books, and cybersecurity news. Visit https://miguelacallesmba.com/subscribe to join.
Stay secure, Miguel