Use the Conformity Knowledge Base AI to help improve your Cloud Posture

Check for Unknown Cross Account API Access

Trend Cloud One™ – Conformity is a continuous assurance tool that provides peace of mind for your cloud infrastructure, delivering over 1000 automated best practice checks.

Risk Level: High (not acceptable risk)

Ensure that your Amazon API Gateway REST APIs are configured to allow access only to trusted AWS accounts in order to protect against unauthorized cross-account access. Before running this rule by the Trend Cloud One™ – Conformity engine, you must define the account ID of each trusted AWS entity that can access your REST APIs within the rule settings, on your Conformity account console.

This rule can help you work with the AWS Well-Architected Framework.

Security

Allowing untrustworthy cross-account access to your Amazon API Gateway APIs can lead to unauthorized API invocation. To prevent API exposure, you can use the Amazon API Gateway resource policies to allow your REST APIs to be securely invoked only by trusted entities, such as IAM users and IAM roles from other AWS cloud accounts.


Audit

To determine if there are any Amazon API Gateway REST APIs that allow unknown cross-account access available within your AWS account, perform the following actions:

Using AWS Console

01 Sign in to the AWS Management Console.

02 Navigate to Amazon API Gateway console at https://console.aws.amazon.com/apigateway/.

03 In the left navigation panel, select APIs to access the Amazon API Gateway APIs listing page.

04 Click on the name of the REST API that you want to examine to access the API configuration. To identify a REST API check the value available in the Protocol column for each listed API.

05 In the navigation panel, within the API submenu, choose Resource Policy to access the resource policy attached to the selected API. An API resource policy is a JSON policy document that you can attach to your API to control whether a specified AWS principal can invoke your API.

06 Inside the Resource Policy text box, within the policy document, check each "Principal" element value to identify the AWS account ID (e.g. 123456789012), included in the IAM entity ARN (e.g. "arn:aws:iam::123456789012:root"), where the policy statement's "Effect" is set to "Allow".

07 Sign in to your Trend Cloud One™ – Conformity account, access Unknown Cross Account API Access conformity rule settings, and compare the AWS account ID(s) found at the previous step against each ID defined in the rule configuration section. If the identity (account) ID found does not match any of the trusted account IDs listed on your Conformity console, the cross-account access to the selected Amazon API Gateway REST API is not secured.

08 Repeat steps no. 4 – 7 for each REST API available within the current AWS cloud region.

09 Change the AWS region from the navigation bar and repeat the process for the other regions.

Using AWS CLI

01 Run get-rest-apis command (OSX/Linux/UNIX) with custom query filters to list the IDs of the REST APIs created in the selected AWS cloud region:

aws apigateway get-rest-apis
  --region us-east-1
  --output table
  --query 'items[*].id'

02 The command output should return a table with the requested API identifiers (IDs):

----------------
|  GetRestApis |
+--------------+
|  aaabbbbccc  |
|  abcdabcdab  |
+--------------+

03 Run get-rest-api command (OSX/Linux/UNIX) using the ID of the REST API that you want to examine as the identifier parameter and custom query filters to describe the resource policy attached to the selected API:

aws apigateway get-rest-api
  --region us-east-1
  --rest-api-id aaabbbbccc
  --query 'policy'

04 The command output should return the attached resource policy in JSON format:

{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Effect": "Allow",
			"Principal": {
				"AWS": [
					"arn:aws:iam::123456789012:root",
					"arn:aws:iam::123456789012:user/David"
				]
			},
			"Action": "execute-api:Invoke",
			"Resource": "arn:aws:execute-api:us-east-1:123412341234:aaabbbbccc/stage/GET/project5api"
		}
	]
}

Search the policy document returned by the get-rest-api command output for each "Principal" element value to identify the AWS account ID (e.g. 123456789012), included in the IAM entity ARN (e.g. "arn:aws:iam::123456789012:root"), where the policy statement's "Effect" is set to "Allow".

