AWS lambda-function-public-access-prohibited rule in Config - amazon-web-services

In AWS's Config, I set a rule called: "lambda-function-public-access-prohibited". This says it runs its own lambda to "check", but I can't seem to find much else on what it's doing or how it determines that it's publicly accessible.
Can anyone point me to documentation on this or know what it's doing exactly?
Thank you!

This is the AWS Reference
Under Function policy, if the policy allows actions for the principal element “” or {“AWS”: “”}, it is publicly accessible.
Consider adding the following IAM condition to scope access to your account only.
"Condition": {
"StringEquals": {
"AWS:SourceAccount": "<account_id>"
}
}
}
source: https://hub.steampipe.io/mods/turbot/aws_compliance/controls/control.pci_v321_lambda_1?context=benchmark.pci_v321/benchmark.pci_v321_lambda
EDIT: This config rule was triggered by an S3 bucket resource attached to the lambda. In the console's resource-based policy form, you can specify an AWS account number. Once specified this will automatically create the above policy. After rescanning your config rules should appear as resolved.

Make sure you don't give * in resource or actions, so as to get all resources who have AWS account can access your lambda.
{
"Sid": "lambdaAccess",
"Effect": "Allow",
"Action": [
"lambda:*"
],
"Resource": "*"
},
Instead you can give ARN in resources and specific action like read, write, get access in action item.
Recommended :
{
"Sid": "lambdaAccess",
"Effect": "Allow",
"Action": [
"lambda:GetFunction"
],
"Resource": "arn:aws-us:lambda:us-west-1:123456789:function:lambda1234"
},

Related

AWS IAM Policy grant permissions for some EC2 instances

I want to restrict access for a specific user to see just few EC2 instances. I created a new user in IAM Roles and I attached a new Policy to it. The content of that Policy is attached below. I tried to look over documentation and to do it myself like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "ec2:*",
"Resource": [
"arn:aws:ec2:eu-west-1:ACCOUNT_ID:instance/i-INSTANCE_ID1",
"arn:aws:ec2:eu-west-1:ACCOUNT_ID:instance/i-INSTANCE_ID2"
]
}
]
}
I placed my region,ACCOUNT_ID(the owner id, not of the new user created) and instance-id, but when I connect with that user and I go to list all Instances I got this An error occurred fetching instance data: You are not authorized to perform this operation..
After I placed the code in JSON editor, in Policy Review step I got this message:
This policy defines some actions, resources, or conditions that do not
provide permissions. To grant access, policies must have an action
that has an applicable resource or condition. For details, choose Show
remaining Learn more
The AWS documentation mention exactly the same configuration or these examples.
I assume you connect as that user in the console (but it would be the same with CLI) Here is what I think is happening:
To list all the instances, the console most probably calls the DescribeInstances API. As per the list of action/resources/tags that can be used in IAM policy, this API does not support the resource filter in IAM.
This means your user has no authorization to list instances and they will not be shown in the console. You can validate this theory by using the CLI to request the details of a specific instance id, if my hypothesis is correct, it will be authorized.
As DescribeInstances can not be restricted by resource or tags, I don't think it is possible to filter the instance list for a user.
To have the console working, you'll need to add the following statement in your IAM policy
"Statement": [
{ your existing statement },
{
"Effect": "Allow",
"Action": "ec2:DescribeInstances",
"Resource": "*"
}
]
Please report if I was right :-) The example you mentioned in your question shows exactly that : Resources = * on DescribeInstances and Resources specific InstanceId on other operations.
The previous answer is wrong, you can Conditionally allow access to ec2:DescribeInstances by tag names. It's an AWS best practice as well. Also explicitly deny access to the ec2:CreateTags and ec2:DeleteTags actions to prevent users from creating or deleting tags to take control of the instance.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "ec2:DescribeInstances",
"Resource": "*",
"Condition": {
"StringEquals": {
"ec2:ResourceTag/UserName": "${aws:username}"
}
}
},
{
"Effect": "Deny",
"Action": [
"ec2:CreateTags",
"ec2:DeleteTags"
],
"Resource": "*"
}
]
}
DescribeInstances action does not support condition.
https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonec2.html

What is the ARN of an assumed role assumed by a Lambda function?

