amazon-s3aws-sdkaws-sdk-js

Is this a safe way to use aws-sdk on client side?


I have read different opinions so I'd like expert ones. My question is basic: If I create a react app (only client side), from where I'm planning to read a s3 object, is the following a safe approach or my credentials will be somehow exposed? My env variable would only be stored in Netlify.

I'm asking this because I had a similar setup and my AWS was compromised (but I'm unsure if this approach was the reason).

aws-exports.js

import { config } from 'aws-sdk'
const AWSConfig = {
    accessKeyId: process.env.REACT_APP_AWS_ACCESS_KEY_ID,
    secretAccessKey: process.env.REACT_APP_AWS_SECRET_ACCESS_KEY,
    region: process.env.REACT_APP_AWS_REGION,
}
config.update(AWSConfig)

s3.js

import { S3 } from 'aws-sdk'

class S3Singleton {
    static instance = undefined
static async getInstance() {        
        if (S3Singleton.instance) {
            return S3Singleton.instance
        }
        S3Singleton.instance = await S3Singleton.createInstance()
        return S3Singleton.instance
    }
static createInstance = async () => {
        return new S3({
            apiVersion: process.env.REACT_APP_AWS_API_VERSION,
            region: process.env.REACT_APP_AWS_REGION,
            params: { Bucket: process.env.REACT_APP_AWS_BUCKET },
        })
    }
}
export default S3Singleton

The s3 object reading

import S3Singleton from './s3'

export const getXFile = async () => {
  try {
    const s3 = await S3Singleton.getInstance()

    return await new Promise((resolve, reject) => {
      s3.getObject(
        {
          Bucket: process.env.REACT_APP_BUCKET,
          Key: "xfile.json",
        },
        (err, data) => {
          if (err) reject(err)
          if (data) resolve(JSON.parse(data.Body.toString()))
        },
      )
    })
  } catch (e) {
    console.log(e)
  }
}

Solution

  • If you have a client application that connects to an API with any kind of credentials, those credentials are part of the client application and should be considered "leaked". There are multiple ways to extract those credentials from a client with different level of effort.

    I put "leaked" in quotes because it depends on the permissions you get with those credentials. If it is possible to restrict you credentials to just the use-case the user should be allowed to do, then it does not matter if the user can extract them. If he can escalate his privileges do to more then he should be able, then it is not safe and you need to add another layer.

    It does not depend on how you handle those credentials, as the client still must be able to read and use those credentials, so any user of that client would be able to do the same. (just with more or less effort ;-) )