05 Sign in to your Trend Cloud One™ – Conformity account, access Unknown Cross Account API Access conformity rule settings, and compare the AWS account ID(s) found at the previous step against each ID defined in the rule configuration section. If the identity ID found does not match any of the trusted account IDs listed on your Conformity console, the cross-account access to the selected Amazon API Gateway REST API is not secured.

06 Repeat steps no. 3 – 5 for each REST API available in the selected AWS cloud region.

07 Change the AWS region by updating the --region command parameter value and repeat steps no. 1 – 6 to perform the audit process for other regions.

Remediation / Resolution

To update the resource-based policies associated with your Amazon API Gateway REST APIs in order to allow cross-account access only from trusted AWS entities, perform the following actions:

Using AWS CloudFormation

01 CloudFormation template (JSON):

{
	"AWSTemplateFormatVersion": "2010-09-09",
	"Description": "Allows Trusted Cross-Account API Access",
	"Resources": {
		"RestAPI": {
			"Type": "AWS::ApiGateway::RestApi",
			"Properties": {
				"Name": "WebServiceRestAPI",
				"Description": "A simple API Gateway REST API",
				"Policy": {
					"Version": "2012-10-17",
					"Statement": [
						{
							"Effect": "Allow",
							"Principal": {
								"AWS": "arn:aws:iam::123123123123:root"
								"AWS": "arn:aws:iam::123456789012:root"
							},
							"Action": "execute-api:Invoke",
							"Resource": "arn:aws:execute-api:us-east-1:123456789012:aaabbbbccc/Production/*"
						}
					]
				}
			}
		},
		"StageDeployment": {
			"Type": "AWS::ApiGateway::Deployment",
			"Properties": {
				"RestApiId": {
					"Ref": "RestAPI"
				}
			}
		},
		"APIStage": {
			"Type": "AWS::ApiGateway::Stage",
			"Properties": {
				"DeploymentId": {
					"Ref": "StageDeployment"
				},
				"RestApiId": {
					"Ref": "RestAPI"
				},
				"StageName": "Production"
			}
		}
	}
}

02 CloudFormation template (YAML):

