aws-boto3-credentials

Try in Playground
python-securitySecurityCritical

0

awsboto3
CWE-798

This rule makes sure that the boto3 library use the environments variables to authenticate instead of using hardcoded credentials. This rule checks for the boto3.client and boto3.Session calls. It addresses the CWE-798 rule - uses of hardcoded credentials in code.

** Learn More **

  • AWS credentials
  • CWE-798: Use of Hard-coded Credentials

Ast Rule: function call


aws-boto3-credentials

How to write a rule
function visit(node) {
  if (!node.arguments || !node.arguments.values || !node.context) {
    return;
  }
  const functions = ["Session", "client"];

  if (!node.functionName || !functions.includes(node.functionName.value)){
    return;
  }
  
  const arguments = node.arguments.values;
  const nbArguments = node.arguments.values.length;
  const allPackages = node.context.imports.filter(i => i.packages).flatMap(i => i.packages.map(p => p.name.str));
  const useBotoPackage = allPackages.filter(i => i === "boto3").length > 0;
  
  if (!useBotoPackage){
    return;
  }
  
  const ACCESS_KEY_PREFIX = [
    "ABIA", "ACCA", "AGPA", "AIDA", "AIPA", "AKIA", "ANPA", "ANVA",
    "APKA", "AROA", "ASCA", "ASIA"];
  const accessKeyArguments = node.arguments.values.filter(a => a.name && a.name.value == "aws_access_key_id");
  const secretKeyArguments = node.arguments.values.filter(a => a.name && a.name.value == "aws_secret_access_key");
  
  functions.forEach(functionName => {
    const hasAccessKeyArgument = accessKeyArguments.length > 0;
    const hasSecretKeyArgument = secretKeyArguments.length > 0;
    
    if((hasAccessKeyArgument ||hasSecretKeyArgument)  && node.functionName.value === functionName && node.moduleOrObject.value === "boto3"){
      const accessKey = accessKeyArguments[0].value.value;
      const secretKey = secretKeyArguments[0].value.value;
      
      // remove potential quote
      const accessKeyPrefix = accessKey.replace(/['"]+/g, '').substring(0, 4);
      console.log(accessKeyPrefix);
      
      if (ACCESS_KEY_PREFIX.includes(accessKeyPrefix)) {
        const error = buildError(node.start.line, node.start.col, node.end.line, node.end.col, "Clear credentials passed, use environment variables", "CRITICAL", "SECURITY");
        const lineToInsert = arguments[arguments.length - 1].end.line;
        const colToInsert = arguments[arguments.length - 1].end.col;
        addError(error);
      }
     
  	}
  });
  
}

test-fail.py

Expected test result: has error

import boto3

client = boto3.client(
    's3',
    aws_access_key_id="AGPAFOOBAR",
    aws_secret_access_key="bar",
    aws_session_token=SESSION_TOKEN
)

session-no-error.py

Expected test result: no error

import boto3

client = boto3.Session(
    's3',
    aws_session_token=SESSION_TOKEN
)

not-passing-access-and-secret-keys.py

Expected test result: no error

import boto3

client = boto3.client(
    's3',
    aws_session_token=SESSION_TOKEN
)

session-error.py

Expected test result: no error

not-using-boto3.py

Expected test result: no error

Add comment

Log in to add a comment


    Be the first one to leave a comment!

Codiga Logo
Codiga Hub
  • Rulesets
  • Explore
  • Cookbooks
  • Playground
soc-2 icon

We are SOC-2 Compliance Certified

G2 high performer medal

Codiga – All rights reserved 2022.