I am trying to use the NotPrincipal element in my bucket policy to explicitly deny access to my s3 bucket while whitelisting a particular lambda that accesses the bucket. I specified the role ARN and assumed role ARN for the lambda's role in the NotPrincipal element:
"arn:aws:iam::{Account ID}:role/service-role/{Lambda role name}",
"arn:aws:sts::{Account ID}:assumed-role/{Lambda role name}/{role session name}"
This doc explains the structure of the assumed role ARNs:
https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html#identifiers-unique-ids
I can't seem to get the assumed role ARN correct. The bucket policy is valid, but it seems I can provide anything for the role session name (the last part of the assumed-role ARN), and the ARN is considered valid. What does AWS set this role session name to when Lambda or other service assumes a service role? Is it possible to list active sessions for a role or list the assumed-role ARNs? I am currently using the Lambda function name for the role session name, but this is not working (the Lambda still cannot access the bucket).
Since I can't use wildcards in the NotPrincipal element, I need the full assumed-role ARN of the Lambda once it assumes the role.
UPDATE:
I tried using two conditions to deny all requests where the ARN does not match the ARN of the Lambda role or assumed role. The Lambda role is still denied from writing to S3 using the IAM policy simulator. Here is the policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "WhitelistRegistryAPILambdaRole",
"Effect": "Deny",
"Principal": "*",
"Action": [
"s3:PutObject",
"s3:DeleteObject",
"s3:DeleteObjectVersion",
"s3:GetObjectVersion",
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::{bucket name}",
"arn:aws:s3:::{bucket name}/*"
],
"Condition": {
"ArnNotLike": {
"AWS:SourceARN": "arn:aws:iam::{account ID}:role/{lambda role name}"
}
}
},
{
"Sid": "WhitelistRegistryAPILambdaAssumedRole",
"Effect": "Deny",
"Principal": "*",
"Action": [
"s3:PutObject",
"s3:DeleteObject",
"s3:DeleteObjectVersion",
"s3:GetObjectVersion",
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::{bucket name}",
"arn:aws:s3:::{bucket name}/*"
],
"Condition": {
"ArnNotLike": {
"AWS:SourceARN": "arn:aws:sts::{account ID}:assumed-role/{lambda role name}/{lambda function name}"
}
}
}
]
}
TL;DR:
The Assumed Role ARN of a Lambda Function is constructed as this:
arn:aws:sts::{AccountID}:assumed-role/{RoleName}/{FunctionName}
Details:
So the "role session name" is, in your case, the lambda function name.
You can easily verify this, by trying to call an API from your Lambda (DynamoDB ListTables for example) for which you do not have permissions. The error message in the callback will also contain the assumed role ARN (note that some service such as S3 do not provide detailed error messages when an operation is denied. DynamoDB, Lambda, and most of the recently launched services, will.)
I'm not sure to understand why you need a NotPrincipal, as probably there is a better way to handle the scenario you described :) More info would be useful to provide a more precise answer.
From the AWS IAM Documentation:
Important: Very few scenarios require the use of NotPrincipal, and we
recommend that you explore other authorization options before you
decide to use NotPrincipal.

Restrict cloudwatch access by region

I can't use a resource arn to restrict cloudwatch access.
But I can use conditions. Can I use a condition to only allow users to perform cloudwatch actions in a specific region? I haven't seen any examples of using conditions like this.
CloudWatch is very bad in terms of access control as it does not provide either resources to use in 'Resources' or condition Keys. At some point the DescribeAlarms action in particular was being performed on a US region and was causing unwanted errors when accessing through the console, but I don't see in my CloudTrail that it does now. Maybe it can be restricted to all actions now.
A policy statement to restrict cloudwatch access to the eu-central-region would be:
{
"Sid": "CloudWatchInFrankfurtOnly",
"Effect": "Deny",
"NotAction": ["cloudwatch:DescribeAlarms"],
"Resource": ["arn:aws:cloudwatch:*:*:alarm:*","arn:aws:cloudwatch::*:dashboard/*"],
"Condition": {"StringNotEquals": {"aws:RequestedRegion": "eu-central-1"}}
}
Yes you can use conditions in your policy, for example the below policy will only allow access to cloudwatch actions in eu-central-1.
{
"Statement": [
{ "Sid": "Stmt1338559372809",
"Action": [
"cloudwatch:GetMetricStatistics",
"cloudwatch:ListMetrics",
"cloudwatch:DescribeAlarms"
],
"Effect": "Allow",
"Resource": "*",
"Condition": {
"StringEquals": {
"ec2:Region": "eu-central-1"
}
}
}
]
}
Hope it will Help!

AWS allow policy to create tags for instances on a particular VPC

