Cross-service confused deputy prevention
The confused deputy problem is a security issue where an entity that doesn't have permission to perform an action can coerce a more-privileged entity to perform the action. In AWS, cross-service impersonation can result in the confused deputy problem. Cross-service impersonation can occur when one service (the calling service) calls another service (the called service). The calling service can be manipulated to use its permissions to act on another customer's resources in a way it shouldn't otherwise have permission to access. To prevent this, AWS provides tools that help you protect your data for all services with service principals that have been given access to resources in your account.
To limit the permissions that AWS IoT gives another service to the resource, we recommend
using the aws:SourceArn
and aws:SourceAccount
global condition context keys in resource
policies. If you use both global condition context keys, the aws:SourceAccount
value and the account in the aws:SourceArn
value must use the same account ID
when used in the same policy statement.
The most effective way to protect against the confused deputy problem is to use the
aws:SourceArn
global condition context key with the full Amazon Resource
Name (ARN) of the resource. For AWS IoT, your aws:SourceArn
must comply with the
format:
arn:
for resource specific permissions or
aws
:iot:region
:account-id
:resource-type/resource-id
arn:
.
The resource-id can be the name or ID of the permitted resource, or a wildcard statement of
the permitted resource IDs. Make sure that the aws
:iot:region
:account-id
:*
region
matches
your AWS IoT Region and the account-id
matches your customer
account ID.
The following example shows how to prevent the confused deputy problem by using the
aws:SourceArn
and aws:SourceAccount
global condition context
keys in the AWS IoT role trust policy. For more examples, see Detailed examples of
confused deputy prevention.
{ "Version":"2012-10-17", "Statement":[ { "Effect":"Allow", "Principal":{ "Service":"iot.amazonaws.com" }, "Action":"sts:AssumeRole", "Condition":{ "StringEquals":{ "aws:SourceAccount":"
123456789012
" }, "ArnLike":{ "aws:SourceArn":"arn:aws
:iot:us-east-1
:123456789012
:*
" } } } ] }
Note
If you get access deny errors, it can be because the service integration with AWS
Security Token Service (STS) doesn't support the aws:SourceArn
and
aws:SourceAccount
context keys.
Detailed examples of confused deputy prevention
This section provides detailed examples of how to prevent the confused deputy problem by using the aws:SourceArn and aws:SourceAccount global condition context keys in the AWS IoT role trust policy.
Fleet provisioning
You can configure fleet provisioning
using a provisioning template resource. When a provisioning template references a
provisioning role, that role's trust policy can include the
aws:SourceArn
and aws:SourceAccount
condition keys.
These keys limit the resources for which the configuration can invoke the
sts:AssumeRole
request.
The role with the following trust policy can only be assumed by the IoT principal
(iot.amazonaws.com
) for the provisioning template specified in the
SourceArn
.
{ "Version":"2012-10-17", "Statement":[ { "Effect":"Allow", "Principal":{ "Service":"iot.amazonaws.com" }, "Action":"sts:AssumeRole", "Condition":{ "StringEquals":{ "aws:SourceAccount":"
123456789012
" }, "ArnLike":{ "aws:SourceArn":"arn:aws
:iot:us-east-1
:123456789012
:provisioningtemplate/example_template
" } } } ] }
JITP
In just-in-time provisioning
(JITP), you can either use provisioning template as a resource separate
from the CA or define the template body and the role as part of the CA certificate
configuration. The value of aws:SourceArn
in the AWS IoT role trust
policy depends on how you define the provisioning template.
If you define your provisioning template as a separate resource, the value
of aws:SourceArn
can be
"arn:aws:iot:
.
You can use the same policy example in Fleet
provisioning.region
:account-id
:provisioningtemplate/example_template
"
If you define your provisioning template within a CA certificate resource,
the value of aws:SourceArn
can be
"arn:aws:iot:
or
region
:account-id
:cacert/cert_id
""arn:aws:iot:
.
You can use a wildcard when the resource identifier, such as the ID of a CA
certificate, is unknown at the time of creation.region
:account-id
:cacert/*
"
The role with the following trust policy can only be assumed by the IoT
principal (iot.amazonaws.com
) for the CA certificate specified
in the SourceArn
.
{ "Version":"2012-10-17", "Statement":[ { "Effect":"Allow", "Principal":{ "Service":"iot.amazonaws.com" }, "Action":"sts:AssumeRole", "Condition":{ "StringEquals":{ "aws:SourceAccount":"
123456789012
" }, "ArnLike":{ "aws:SourceArn":"arn:aws
:iot:us-east-1
:123456789012
:cacert/8ecde6884f3d87b1125ba31ac3fcb13d7016de7f57cc904fe1cb97c6ae98196e
" } } } ] }
When creating a CA certificate, you can reference a provisioning role in
the registration configuration. The trust policy of the provisioning role
can use aws:SourceArn
to restrict what resources the role can
be assumed for. However, during the initial RegisterCACertificate call to register the CA certificate, you
would not have the ARN of the CA certificate to specify in the
aws:SourceArn
condition.
To work around this, i.e., to specify the provisioning role trust policy to the specific CA certificate that's registered with AWS IoT Core, you can do the following:
-
First, call RegisterCACertificate without providing the
RegistrationConfig
parameter. -
After the CA certificate is registered with AWS IoT Core, call UpdateCACertificate on it.
In the UpdateCACertificate call, provide a
RegistrationConfig
that includes the provisioning role trust policy withaws:SourceArn
set to the ARN of the newly registered CA certificate.
Credential provider
For AWS IoT Core
credential provider, use the same AWS account you use to create the
role alias in aws:SourceAccount
, and specify a statement that matches
the resource ARN of the rolealias resource type in aws:SourceArn
. When
creating an IAM role for use with AWS IoT Core credential provider, you must include
in the aws:SourceArn
condition the ARNs of any role aliases that might
need to assume the role, thereby authorizing the cross-service
sts:AssumeRole
request.
The role with the following trust policy can only be assumed by the principal of
AWS IoT Core credential provider (credentials.iot.amazonaws.com
) for the
roleAlias specified in the SourceArn
. If a principal attempts to
retrieve credentials for a role alias other than what's specified in the
aws:SourceArn
condition, the request will be denied, even if that
other role alias references the same IAM role.
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "credentials.iot.amazonaws.com" }, "Action": "sts:AssumeRole", "Condition": { "StringEquals": { "aws:SourceAccount": "
123456789012
" }, "ArnLike": { "aws:SourceArn": "arn:aws
:iot:us-east-1
:123456789012
:rolealias/example_rolealias
" } } } ] }