mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-24 13:01:56 +00:00
fix(aws): raise ArgumentTypeError for parser (#4921)
This commit is contained in:
@@ -1245,7 +1245,7 @@ def validate_session_duration(duration: int) -> int:
|
||||
# Since the range(i,j) goes from i to j-1 we have to j+1
|
||||
if duration not in range(900, 43201):
|
||||
raise AWSArgumentTypeValidationError(
|
||||
original_exception="Session Duration must be between 900 and 43200 seconds.",
|
||||
message="Session Duration must be between 900 and 43200 seconds.",
|
||||
file=os.path.basename(__file__),
|
||||
)
|
||||
else:
|
||||
@@ -1274,5 +1274,5 @@ def validate_role_session_name(session_name) -> str:
|
||||
else:
|
||||
raise AWSArgumentTypeValidationError(
|
||||
file=os.path.basename(__file__),
|
||||
original_exception="Role Session Name must be between 2 and 64 characters and may contain alphanumeric characters, periods, hyphens, and underscores.",
|
||||
message="Role Session Name must be between 2 and 64 characters and may contain alphanumeric characters, periods, hyphens, and underscores.",
|
||||
)
|
||||
|
||||
@@ -8,188 +8,170 @@ class AWSBaseException(ProwlerException):
|
||||
(1902, "AWSClientError"): {
|
||||
"message": "AWS ClientError occurred",
|
||||
"remediation": "Check your AWS client configuration and permissions.",
|
||||
"file": "{file}",
|
||||
"provider": "AWS",
|
||||
},
|
||||
(1903, "AWSProfileNotFoundError"): {
|
||||
"message": "AWS Profile not found",
|
||||
"remediation": "Ensure the AWS profile is correctly configured, please visit https://docs.aws.amazon.com/cli/v1/userguide/cli-configure-files.html",
|
||||
"file": "{file}",
|
||||
"provider": "AWS",
|
||||
},
|
||||
(1904, "AWSNoCredentialsError"): {
|
||||
"message": "No AWS credentials found",
|
||||
"remediation": "Verify that AWS credentials are properly set up, please visit https://docs.prowler.com/projects/prowler-open-source/en/latest/tutorials/aws/authentication/ and https://docs.aws.amazon.com/cli/v1/userguide/cli-chap-configure.html",
|
||||
"file": "{file}",
|
||||
"provider": "AWS",
|
||||
},
|
||||
(1905, "AWSArgumentTypeValidationError"): {
|
||||
"message": "AWS argument type validation error",
|
||||
"remediation": "Check the provided argument types specific to AWS and ensure they meet the required format. For session duration check: https://docs.aws.amazon.com/singlesignon/latest/userguide/howtosessionduration.html and for role session name check: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_terms-and-concepts.html#iam-term-role-session-name",
|
||||
"file": "{file}",
|
||||
"provider": "AWS",
|
||||
},
|
||||
(1906, "AWSSetUpSessionError"): {
|
||||
"message": "AWS session setup error",
|
||||
"remediation": "Check the AWS session setup and ensure it is properly configured, please visit https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html and check if the provided profile has the necessary permissions.",
|
||||
"file": "{file}",
|
||||
"provider": "AWS",
|
||||
},
|
||||
(1907, "AWSIAMRoleARNRegionNotEmtpy"): {
|
||||
"message": "AWS IAM Role ARN region is not empty",
|
||||
"remediation": "Check the AWS IAM Role ARN region and ensure it is empty, visit https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html#identifiers-arns for more information.",
|
||||
"file": "{file}",
|
||||
"provider": "AWS",
|
||||
},
|
||||
(1908, "AWSIAMRoleARNPartitionEmpty"): {
|
||||
"message": "AWS IAM Role ARN partition is empty",
|
||||
"remediation": "Check the AWS IAM Role ARN partition and ensure it is not empty, visit https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html#identifiers-arns for more information.",
|
||||
"file": "{file}",
|
||||
"provider": "AWS",
|
||||
},
|
||||
(1909, "AWSIAMRoleARNMissingFields"): {
|
||||
"message": "AWS IAM Role ARN missing fields",
|
||||
"remediation": "Check the AWS IAM Role ARN and ensure all required fields are present, visit https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html#identifiers-arns for more information.",
|
||||
"file": "{file}",
|
||||
"provider": "AWS",
|
||||
},
|
||||
(1910, "AWSIAMRoleARNServiceNotIAMnorSTS"): {
|
||||
"message": "AWS IAM Role ARN service is not IAM nor STS",
|
||||
"remediation": "Check the AWS IAM Role ARN service and ensure it is either IAM or STS, visit https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html#identifiers-arns for more information.",
|
||||
"file": "{file}",
|
||||
"provider": "AWS",
|
||||
},
|
||||
(1911, "AWSIAMRoleARNInvalidAccountID"): {
|
||||
"message": "AWS IAM Role ARN account ID is invalid",
|
||||
"remediation": "Check the AWS IAM Role ARN account ID and ensure it is a valid 12-digit number, visit https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html#identifiers-arns for more information.",
|
||||
"file": "{file}",
|
||||
"provider": "AWS",
|
||||
},
|
||||
(1912, "AWSIAMRoleARNInvalidResourceType"): {
|
||||
"message": "AWS IAM Role ARN resource type is invalid",
|
||||
"remediation": "Check the AWS IAM Role ARN resource type and ensure it is valid, resources types are: role, user, assumed-role, root, federated-user, visit https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html#identifiers-arns for more information.",
|
||||
"file": "{file}",
|
||||
"provider": "AWS",
|
||||
},
|
||||
(1913, "AWSIAMRoleARNEmptyResource"): {
|
||||
"message": "AWS IAM Role ARN resource is empty",
|
||||
"remediation": "Check the AWS IAM Role ARN resource and ensure it is not empty, visit https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html#identifiers-arns for more information.",
|
||||
"file": "{file}",
|
||||
"provider": "AWS",
|
||||
},
|
||||
(1914, "AWSAssumeRoleError"): {
|
||||
"message": "AWS assume role error",
|
||||
"remediation": "Check the AWS assume role configuration and ensure it is properly set up, please visithttps://docs.prowler.com/projects/prowler-open-source/en/latest/tutorials/aws/role-assumption/ and https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_terms-and-concepts.html#iam-term-role-session-name",
|
||||
"file": "{file}",
|
||||
"provider": "AWS",
|
||||
"remediation": "Check the AWS assume role configuration and ensure it is properly set up, please visit https://docs.prowler.com/projects/prowler-open-source/en/latest/tutorials/aws/role-assumption/ and https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_terms-and-concepts.html#iam-term-role-session-name",
|
||||
},
|
||||
}
|
||||
|
||||
def __init__(self, code, provider="AWS", file=None, original_exception=None):
|
||||
def __init__(self, code, file=None, original_exception=None, message=None):
|
||||
error_info = self.AWS_ERROR_CODES.get((code, self.__class__.__name__))
|
||||
super().__init__(code, provider, file, original_exception, error_info)
|
||||
if message:
|
||||
error_info["message"] = message
|
||||
super().__init__(
|
||||
code,
|
||||
provider="AWS",
|
||||
file=file,
|
||||
original_exception=original_exception,
|
||||
error_info=error_info,
|
||||
)
|
||||
|
||||
|
||||
class AWSCredentialsError(AWSBaseException):
|
||||
"""Base class for AWS credentials errors."""
|
||||
|
||||
def __init__(self, code, provider="AWS", file=None, original_exception=None):
|
||||
super().__init__(code, provider, file, original_exception)
|
||||
def __init__(self, code, file=None, original_exception=None, message=None):
|
||||
super().__init__(code, file, original_exception, message)
|
||||
|
||||
|
||||
class AWSClientError(AWSCredentialsError):
|
||||
def __init__(self, file=None, original_exception=None):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1902, provider="AWS", file=file, original_exception=original_exception
|
||||
1902, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AWSProfileNotFoundError(AWSCredentialsError):
|
||||
def __init__(self, file=None, original_exception=None):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1903, provider="AWS", file=file, original_exception=original_exception
|
||||
1903, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AWSNoCredentialsError(AWSCredentialsError):
|
||||
def __init__(self, file=None, original_exception=None):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1904, provider="AWS", file=file, original_exception=original_exception
|
||||
1904, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AWSArgumentTypeValidationError(AWSBaseException):
|
||||
def __init__(self, file=None, original_exception=None):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1905, provider="AWS", file=file, original_exception=original_exception
|
||||
1905, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AWSSetUpSessionError(AWSBaseException):
|
||||
def __init__(self, file=None, original_exception=None):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1906, provider="AWS", file=file, original_exception=original_exception
|
||||
1906, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AWSRoleArnError(AWSBaseException):
|
||||
"""Base class for AWS role ARN errors."""
|
||||
|
||||
def __init__(self, code, provider="AWS", file=None, original_exception=None):
|
||||
super().__init__(code, provider, file, original_exception)
|
||||
def __init__(self, code, file=None, original_exception=None, message=None):
|
||||
super().__init__(code, file, original_exception, message)
|
||||
|
||||
|
||||
class AWSIAMRoleARNRegionNotEmtpy(AWSRoleArnError):
|
||||
def __init__(self, file=None, original_exception=None):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1907, provider="AWS", file=file, original_exception=original_exception
|
||||
1907, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AWSIAMRoleARNPartitionEmpty(AWSRoleArnError):
|
||||
def __init__(self, file=None, original_exception=None):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1908, provider="AWS", file=file, original_exception=original_exception
|
||||
1908, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AWSIAMRoleARNMissingFields(AWSRoleArnError):
|
||||
def __init__(self, file=None, original_exception=None):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1909, provider="AWS", file=file, original_exception=original_exception
|
||||
1909, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AWSIAMRoleARNServiceNotIAMnorSTS(AWSRoleArnError):
|
||||
def __init__(self, file=None, original_exception=None):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1910, provider="AWS", file=file, original_exception=original_exception
|
||||
1910, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AWSIAMRoleARNInvalidAccountID(AWSRoleArnError):
|
||||
def __init__(self, file=None, original_exception=None):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1911, provider="AWS", file=file, original_exception=original_exception
|
||||
1911, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AWSIAMRoleARNInvalidResourceType(AWSRoleArnError):
|
||||
def __init__(self, file=None, original_exception=None):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1912, provider="AWS", file=file, original_exception=original_exception
|
||||
1912, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AWSIAMRoleARNEmptyResource(AWSRoleArnError):
|
||||
def __init__(self, file=None, original_exception=None):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1913, provider="AWS", file=file, original_exception=original_exception
|
||||
1913, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AWSAssumeRoleError(AWSBaseException):
|
||||
def __init__(self, file=None, original_exception=None):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1914, provider="AWS", file=file, original_exception=original_exception
|
||||
1914, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
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,
|
||||
validate_role_session_name,
|
||||
validate_session_duration,
|
||||
)
|
||||
from prowler.providers.aws.aws_provider import get_aws_available_regions
|
||||
from prowler.providers.aws.config import ROLE_SESSION_NAME
|
||||
from prowler.providers.aws.lib.arn.arn import arn_type
|
||||
|
||||
@@ -172,6 +168,42 @@ def init_parser(self):
|
||||
)
|
||||
|
||||
|
||||
def validate_session_duration(session_duration: int) -> int:
|
||||
"""validate_session_duration validates that the input session_duration is valid"""
|
||||
duration = int(session_duration)
|
||||
# Since the range(i,j) goes from i to j-1 we have to j+1
|
||||
if duration not in range(900, 43201):
|
||||
raise ArgumentTypeError(
|
||||
"Session duration must be between 900 and 43200 seconds"
|
||||
)
|
||||
else:
|
||||
return duration
|
||||
|
||||
|
||||
def validate_role_session_name(session_name) -> str:
|
||||
"""
|
||||
Validates that the role session name is valid.
|
||||
|
||||
Args:
|
||||
session_name (str): The role session name to be validated.
|
||||
|
||||
Returns:
|
||||
str: The validated role session name.
|
||||
|
||||
Raises:
|
||||
ArgumentTypeError: If the role session name is invalid.
|
||||
|
||||
Documentation:
|
||||
- AWS STS AssumeRole API: https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html
|
||||
"""
|
||||
if fullmatch(r"[\w+=,.@-]{2,64}", session_name):
|
||||
return session_name
|
||||
else:
|
||||
raise ArgumentTypeError(
|
||||
"Role session name must be between 2 and 64 characters long and may contain alphanumeric characters, hyphens, underscores, plus signs, equal signs, commas, periods, at signs, and tildes."
|
||||
)
|
||||
|
||||
|
||||
def validate_arguments(arguments: Namespace) -> tuple[bool, str]:
|
||||
"""validate_arguments returns {True, "} if the provider arguments passed are valid and can be used together. It performs an extra validation, specific for the AWS provider, apart from the argparse lib."""
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ from mock import patch
|
||||
|
||||
from prowler.lib.cli.parser import ProwlerArgumentParser
|
||||
from prowler.providers.aws.config import ROLE_SESSION_NAME
|
||||
from prowler.providers.aws.exceptions.exceptions import AWSArgumentTypeValidationError
|
||||
from prowler.providers.aws.lib.arguments.arguments import (
|
||||
validate_bucket,
|
||||
validate_role_session_name,
|
||||
@@ -1326,13 +1325,13 @@ class Test_Parser:
|
||||
"role-name?",
|
||||
]
|
||||
for role_name in bad_role_names:
|
||||
with pytest.raises(AWSArgumentTypeValidationError) as argument_error:
|
||||
with pytest.raises(ArgumentTypeError) as argument_error:
|
||||
validate_role_session_name(role_name)
|
||||
|
||||
assert argument_error.type == AWSArgumentTypeValidationError
|
||||
assert argument_error.type == ArgumentTypeError
|
||||
assert (
|
||||
argument_error.value.args[0]
|
||||
== "[1905] AWS argument type validation error - Role Session Name must be between 2 and 64 characters and may contain alphanumeric characters, periods, hyphens, and underscores."
|
||||
== "Role session name must be between 2 and 64 characters long and may contain alphanumeric characters, hyphens, underscores, plus signs, equal signs, commas, periods, at signs, and tildes."
|
||||
)
|
||||
|
||||
def test_validate_role_session_name_valid_role_names(self):
|
||||
|
||||
@@ -1291,9 +1291,8 @@ aws:
|
||||
) # No profile to avoid ProfileNotFound error
|
||||
|
||||
assert exception.type == AWSNoCredentialsError
|
||||
assert (
|
||||
"AWSNoCredentialsError[1904]: No AWS credentials found - Unable to locate credentials"
|
||||
in str(exception.value)
|
||||
assert "AWSNoCredentialsError[1904]: No AWS credentials found" in str(
|
||||
exception.value
|
||||
)
|
||||
|
||||
@mock_aws
|
||||
@@ -1334,7 +1333,7 @@ aws:
|
||||
assert exception.type == AWSArgumentTypeValidationError
|
||||
assert (
|
||||
exception.value.args[0]
|
||||
== "[1905] AWS argument type validation error - Session Duration must be between 900 and 43200 seconds."
|
||||
== "[1905] Session Duration must be between 900 and 43200 seconds."
|
||||
)
|
||||
|
||||
@mock_aws
|
||||
@@ -1354,7 +1353,7 @@ aws:
|
||||
assert isinstance(connection.error, AWSArgumentTypeValidationError)
|
||||
assert (
|
||||
connection.error.args[0]
|
||||
== "[1905] AWS argument type validation error - Session Duration must be between 900 and 43200 seconds."
|
||||
== "[1905] Session Duration must be between 900 and 43200 seconds."
|
||||
)
|
||||
|
||||
@mock_aws
|
||||
@@ -1370,7 +1369,7 @@ aws:
|
||||
assert exception.type == AWSArgumentTypeValidationError
|
||||
assert (
|
||||
exception.value.args[0]
|
||||
== "[1905] AWS argument type validation error - Role Session Name must be between 2 and 64 characters and may contain alphanumeric characters, periods, hyphens, and underscores."
|
||||
== "[1905] Role Session Name must be between 2 and 64 characters and may contain alphanumeric characters, periods, hyphens, and underscores."
|
||||
)
|
||||
|
||||
@mock_aws
|
||||
|
||||
Reference in New Issue
Block a user