Search code examples
reactjsamazon-web-servicessecurityaws-secrets-manageraws-amplify

Access AWS Secrets from React Amplify APP


This May be a stupid question, But is it safe to access AWS Secrets from my React front end app (Hosted on AWS Amplify) In this manner ?

These Secrets are obviously not intended to be public so I dont want to use Amplify Env Variables option.

If this is not the appropriate way of loading API Secrets and keys to a Front End Application, then what is ?

var AWS = require('aws-sdk'),
    region = "us-east-2",
    secretName = "MNTSWP",
    secret,
    decodedBinarySecret;

// Create a Secrets Manager client
var client = new AWS.SecretsManager({
    region: region
});



client.getSecretValue({SecretId: secretName}, function(err, data) {
    if (err) {
        if (err.code === 'DecryptionFailureException')

            throw err;
        else if (err.code === 'InternalServiceErrorException')

            throw err;
        else if (err.code === 'InvalidParameterException')

            throw err;
        else if (err.code === 'InvalidRequestException')

            throw err;
        else if (err.code === 'ResourceNotFoundException')

            throw err;
    }
    else {

        if ('SecretString' in data) {
            secret = data.SecretString;
        } else {
            let buff = new Buffer(data.SecretBinary, 'base64');
            decodedBinarySecret = buff.toString('ascii');
        }
    }
    
    // Your code goes here. 
});

Solution

  • Because your front end runs in a web browser, because the code can easily be examined by moderately technical users, you cannot keep credentials (such as your AWS credentials) there safely. If you do that, not only are your secrets exposed, but your AWS credentials are exposed, and an attacker can do a lot of damage with those (and there are tools to scan for AWS keys).

    Honestly there aren't really solid ways to protect credentials in a front-end application, so you can:

    • Use a back-end API which holds the credential securely
      • But are you just pushing the problem around? Now do you need to verify that the user should have access to the back-end API?
    • Have the user supply credentials
      • This is the most common approach -- the user provides username and password and you use that to control access
      • This may still require a back-end API or something that can parse the credentials (e.g. AWS API Gateway + Authorizer)
    • Work out complicated rules to protect back-end resources even when some level of key is exposed (e.g. see Firebase Security Rules).