Amplify App Access Token Exposed

  • Query id: 73980e43-f399-4fcc-a373-658228f7adf7
  • Query name: Amplify App Access Token Exposed
  • Platform: CloudFormation
  • Severity: Medium
  • Category: Secret Management
  • URL: Github

Description

Amplify App Access Token must not be in a plain text string or referenced in a parameter as a default value.
Documentation

Code samples

Code samples with security vulnerabilities

Positive test num. 1 - yaml file
AWSTemplateFormatVersion: 2010-09-09
Resources:
  NewAmpApp:
    Type: AWS::Amplify::App
    Properties:
      AccessToken: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE1MTYyMzkwMjJ9.tbDepxpstvGdW8TC3G8zg4B6rUYAOvfzdceoH48wgRQ
      BuildSpec: String
      CustomHeaders: String
      Description: String
      EnableBranchAutoDeletion: True
      IAMServiceRole: String
      Name: String
      OauthToken: String
      Repository: String
Positive test num. 2 - yaml file
AWSTemplateFormatVersion: 2010-09-09
Parameters:
  ParentAccessToken:
    Description: 'Access Token'
    Type: String
    Default: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE1MTYyMzkwMjJ9.tbDepxpstvGdW8TC3G8zg4B6rUYAOvfzdceoH48wgRQ'
Resources:
  AmpApp:
    Type: AWS::Amplify::App
    Properties:
      AccessToken: !Ref ParentAccessToken
      BuildSpec: String
      CustomHeaders: String
      Description: String
      EnableBranchAutoDeletion: true
      IAMServiceRole: String
      Name: NewAmpApp
      OauthToken: String
      Repository: String
Positive test num. 3 - yaml file
AWSTemplateFormatVersion: 2010-09-09
Parameters:
  ParentUserToken:
    Description: 'UserToken'
    Type: String
Resources:
  NewApp:
    Type: AWS::Amplify::App
    Properties:
      AccessToken: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE1MTYyMzkwMjJ9.tbDepxpstvGdW8TC3G8zg4B6rUYAOvfzdceoH48wgRQ
      BuildSpec: String
      CustomHeaders: String
      Description: String
      EnableBranchAutoDeletion: true
      IAMServiceRole: String
      Name: NewAmpApp
      OauthToken: String
      Repository: String

Positive test num. 4 - json file
{
  "AWSTemplateFormatVersion": "2010-09-09T00:00:00Z",
  "Resources": {
    "NewAmpApp": {
      "Type": "AWS::Amplify::App",
      "Properties": {
        "EnableBranchAutoDeletion": true,
        "IAMServiceRole": "String",
        "OauthToken": "String",
        "Repository": "String",
        "AccessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE1MTYyMzkwMjJ9.tbDepxpstvGdW8TC3G8zg4B6rUYAOvfzdceoH48wgRQ",
        "CustomHeaders": "String",
        "Name": "String",
        "BuildSpec": "String",
        "Description": "String"
      }
    }
  }
}
Positive test num. 5 - json file
{
  "AWSTemplateFormatVersion": "2010-09-09T00:00:00Z",
  "Parameters": {
    "ParentAccessToken": {
      "Description": "Access Token",
      "Type": "String",
      "Default": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE1MTYyMzkwMjJ9.tbDepxpstvGdW8TC3G8zg4B6rUYAOvfzdceoH48wgRQ"
    }
  },
  "Resources": {
    "AmpApp": {
      "Type": "AWS::Amplify::App",
      "Properties": {
        "OauthToken": "String",
        "AccessToken": "ParentAccessToken",
        "Description": "String",
        "EnableBranchAutoDeletion": true,
        "IAMServiceRole": "String",
        "BuildSpec": "String",
        "CustomHeaders": "String",
        "Name": "NewAmpApp",
        "Repository": "String"
      }
    }
  }
}
Positive test num. 6 - json file
{
  "Resources": {
    "NewApp": {
      "Type": "AWS::Amplify::App",
      "Properties": {
        "EnableBranchAutoDeletion": true,
        "IAMServiceRole": "String",
        "Name": "NewAmpApp",
        "AccessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE1MTYyMzkwMjJ9.tbDepxpstvGdW8TC3G8zg4B6rUYAOvfzdceoH48wgRQ",
        "CustomHeaders": "String",
        "Description": "String",
        "OauthToken": "String",
        "Repository": "String",
        "BuildSpec": "String"
      }
    }
  },
  "AWSTemplateFormatVersion": "2010-09-09T00:00:00Z",
  "Parameters": {
    "ParentUserToken": {
      "Type": "String",
      "Description": "UserToken"
    }
  }
}

