Code Monkey home page Code Monkey logo

netlify-env-poc's Introduction

Netlify & Your Secrets

This is a proof-of-concept for a potential exploit that can be used to steal secret keys associated with your Netlify website.

This is current as of November 3, 2019.

FAQ

Huh?

Isn't Netlify mainly for hosting your static website?

Yes.

Then why do you have secret keys on your website?

Even though Netlify's useful for static websites, they offer a lot of extra functionality that enable you to build super extensive web-apps without needing your own server, thanks to features like serverless functions. Essentially, they're Lambda functions that you can roll into your Netlify website without worrying about having to configuring them beyond Netlify.

As such, they're incredibly useful for abstracting away secret keys that the function will use on behalf of the front-end.

In other words, welcome to the JAMStack.

The Exploit

How does it work?

The exploit involves an interaction between two components: deploy previews and your environment variables.

Component details
Deploy previews

Netlify offers the ability to generate deploy previews, which are status checks for PRs that build a live-preview of the changes. They're incredibly useful since you can review a PR's changes without having to pull, build, and verify your changes yourself as Netlify will do that for you by generating a preview at deploy-preview-<PR#>--<sitename>.netlify.com.

This feature is on by default.

Environment variables

Environment variables, as the name suggests, are variables that are accessible during your build. They can either be set through your team settings, your site settings, or the netlify.toml file. Your netlify.toml configuration will override your site settings, which will override your team settings. In other words, it will read the netlify.toml file first, then your site settings, then your team settings to determine the environment variables.

In addition, you can set variables (and also basically every other configuration setting) per build context. Those build contexts can be production, deploy-preview, or branch-deploy. This will be important later.

The exploit, lite

Assume a scenario where you have a public repo that Netlify builds. Within the repo, you have a lambda function that consumes a secret key to access an external service. We wouldn't want to commit those secret keys in the repo so we set them through the UI on Netlify's website.

A bad actor can then come along and submit a PR that uses (and prints) your environment variables on the front-end; this malicious code will be automatically deployed by Netlify, which will expose the key.

But wait, can't I use a build context to prevent those keys from being leaked?

Sort of. You're able to specifiy a deploy preview-specific environment variables in your configuration file, which can override the secret keys in your production context. However, a bad actor can simply comment out those lines in your netlify.toml that sets those context-specific environment variables, effectively bypassing those values. As mentioned previously, the build will then fall back to the environment variables set by your site (the UI). At the time of writing, there is not way to set context-specific environment variables through the UI, so it will expose the production keys.

Can I see it in action?

This repo was set up as a Netlify website with all the default settings; it's a very simple site that uses webpack to generate some front-end JS that consumes (during the build) and prints (when the front-end loads) the CONTEXT and SECRET environment variables. The only change to the site's configuration on the website was within the build settings, where SECRET was set. In addition, we have a netlify.toml configuration which sets the deploy preview variables to mask our prod variables.

You can view the production site here.

Now, a non-malicious PR was submitted, which generated a deploy preview. Notice that our secret is now the value we set in the configuration file.

Finally, a malicious PR was submitted, which commented out the deploy preview settings in our configuration file. The deploy preview now exposes the production secret.

The scope seems really narrow

You're correct, it is. It requires a project to be public, deploy previews to be on (it is by default), and also for the project to consume secret keys. But given that combination, and you're (very unlikely, but still) in for a bad time.

Or you could simply turn off deploy previews.

netlify-env-poc's People

Contributors

lcfyi avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.