AWSTemplateFormatVersion: '2010-09-09'
	Description: Allows Trusted Cross-Account API Access
	Resources:
	RestAPI:
		Type: AWS::ApiGateway::RestApi
		Properties:
		Name: WebServiceRestAPI
		Description: A simple API Gateway REST API
		Policy:
			Version: '2012-10-17'
			Statement:
			- Effect: Allow
				Principal:
					AWS: arn:aws:iam::123123123123:root
					AWS: arn:aws:iam::123456789012:root
				Action: execute-api:Invoke
				Resource: arn:aws:execute-api:us-east-1:123456789012:aaabbbbccc/Production/*
	StageDeployment:
		Type: AWS::ApiGateway::Deployment
		Properties:
		RestApiId: !Ref 'RestAPI'
	APIStage:
		Type: AWS::ApiGateway::Stage
		Properties:
		DeploymentId: !Ref 'StageDeployment'
		RestApiId: !Ref 'RestAPI'
		StageName: Production

Using Terraform (AWS Provider)

01 Terraform configuration file (.tf):

terraform {
	required_providers {
		aws = {
			source  = "hashicorp/aws"
			version = "~> 4.0"
		}
	}

	required_version = ">= 0.14.9"
}

provider "aws" {
	profile = "default"
	region  = "us-east-1"
}

resource "aws_api_gateway_rest_api" "rest-api" {
	name        = "web-service-rest-api"
	description = "A simple API Gateway REST API"
}

# Allows Trusted Cross-Account API Access
data "aws_iam_policy_document" "iam-policy-document" {
	statement {
	effect = "Allow"

	principals {
		type        = "AWS"
		identifiers = ["arn:aws:iam::123123123123:root"]
		identifiers = ["arn:aws:iam::123456789012:root"]
	}

	actions   = ["execute-api:Invoke"]
	resources = [aws_api_gateway_rest_api.rest-api.execution_arn]
	}
}

resource "aws_api_gateway_rest_api_policy" "rest-api-policy" {
	rest_api_id = aws_api_gateway_rest_api.rest-api.id
	policy      = data.aws_iam_policy_document.iam-policy-document.json
}

resource "aws_api_gateway_deployment" "rest-api-deployment" {
	rest_api_id = aws_api_gateway_rest_api.rest-api.id
}

resource "aws_api_gateway_stage" "api-stage" {
	deployment_id = aws_api_gateway_deployment.rest-api-deployment.id
	rest_api_id   = aws_api_gateway_rest_api.rest-api.id
	stage_name    = "Production"
}

Using AWS Console

01 Sign in to the AWS Management Console.

02 Navigate to Amazon API Gateway console at https://console.aws.amazon.com/apigateway/.

03 In the left navigation panel, select APIs to access the Amazon API Gateway APIs listing page.

04 Click on the name of the REST API that you want to reconfigure (see Audit section part I to identify the right API) to access the API configuration.

05 In the navigation panel, within the API submenu, choose Resource Policy to access the resource policy attached to the selected API.

06 Within the Resource Policy editor box, find the policy statement with the "Effect" set to "Allow" and the "Principal" element set to one or more untrusted AWS entities, then replace the non-compliant entity identifiers (IDs and ARNs) with the trusted entity identifiers, defined in the conformity rule settings. Choose Save to apply the changes. Once the API policy has been successfully updated, only requests that originate from trustworthy AWS accounts can reach the selected API.

07 Repeat steps no. 4 – 6 to reconfigure other Amazon API Gateway APIs available within the current AWS region.

08 Change the AWS cloud region from the navigation bar and repeat the remediation process for other regions.

Using AWS CLI

01 Modify the existing resource policy attached to the Amazon API Gateway API that you want to reconfigure. Find the policy statement with the "Effect" set to "Allow" and the "Principal" element set to one or more untrusted AWS entities, then replace the non-compliant entity identifiers (IDs and ARNs – highlighted) with the trusted entity identifiers, defined in the conformity rule settings:

{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Effect": "Allow",
			"Principal": {
				"AWS": [
					"arn:aws:iam::123123123123:root",
					"arn:aws:iam::123123123123:user/Harry"
				]
			},
			"Action": "execute-api:Invoke",
			"Resource": "arn:aws:execute-api:us-east-1:123412341234:aaabbbbccc/stage/GET/project5api"
		}
	]
}

02 Run update-rest-api command (OSX/Linux/UNIX) using the ID of the REST API that you want to reconfigure as the identifier parameter, to replace the existing resource policy attached to the selected API with the one modified at the previous step. Replace jsonEscapedPolicyDocument placeholder with your properly-escaped JSON policy document:

aws apigateway update-rest-api
  --region us-east-1
  --rest-api-id aaabbbbccc
  --patch-operations op=replace,path=/policy,value='{\"jsonEscapedPolicyDocument\"}'

03 The command output should return the metadata available for the reconfigured API:

{
	"id": "aaabbbbccc",
	"name": "project5api",
	"description": "Project5 API",
	"createdDate": "2021-02-18T11:00:00+00:00",
	"apiKeySource": "HEADER",
	"endpointConfiguration": {
		"types": [
			"REGIONAL"
		]
	},
	"policy": "{\\\"Version\\\":\\\"2012-10-17\\\",\\\"Statement\\\":[{\\\"Effect\\\":\\\"Allow\\\",\\\"Principal\\\":[\\\"arn:aws:iam::123123123123:root\\\",\\\"arn:aws:iam::123123123123:user/Harry\\\"],\\\"Action\\\":\\\"execute-api:Invoke\\\",\\\"Resource\\\":\\\"arn:aws:execute-api:us-east-1:123412341234:aaabbbbccc\\/stage\\/GET\\/project5api\\\"}]}",
	"tags": {},
	"disableExecuteApiEndpoint": false
}

04 Repeat steps no. 1 – 3 to reconfigure other Amazon API Gateway APIs available in the selected AWS region.

05 Change the AWS cloud region by updating the --region command parameter value and repeat the remediation process for other regions.

References

Publication date Jan 16, 2024