Code samples without security vulnerabilities

Negative test num. 1 - yaml file
Resources:
     NewAmpApp:
        Type: AWS::Amplify::App
        Properties:
          AccessToken: !Sub '{{resolve:secretsmanager:${MyAmpAppSecretManagerRotater}::password}}'
          BuildSpec: String
          CustomHeaders: String
          Description: String
          EnableBranchAutoDeletion: true
          IAMServiceRole: String
          Name: NewAmpApp
          OauthToken: String
          Repository: String
     MyAmpAppSecretManagerRotater:
        Type: AWS::SecretsManager::Secret
        Properties:
          Description: 'This is my amp app instance secret'
          GenerateSecretString:
            SecretStringTemplate: '{"username": "admin"}'
            GenerateStringKey: 'password'
            PasswordLength: 16
            ExcludeCharacters: '"@/\'
Negative test num. 2 - yaml file
Parameters:
  ParentAccessToken:
    Description: 'Access Token'
    Type: String
Resources:
  NewAmp:
    Type: AWS::Amplify::App
    Properties:
      AccessToken: !Ref ParentAccessToken
      BuildSpec: String
      CustomHeaders: String
      Description: String
      EnableBranchAutoDeletion: true
      IAMServiceRole: String
      Name: NewAmpApp
      OauthToken: String
      Repository: String
Negative test num. 3 - yaml file
Parameters:
  ParentAccessToken:
    Description: 'Access Token'
    Type: String
    Default: ""
Resources:
  AmpApp:
    Type: AWS::Amplify::App
    Properties:
      AccessToken: !Ref ParentAccessToken
      BuildSpec: String
      CustomHeaders: String
      Description: String
      EnableBranchAutoDeletion: true
      IAMServiceRole: String
      Name: NewAmpApp
      OauthToken: String
      Repository: String

Negative test num. 4 - json file
{
  "Resources": {
    "NewAmpApp": {
      "Type": "AWS::Amplify::App",
      "Properties": {
        "Name": "NewAmpApp",
        "Repository": "String",
        "AccessToken": "{{resolve:secretsmanager:${MyAmpAppSecretManagerRotater}::password}}",
        "BuildSpec": "String",
        "Description": "String",
        "OauthToken": "String",
        "CustomHeaders": "String",
        "EnableBranchAutoDeletion": true,
        "IAMServiceRole": "String"
      }
    },
    "MyAmpAppSecretManagerRotater": {
      "Type": "AWS::SecretsManager::Secret",
      "Properties": {
        "Description": "This is my amp app instance secret",
        "GenerateSecretString": {
          "SecretStringTemplate": "{\"username\": \"admin\"}",
          "GenerateStringKey": "password",
          "PasswordLength": 16,
          "ExcludeCharacters": "\"@/\\"
        }
      }
    }
  }
}
Negative test num. 5 - json file
{
  "Parameters": {
    "ParentAccessToken": {
      "Description": "Access Token",
      "Type": "String"
    }
  },
  "Resources": {
    "NewAmp": {
      "Properties": {
        "Name": "NewAmpApp",
        "AccessToken": "ParentAccessToken",
        "BuildSpec": "String",
        "Description": "String",
        "EnableBranchAutoDeletion": true,
        "CustomHeaders": "String",
        "IAMServiceRole": "String",
        "OauthToken": "String",
        "Repository": "String"
      },
      "Type": "AWS::Amplify::App"
    }
  }
}
Negative test num. 6 - json file
{
  "Parameters": {
    "ParentAccessToken": {
      "Description": "Access Token",
      "Type": "String",
      "Default": ""
    }
  },
  "Resources": {
    "AmpApp": {
      "Type": "AWS::Amplify::App",
      "Properties": {
        "AccessToken": "ParentAccessToken",
        "BuildSpec": "String",
        "Repository": "String",
        "OauthToken": "String",
        "CustomHeaders": "String",
        "Description": "String",
        "EnableBranchAutoDeletion": true,
        "IAMServiceRole": "String",
        "Name": "NewAmpApp"
      }
    }
  }
}