mirror of
https://github.com/ghndrx/prowler.git
synced 2026-02-10 06:45:08 +00:00
feat(aws): Added AWS role session name parameter (#3234)
Co-authored-by: Sergio Garcia <sergargar1@gmail.com>
This commit is contained in:
@@ -23,6 +23,15 @@ prowler aws -R arn:aws:iam::<account_id>:role/<role_name>
|
||||
prowler aws -T/--session-duration <seconds> -I/--external-id <external_id> -R arn:aws:iam::<account_id>:role/<role_name>
|
||||
```
|
||||
|
||||
## Custom Role Session Name
|
||||
|
||||
Prowler can use your custom Role Session name with:
|
||||
```console
|
||||
prowler aws --role-session-name <role_session_name>
|
||||
```
|
||||
|
||||
> It defaults to `ProwlerAssessmentSession`
|
||||
|
||||
## STS Endpoint Region
|
||||
|
||||
If you are using Prowler in AWS regions that are not enabled by default you need to use the argument `--sts-endpoint-region` to point the AWS STS API calls `assume-role` and `get-caller-identity` to the non-default region, e.g.: `prowler aws --sts-endpoint-region eu-south-2`.
|
||||
|
||||
@@ -113,9 +113,15 @@ def assume_role(
|
||||
sts_endpoint_region: str = None,
|
||||
) -> dict:
|
||||
try:
|
||||
role_session_name = (
|
||||
assumed_role_info.role_session_name
|
||||
if assumed_role_info.role_session_name
|
||||
else "ProwlerAssessmentSession"
|
||||
)
|
||||
|
||||
assume_role_arguments = {
|
||||
"RoleArn": assumed_role_info.role_arn,
|
||||
"RoleSessionName": "ProwlerAsessmentSession",
|
||||
"RoleSessionName": role_session_name,
|
||||
"DurationSeconds": assumed_role_info.session_duration,
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from argparse import ArgumentTypeError, Namespace
|
||||
from re import search
|
||||
from re import fullmatch, search
|
||||
|
||||
from prowler.providers.aws.aws_provider import get_aws_available_regions
|
||||
from prowler.providers.aws.lib.arn.arn import arn_type
|
||||
@@ -27,6 +27,13 @@ def init_parser(self):
|
||||
help="ARN of the role to be assumed",
|
||||
# Pending ARN validation
|
||||
)
|
||||
aws_auth_subparser.add_argument(
|
||||
"--role-session-name",
|
||||
nargs="?",
|
||||
default="ProwlerAssessmentSession",
|
||||
help="An identifier for the assumed role session. Defaults to ProwlerAssessmentSession",
|
||||
type=validate_role_session_name,
|
||||
)
|
||||
aws_auth_subparser.add_argument(
|
||||
"--sts-endpoint-region",
|
||||
nargs="?",
|
||||
@@ -203,3 +210,16 @@ def validate_bucket(bucket_name):
|
||||
raise ArgumentTypeError(
|
||||
"Bucket name must be valid (https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html)"
|
||||
)
|
||||
|
||||
|
||||
def validate_role_session_name(session_name):
|
||||
"""
|
||||
validates that the role session name is valid
|
||||
Documentation: https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html
|
||||
"""
|
||||
if fullmatch("[\w+=,.@-]{2,64}", session_name):
|
||||
return session_name
|
||||
else:
|
||||
raise ArgumentTypeError(
|
||||
"Role Session Name must be 2-64 characters long and consist only of upper- and lower-case alphanumeric characters with no spaces. You can also include underscores or any of the following characters: =,.@-"
|
||||
)
|
||||
|
||||
@@ -30,6 +30,7 @@ current_audit_info = AWS_Audit_Info(
|
||||
session_duration=None,
|
||||
external_id=None,
|
||||
mfa_enabled=None,
|
||||
role_session_name=None,
|
||||
),
|
||||
mfa_enabled=None,
|
||||
audit_resources=None,
|
||||
|
||||
@@ -20,6 +20,7 @@ class AWS_Assume_Role:
|
||||
session_duration: int
|
||||
external_id: str
|
||||
mfa_enabled: bool
|
||||
role_session_name: str
|
||||
|
||||
|
||||
@dataclass
|
||||
|
||||
@@ -85,6 +85,7 @@ Azure Identity Type: {Fore.YELLOW}[{audit_info.identity.identity_type}]{Style.RE
|
||||
current_audit_info.assumed_role_info.role_arn = input_role
|
||||
input_session_duration = arguments.get("session_duration")
|
||||
input_external_id = arguments.get("external_id")
|
||||
input_role_session_name = arguments.get("role_session_name")
|
||||
|
||||
# STS Endpoint Region
|
||||
sts_endpoint_region = arguments.get("sts_endpoint_region")
|
||||
@@ -153,6 +154,9 @@ Azure Identity Type: {Fore.YELLOW}[{audit_info.identity.identity_type}]{Style.RE
|
||||
)
|
||||
current_audit_info.assumed_role_info.external_id = input_external_id
|
||||
current_audit_info.assumed_role_info.mfa_enabled = input_mfa
|
||||
current_audit_info.assumed_role_info.role_session_name = (
|
||||
input_role_session_name
|
||||
)
|
||||
|
||||
# Check if role arn is valid
|
||||
try:
|
||||
|
||||
@@ -5,7 +5,10 @@ import pytest
|
||||
from mock import patch
|
||||
|
||||
from prowler.lib.cli.parser import ProwlerArgumentParser
|
||||
from prowler.providers.aws.lib.arguments.arguments import validate_bucket
|
||||
from prowler.providers.aws.lib.arguments.arguments import (
|
||||
validate_bucket,
|
||||
validate_role_session_name,
|
||||
)
|
||||
from prowler.providers.azure.lib.arguments.arguments import validate_azure_region
|
||||
|
||||
prowler_command = "prowler"
|
||||
@@ -1012,6 +1015,13 @@ class Test_Parser:
|
||||
parsed = self.parser.parse(command)
|
||||
assert parsed.sts_endpoint_region == sts_endpoint_region
|
||||
|
||||
def test_aws_parser_role_session_name(self):
|
||||
argument = "--role-session-name"
|
||||
role_session_name = "ProwlerAssessmentSession"
|
||||
command = [prowler_command, argument, role_session_name]
|
||||
parsed = self.parser.parse(command)
|
||||
assert parsed.role_session_name == role_session_name
|
||||
|
||||
def test_parser_azure_auth_sp(self):
|
||||
argument = "--sp-env-auth"
|
||||
command = [prowler_command, "azure", argument]
|
||||
@@ -1164,3 +1174,25 @@ class Test_Parser:
|
||||
valid_bucket_names = ["bucket-name" "test" "test-test-test"]
|
||||
for bucket_name in valid_bucket_names:
|
||||
assert validate_bucket(bucket_name) == bucket_name
|
||||
|
||||
def test_validate_role_session_name_invalid_role_names(self):
|
||||
bad_role_names = [
|
||||
"role name",
|
||||
"adasD*",
|
||||
"test#",
|
||||
"role-name?",
|
||||
]
|
||||
for role_name in bad_role_names:
|
||||
with pytest.raises(ArgumentTypeError) as argument_error:
|
||||
validate_role_session_name(role_name)
|
||||
|
||||
assert argument_error.type == ArgumentTypeError
|
||||
assert (
|
||||
argument_error.value.args[0]
|
||||
== "Role Session Name must be 2-64 characters long and consist only of upper- and lower-case alphanumeric characters with no spaces. You can also include underscores or any of the following characters: =,.@-"
|
||||
)
|
||||
|
||||
def test_validate_role_session_name_valid_role_names(self):
|
||||
valid_role_names = ["prowler-role" "test@" "test=test+test,."]
|
||||
for role_name in valid_role_names:
|
||||
assert validate_role_session_name(role_name) == role_name
|
||||
|
||||
@@ -32,7 +32,7 @@ class Test_AWS_Provider:
|
||||
@mock_iam
|
||||
@mock_sts
|
||||
def test_aws_provider_user_without_mfa(self):
|
||||
# sessionName = "ProwlerAsessmentSession"
|
||||
# sessionName = "ProwlerAssessmentSession"
|
||||
# Boto 3 client to create our user
|
||||
iam_client = boto3.client("iam", region_name=AWS_REGION_US_EAST_1)
|
||||
# IAM user
|
||||
@@ -56,6 +56,7 @@ class Test_AWS_Provider:
|
||||
session_duration=None,
|
||||
external_id=None,
|
||||
mfa_enabled=False,
|
||||
role_session_name="ProwlerAssessmentSession",
|
||||
),
|
||||
original_session=session,
|
||||
)
|
||||
@@ -75,6 +76,7 @@ class Test_AWS_Provider:
|
||||
session_duration=None,
|
||||
external_id=None,
|
||||
mfa_enabled=False,
|
||||
role_session_name="ProwlerAssessmentSession",
|
||||
)
|
||||
|
||||
@mock_iam
|
||||
@@ -103,6 +105,7 @@ class Test_AWS_Provider:
|
||||
session_duration=None,
|
||||
external_id=None,
|
||||
mfa_enabled=False,
|
||||
role_session_name="ProwlerAssessmentSession",
|
||||
),
|
||||
original_session=session,
|
||||
profile_region=AWS_REGION_US_EAST_1,
|
||||
@@ -123,6 +126,7 @@ class Test_AWS_Provider:
|
||||
session_duration=None,
|
||||
external_id=None,
|
||||
mfa_enabled=False,
|
||||
role_session_name="ProwlerAssessmentSession",
|
||||
)
|
||||
|
||||
@mock_iam
|
||||
@@ -132,7 +136,7 @@ class Test_AWS_Provider:
|
||||
role_name = "test-role"
|
||||
role_arn = f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:role/{role_name}"
|
||||
session_duration_seconds = 900
|
||||
sessionName = "ProwlerAsessmentSession"
|
||||
sessionName = "ProwlerAssessmentSession"
|
||||
|
||||
# Boto 3 client to create our user
|
||||
iam_client = boto3.client("iam", region_name=AWS_REGION_US_EAST_1)
|
||||
@@ -157,6 +161,7 @@ class Test_AWS_Provider:
|
||||
session_duration=session_duration_seconds,
|
||||
external_id=None,
|
||||
mfa_enabled=True,
|
||||
role_session_name="ProwlerAssessmentSession",
|
||||
),
|
||||
original_session=session,
|
||||
profile_region=AWS_REGION_US_EAST_1,
|
||||
@@ -210,7 +215,7 @@ class Test_AWS_Provider:
|
||||
role_name = "test-role"
|
||||
role_arn = f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:role/{role_name}"
|
||||
session_duration_seconds = 900
|
||||
sessionName = "ProwlerAsessmentSession"
|
||||
sessionName = "ProwlerAssessmentSession"
|
||||
|
||||
# Boto 3 client to create our user
|
||||
iam_client = boto3.client("iam", region_name=AWS_REGION_US_EAST_1)
|
||||
@@ -235,6 +240,7 @@ class Test_AWS_Provider:
|
||||
session_duration=session_duration_seconds,
|
||||
external_id=None,
|
||||
mfa_enabled=False,
|
||||
role_session_name="ProwlerAssessmentSession",
|
||||
),
|
||||
original_session=session,
|
||||
profile_region=AWS_REGION_US_EAST_1,
|
||||
@@ -282,7 +288,7 @@ class Test_AWS_Provider:
|
||||
session_duration_seconds = 900
|
||||
AWS_REGION_US_EAST_1 = AWS_REGION_EU_WEST_1
|
||||
sts_endpoint_region = AWS_REGION_US_EAST_1
|
||||
sessionName = "ProwlerAsessmentSession"
|
||||
sessionName = "ProwlerAssessmentSession"
|
||||
|
||||
# Boto 3 client to create our user
|
||||
iam_client = boto3.client("iam", region_name=AWS_REGION_US_EAST_1)
|
||||
@@ -307,6 +313,7 @@ class Test_AWS_Provider:
|
||||
session_duration=session_duration_seconds,
|
||||
external_id=None,
|
||||
mfa_enabled=False,
|
||||
role_session_name="ProwlerAssessmentSession",
|
||||
),
|
||||
original_session=session,
|
||||
profile_region=AWS_REGION_US_EAST_1,
|
||||
|
||||
@@ -116,6 +116,7 @@ class Test_Set_Audit_Info:
|
||||
session_duration=None,
|
||||
external_id=None,
|
||||
mfa_enabled=None,
|
||||
role_session_name="ProwlerAssessmentSession",
|
||||
),
|
||||
audited_regions=["eu-west-2", "eu-west-1"],
|
||||
organizations_metadata=None,
|
||||
|
||||
Reference in New Issue
Block a user