I want to be able to apply tags only to instances running in EC2 on a particular VPC (vpc-11111111).
I tried to use the policy
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "EC2TagNonresourceSpecificActions",
"Effect": "Allow",
"Action": [
"ec2:CreateTags",
"ec2:DeleteTags",
"ec2:DescribeTags"
],
"Condition": {
"StringEquals": {
"ec2:vpc": "arn:aws:ec2:<myRegion>:<myCustomerId>:vpc/vpc-11111111"
}
},
"Resource": "*"
}
]
}
but the user with this policy cannot modify the tags unless I remove the condition.
What have I done wrong?
Tags do not support conditions, according to Amazon docs and support.
This is a long standing feature request for several years!
Normally, if given some particular AWS user rights, the Tag rights is inside the policies.
Mistake in your new policies will overwrite those default access. You should try it out using AWS policy simulator.
Try add a principal and try it out.
"Principal": {
"AWS": "arn:aws:iam::<myCustomerId>:user/*"
}

Restricting S3 bucket access to a VPC

I am trying to apply the following policy in order to restrict my_bucket's access to a particular VPC.
When I try to apply this as a bucket policy, I get an Policy has an invalid condition key - ec2:Vpc.
How do I correct this?
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": "*",
"Resource": "arn:aws:s3:::my_bucket/*",
"Condition":{
"StringNotEquals": {
"ec2:Vpc": "arn:aws:ec2:region:account:vpc/vpc-ccccccc"
}
}
}
]
}
I just got this to work. I had to do two things. 1) Create the bucket policy on the S3 bucket, 2) create a "VPC Endpoint"
My S3 bucket policy looks like this (of course put in your bucket name and VPC identifier):
{
"Version": "2012-10-17",
"Id": "Policy1234567890123",
"Statement": [
{
"Sid": "Stmt1234567890123",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:*",
"Resource": "arn:aws:s3:::my_bucket/*",
"Condition": {
"StringEquals": {
"aws:sourceVpc": "vpc-12345678"
}
}
}
]
}
The S3 bucket also has some permissions outside the bucket policy to allow access from the AWS Console. Doing the above did not give access. To get access, I also had to go to AWS Console -> VPC -> Endpoints, and then create an endpoint. I attached the newly created endpoint to the only routing policy the account has at the moment (that has all subnets attached to it) and I used the default policy of
{
"Statement": [
{
"Action": "*",
"Effect": "Allow",
"Resource": "*",
"Principal": "*"
}
]
}
Once I created the endpoint, I was able to read from the S3 bucket from any EC2 instance in my VPC simply using wget with the right URL. I am still able to access the bucket from the AWS Console. But if I try to access the URL from outside the VPC, I get 403 forbidden. Thus, access to the S3 bucket is restricted to a single VPC, just like what you are looking for.
This is apparently a new feature. See this AWS blog entry for more information.
Two things that bit me and which might be helpful to add to Eddie's nice answer are:
First, you won't be able to view your bucket (or even modify its policy once you set the policy above) in the S3 AWS console unless you also give your AWS users permissions to manipulate the bucket. To do that, find your AWS account number (displayed in upper-right here), and add this statement to the bucket policy statements list:
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::YOUR_AWS_ACCOUNT_NUMBER:root"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::my_bucket",
"arn:aws:s3:::my_bucket/*"
]
},
Second, if you have more than one VPC, say vpc-XXXXXX and vpc-YYYYYY to give access to, the statement in Eddie's answer needs to be tweaked to something like the following (note the "Allow" "StringEquals" and list of sourceVpc values:
...
"Effect": "Allow",
...
"Condition": {
"StringEquals": {
"aws:sourceVpc": [
"vpc-XXXXXXXX",
"vpc-YYYYYYYY"
]
}
No, you can't do that.
Here's another person asking the same: https://forums.aws.amazon.com/thread.jspa?threadID=102387
Some have gotten overly creative with the problem trying to solve it with networking: https://pete.wtf/2012/05/01/how-to-setup-aws-s3-access-from-specific-ips/
I prefer a more simple route, S3 allows you to sign urls to solve this very problem, but inside of your VPC you may wish to not have to think about signing - or you just couldn't sign, for example you might be using wget, etc. So I wrote this little micro-service for that very reason: https://github.com/rmmeans/S3-Private-Downloader
Hope that helps!
UPDATED:
AWS now has a feature for VPC endpoints: https://aws.amazon.com/blogs/aws/new-vpc-endpoint-for-amazon-s3/, you should use that and not what I previously suggested.