mirror of
https://github.com/ghndrx/prowler.git
synced 2026-02-10 06:45:08 +00:00
feat(password_policy_checks): Include password policy checks (#1364)
This commit is contained in:
@@ -1,39 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Prowler - the handy cloud security tool (copyright 2019) by Toni de la Fuente
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
# use this file except in compliance with the License. You may obtain a copy
|
||||
# of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software distributed
|
||||
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations under the License.
|
||||
|
||||
CHECK_ID_check110="1.10"
|
||||
CHECK_TITLE_check110="[check110] Ensure IAM password policy prevents password reuse: 24 or greater"
|
||||
CHECK_SCORED_check110="SCORED"
|
||||
CHECK_CIS_LEVEL_check110="LEVEL1"
|
||||
CHECK_SEVERITY_check110="Medium"
|
||||
CHECK_ASFF_TYPE_check110="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
|
||||
CHECK_ALTERNATE_check110="check110"
|
||||
CHECK_SERVICENAME_check110="iam"
|
||||
CHECK_RISK_check110='Password policies are used to enforce password complexity requirements. IAM password policies can be used to ensure password are comprised of different character sets. It is recommended that the password policy require at least one uppercase letter.'
|
||||
CHECK_REMEDIATION_check110='Ensure "Number of passwords to remember" is set to 24.'
|
||||
CHECK_DOC_check110='https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_passwords_account-policy.html'
|
||||
CHECK_CAF_EPIC_check110='IAM'
|
||||
|
||||
check110(){
|
||||
# "Ensure IAM password policy prevents password reuse: 24 or greater (Scored)"
|
||||
COMMAND110=$($AWSCLI iam get-account-password-policy $PROFILE_OPT --region $REGION --query 'PasswordPolicy.PasswordReusePrevention' --output text 2> /dev/null)
|
||||
if [[ $COMMAND110 ]];then
|
||||
if [[ $COMMAND110 -gt "23" ]];then
|
||||
textPass "$REGION: Password Policy limits reuse" "$REGION" "password policy"
|
||||
else
|
||||
textFail "$REGION: Password Policy has weak reuse requirement (lower than 24)" "$REGION" "password policy"
|
||||
fi
|
||||
else
|
||||
textFail "$REGION: Password Policy missing reuse requirement" "$REGION" "password policy"
|
||||
fi
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Prowler - the handy cloud security tool (copyright 2019) by Toni de la Fuente
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
# use this file except in compliance with the License. You may obtain a copy
|
||||
# of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software distributed
|
||||
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations under the License.
|
||||
|
||||
CHECK_ID_check15="1.5"
|
||||
CHECK_TITLE_check15="[check15] Ensure IAM password policy requires at least one uppercase letter"
|
||||
CHECK_SCORED_check15="SCORED"
|
||||
CHECK_CIS_LEVEL_check15="LEVEL1"
|
||||
CHECK_SEVERITY_check15="Medium"
|
||||
CHECK_ASFF_TYPE_check15="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
|
||||
CHECK_ALTERNATE_check105="check15"
|
||||
CHECK_SERVICENAME_check15="iam"
|
||||
CHECK_RISK_check15='Password policies are used to enforce password complexity requirements. IAM password policies can be used to ensure password are comprised of different character sets. It is recommended that the password policy require at least one uppercase letter.'
|
||||
CHECK_REMEDIATION_check15='Ensure "Requires at least one uppercase letter" is checked under "Password Policy".'
|
||||
CHECK_DOC_check15='https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_passwords_account-policy.html'
|
||||
CHECK_CAF_EPIC_check15='IAM'
|
||||
|
||||
check15(){
|
||||
# "Ensure IAM password policy requires at least one uppercase letter (Scored)"
|
||||
COMMAND15=$($AWSCLI iam get-account-password-policy $PROFILE_OPT --region $REGION --output json --query 'PasswordPolicy.RequireUppercaseCharacters' 2> /dev/null) # must be true
|
||||
if [[ "$COMMAND15" == "true" ]];then
|
||||
textPass "$REGION: Password Policy requires upper case" "$REGION" "password policy"
|
||||
else
|
||||
textFail "$REGION: Password Policy missing upper-case requirement" "$REGION" "password policy"
|
||||
fi
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Prowler - the handy cloud security tool (copyright 2019) by Toni de la Fuente
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
# use this file except in compliance with the License. You may obtain a copy
|
||||
# of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software distributed
|
||||
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations under the License.
|
||||
|
||||
CHECK_ID_check16="1.6"
|
||||
CHECK_TITLE_check16="[check16] Ensure IAM password policy require at least one lowercase letter"
|
||||
CHECK_SCORED_check16="SCORED"
|
||||
CHECK_CIS_LEVEL_check16="LEVEL1"
|
||||
CHECK_SEVERITY_check16="Medium"
|
||||
CHECK_ASFF_TYPE_check16="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
|
||||
CHECK_ALTERNATE_check106="check16"
|
||||
CHECK_SERVICENAME_check16="iam"
|
||||
CHECK_RISK_check16='Password policies are used to enforce password complexity requirements. IAM password policies can be used to ensure password are comprised of different character sets. It is recommended that the password policy require at least one uppercase letter.'
|
||||
CHECK_REMEDIATION_check16='Ensure "Requires at least one lowercase letter" is checked under "Password Policy".'
|
||||
CHECK_DOC_check16='https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_passwords_account-policy.html'
|
||||
CHECK_CAF_EPIC_check16='IAM'
|
||||
|
||||
check16(){
|
||||
# "Ensure IAM password policy require at least one lowercase letter (Scored)"
|
||||
COMMAND16=$($AWSCLI iam get-account-password-policy $PROFILE_OPT --region $REGION --output json --query 'PasswordPolicy.RequireLowercaseCharacters' 2> /dev/null) # must be true
|
||||
if [[ "$COMMAND16" == "true" ]];then
|
||||
textPass "$REGION: Password Policy requires lower case" "$REGION" "password policy"
|
||||
else
|
||||
textFail "$REGION: Password Policy missing lower-case requirement" "$REGION" "password policy"
|
||||
fi
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Prowler - the handy cloud security tool (copyright 2019) by Toni de la Fuente
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
# use this file except in compliance with the License. You may obtain a copy
|
||||
# of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software distributed
|
||||
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations under the License.
|
||||
|
||||
CHECK_ID_check17="1.7"
|
||||
CHECK_TITLE_check17="[check17] Ensure IAM password policy require at least one symbol"
|
||||
CHECK_SCORED_check17="SCORED"
|
||||
CHECK_CIS_LEVEL_check17="LEVEL1"
|
||||
CHECK_SEVERITY_check17="Medium"
|
||||
CHECK_ASFF_TYPE_check17="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
|
||||
CHECK_ALTERNATE_check107="check17"
|
||||
CHECK_SERVICENAME_check17="iam"
|
||||
CHECK_RISK_check17='Password policies are used to enforce password complexity requirements. IAM password policies can be used to ensure password are comprised of different character sets. It is recommended that the password policy require at least one uppercase letter.'
|
||||
CHECK_REMEDIATION_check17='Ensure "Require at least one non-alphanumeric character" is checked under "Password Policy".'
|
||||
CHECK_DOC_check17='https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_passwords_account-policy.html'
|
||||
CHECK_CAF_EPIC_check17='IAM'
|
||||
|
||||
check17(){
|
||||
# "Ensure IAM password policy require at least one symbol (Scored)"
|
||||
COMMAND17=$($AWSCLI iam get-account-password-policy $PROFILE_OPT --region $REGION --output json --query 'PasswordPolicy.RequireSymbols' 2> /dev/null) # must be true
|
||||
if [[ "$COMMAND17" == "true" ]];then
|
||||
textPass "$REGION: Password Policy requires symbol" "$REGION" "password policy"
|
||||
else
|
||||
textFail "$REGION: Password Policy missing symbol requirement" "$REGION" "password policy"
|
||||
fi
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Prowler - the handy cloud security tool (copyright 2019) by Toni de la Fuente
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
# use this file except in compliance with the License. You may obtain a copy
|
||||
# of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software distributed
|
||||
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations under the License.
|
||||
|
||||
CHECK_ID_check18="1.8"
|
||||
CHECK_TITLE_check18="[check18] Ensure IAM password policy require at least one number"
|
||||
CHECK_SCORED_check18="SCORED"
|
||||
CHECK_CIS_LEVEL_check18="LEVEL1"
|
||||
CHECK_SEVERITY_check18="Medium"
|
||||
CHECK_ASFF_TYPE_check18="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
|
||||
CHECK_ALTERNATE_check108="check18"
|
||||
CHECK_SERVICENAME_check18="iam"
|
||||
CHECK_RISK_check18='Password policies are used to enforce password complexity requirements. IAM password policies can be used to ensure password are comprised of different character sets. It is recommended that the password policy require at least one uppercase letter.'
|
||||
CHECK_REMEDIATION_check18='Ensure "Require at least one number " is checked under "Password Policy".'
|
||||
CHECK_DOC_check18='https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_passwords_account-policy.html'
|
||||
CHECK_CAF_EPIC_check18='IAM'
|
||||
|
||||
check18(){
|
||||
# "Ensure IAM password policy require at least one number (Scored)"
|
||||
COMMAND18=$($AWSCLI iam get-account-password-policy $PROFILE_OPT --region $REGION --output json --query 'PasswordPolicy.RequireNumbers' 2> /dev/null) # must be true
|
||||
if [[ "$COMMAND18" == "true" ]];then
|
||||
textPass "$REGION: Password Policy requires number" "$REGION" "password policy"
|
||||
else
|
||||
textFail "$REGION: Password Policy missing number requirement" "$REGION" "password policy"
|
||||
fi
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Prowler - the handy cloud security tool (copyright 2019) by Toni de la Fuente
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
# use this file except in compliance with the License. You may obtain a copy
|
||||
# of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software distributed
|
||||
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations under the License.
|
||||
|
||||
CHECK_ID_check19="1.9"
|
||||
CHECK_TITLE_check19="[check19] Ensure IAM password policy requires minimum length of 14 or greater"
|
||||
CHECK_SCORED_check19="SCORED"
|
||||
CHECK_CIS_LEVEL_check19="LEVEL1"
|
||||
CHECK_SEVERITY_check19="Medium"
|
||||
CHECK_ASFF_TYPE_check19="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
|
||||
CHECK_ALTERNATE_check109="check19"
|
||||
CHECK_SERVICENAME_check19="iam"
|
||||
CHECK_RISK_check19='Password policies are used to enforce password complexity requirements. IAM password policies can be used to ensure password are comprised of different character sets. It is recommended that the password policy require at least one uppercase letter.'
|
||||
CHECK_REMEDIATION_check19='Ensure "Minimum password length" is set to 14 or greater.'
|
||||
CHECK_DOC_check19='https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_passwords_account-policy.html'
|
||||
CHECK_CAF_EPIC_check19='IAM'
|
||||
|
||||
check19(){
|
||||
# "Ensure IAM password policy requires minimum length of 14 or greater (Scored)"
|
||||
COMMAND19=$($AWSCLI iam get-account-password-policy $PROFILE_OPT --region $REGION --output json --query 'PasswordPolicy.MinimumPasswordLength' 2> /dev/null)
|
||||
if [[ $COMMAND19 -gt "13" ]];then
|
||||
textPass "$REGION: Password Policy requires more than 13 characters" "$REGION" "password policy"
|
||||
else
|
||||
textFail "$REGION: Password Policy missing or weak length requirement" "$REGION" "password policy"
|
||||
fi
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"Provider": "aws",
|
||||
"CheckID": "iam_password_policy_lowercase",
|
||||
"CheckTitle": "Ensure IAM password policy require at least one lowercase letter",
|
||||
"CheckType": ["Software and Configuration Checks", "Industry and Regulatory Standards" ,"CIS AWS Foundations Benchmark"],
|
||||
"ServiceName": "iam",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id",
|
||||
"Severity": "medium",
|
||||
"ResourceType": "AwsIamPasswordPolicy",
|
||||
"Description": "Ensure IAM password policy requires at least one uppercase letter",
|
||||
"Risk": "Password policies are used to enforce password complexity requirements. IAM password policies can be used to ensure password are comprised of different character sets. It is recommended that the password policy require at least one lowercase letter.",
|
||||
"RelatedUrl": "",
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "",
|
||||
"NativeIaC": "",
|
||||
"Other": "",
|
||||
"Terraform": ""
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "Ensure \"Requires at least one lowercase letter\" is checked under \"Password Policy\".",
|
||||
"Url": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_passwords_account-policy.html"
|
||||
}
|
||||
},
|
||||
"Categories": [],
|
||||
"Tags": {
|
||||
"Tag1Key": "value",
|
||||
"Tag2Key": "value"
|
||||
},
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": "",
|
||||
"Compliance": [
|
||||
{
|
||||
"Control": [
|
||||
"1.6"
|
||||
],
|
||||
"Framework": "CIS-AWS",
|
||||
"Group": [
|
||||
"level1"
|
||||
],
|
||||
"Version": "1.4"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
from lib.check.models import Check, Check_Report
|
||||
from providers.aws.services.iam.iam_client import iam_client
|
||||
|
||||
|
||||
class iam_password_policy_lowercase(Check):
|
||||
def execute(self) -> Check_Report:
|
||||
findings = []
|
||||
report = Check_Report(self.metadata)
|
||||
report.region = iam_client.region
|
||||
report.resource_id = "password_policy"
|
||||
# Check if password policy exists
|
||||
if iam_client.password_policy:
|
||||
# Check if lowercase flag is set
|
||||
if iam_client.password_policy.lowercase:
|
||||
report.status = "PASS"
|
||||
report.status_extended = "IAM password policy does not require at least one lowercase letter."
|
||||
else:
|
||||
report.status = "FAIL"
|
||||
report.status_extended = (
|
||||
"IAM password policy require at least one lowercase letter."
|
||||
)
|
||||
else:
|
||||
report.status = "FAIL"
|
||||
report.status_extended = f"Password policy cannot be found"
|
||||
findings.append(report)
|
||||
return findings
|
||||
@@ -0,0 +1,50 @@
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_iam
|
||||
|
||||
|
||||
class Test_iam_password_policy_lowercase:
|
||||
@mock_iam
|
||||
def test_iam_password_policy_no_lowercase_flag(self):
|
||||
iam_client = client("iam")
|
||||
# update password policy
|
||||
iam_client.update_account_password_policy(RequireLowercaseCharacters=False)
|
||||
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_password_policy_lowercase.iam_password_policy_lowercase.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from providers.aws.services.iam.iam_password_policy_lowercase.iam_password_policy_lowercase import (
|
||||
iam_password_policy_lowercase,
|
||||
)
|
||||
|
||||
check = iam_password_policy_lowercase()
|
||||
result = check.execute()
|
||||
assert result[0].status == "FAIL"
|
||||
|
||||
@mock_iam
|
||||
def test_iam_password_policy_lowercase_flag(self):
|
||||
iam_client = client("iam")
|
||||
# update password policy
|
||||
iam_client.update_account_password_policy(RequireLowercaseCharacters=True)
|
||||
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_password_policy_lowercase.iam_password_policy_lowercase.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from providers.aws.services.iam.iam_password_policy_lowercase.iam_password_policy_lowercase import (
|
||||
iam_password_policy_lowercase,
|
||||
)
|
||||
|
||||
check = iam_password_policy_lowercase()
|
||||
result = check.execute()
|
||||
assert result[0].status == "PASS"
|
||||
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"Provider": "aws",
|
||||
"CheckID": "iam_password_policy_minimum_length_14",
|
||||
"CheckTitle": "Ensure IAM password policy requires minimum length of 14 or greater",
|
||||
"CheckType": ["Software and Configuration Checks", "Industry and Regulatory Standards" ,"CIS AWS Foundations Benchmark"],
|
||||
"ServiceName": "iam",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id",
|
||||
"Severity": "medium",
|
||||
"ResourceType": "AwsIamPasswordPolicy",
|
||||
"Description": "Ensure IAM password policy requires minimum length of 14 or greater",
|
||||
"Risk": "Password policies are used to enforce password complexity requirements. IAM password policies can be used to ensure password are comprised of different character sets. It is recommended that the password policy require minimum length of 14 or greater.",
|
||||
"RelatedUrl": "",
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "",
|
||||
"NativeIaC": "",
|
||||
"Other": "",
|
||||
"Terraform": ""
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "Ensure \"Minimum password length\" is checked under \"Password Policy\".",
|
||||
"Url": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_passwords_account-policy.html"
|
||||
}
|
||||
},
|
||||
"Categories": [],
|
||||
"Tags": {
|
||||
"Tag1Key": "value",
|
||||
"Tag2Key": "value"
|
||||
},
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": "",
|
||||
"Compliance": [
|
||||
{
|
||||
"Control": [
|
||||
"1.9"
|
||||
],
|
||||
"Framework": "CIS-AWS",
|
||||
"Group": [
|
||||
"level1"
|
||||
],
|
||||
"Version": "1.4"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
from lib.check.models import Check, Check_Report
|
||||
from providers.aws.services.iam.iam_client import iam_client
|
||||
|
||||
|
||||
class iam_password_policy_minimum_length_14(Check):
|
||||
def execute(self) -> Check_Report:
|
||||
findings = []
|
||||
report = Check_Report(self.metadata)
|
||||
report.region = iam_client.region
|
||||
report.resource_id = "password_policy"
|
||||
# Check if password policy exists
|
||||
if iam_client.password_policy:
|
||||
# Check password policy length
|
||||
if (
|
||||
iam_client.password_policy.length
|
||||
and iam_client.password_policy.length >= 14
|
||||
):
|
||||
report.status = "PASS"
|
||||
report.status_extended = "IAM password policy does not requires minimum length of 14 characters."
|
||||
else:
|
||||
report.status = "FAIL"
|
||||
report.status_extended = (
|
||||
"IAM password policy requires minimum length of 14 characters."
|
||||
)
|
||||
else:
|
||||
report.status = "FAIL"
|
||||
report.status_extended = "Password policy cannot be found"
|
||||
findings.append(report)
|
||||
return findings
|
||||
@@ -0,0 +1,72 @@
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_iam
|
||||
|
||||
|
||||
class Test_iam_password_policy_minimum_length_14:
|
||||
@mock_iam
|
||||
def test_iam_password_policy_minimum_length_equal_14(self):
|
||||
iam_client = client("iam")
|
||||
# update password policy
|
||||
iam_client.update_account_password_policy(MinimumPasswordLength=14)
|
||||
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_password_policy_minimum_length_14.iam_password_policy_minimum_length_14.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from providers.aws.services.iam.iam_password_policy_minimum_length_14.iam_password_policy_minimum_length_14 import (
|
||||
iam_password_policy_minimum_length_14,
|
||||
)
|
||||
|
||||
check = iam_password_policy_minimum_length_14()
|
||||
result = check.execute()
|
||||
assert result[0].status == "PASS"
|
||||
|
||||
@mock_iam
|
||||
def test_iam_password_policy_minimum_length_greater_14(self):
|
||||
iam_client = client("iam")
|
||||
# update password policy
|
||||
iam_client.update_account_password_policy(MinimumPasswordLength=20)
|
||||
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_password_policy_minimum_length_14.iam_password_policy_minimum_length_14.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from providers.aws.services.iam.iam_password_policy_minimum_length_14.iam_password_policy_minimum_length_14 import (
|
||||
iam_password_policy_minimum_length_14,
|
||||
)
|
||||
|
||||
check = iam_password_policy_minimum_length_14()
|
||||
result = check.execute()
|
||||
assert result[0].status == "PASS"
|
||||
|
||||
@mock_iam
|
||||
def test_iam_password_policy_minimum_length_less_14(self):
|
||||
iam_client = client("iam")
|
||||
# update password policy
|
||||
iam_client.update_account_password_policy(MinimumPasswordLength=10)
|
||||
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_password_policy_minimum_length_14.iam_password_policy_minimum_length_14.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from providers.aws.services.iam.iam_password_policy_minimum_length_14.iam_password_policy_minimum_length_14 import (
|
||||
iam_password_policy_minimum_length_14,
|
||||
)
|
||||
|
||||
check = iam_password_policy_minimum_length_14()
|
||||
result = check.execute()
|
||||
assert result[0].status == "FAIL"
|
||||
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"Provider": "aws",
|
||||
"CheckID": "iam_password_policy_number",
|
||||
"CheckTitle": "Ensure IAM password policy require at least one number",
|
||||
"CheckType": ["Software and Configuration Checks", "Industry and Regulatory Standards" ,"CIS AWS Foundations Benchmark"],
|
||||
"ServiceName": "iam",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id",
|
||||
"Severity": "medium",
|
||||
"ResourceType": "AwsIamPasswordPolicy",
|
||||
"Description": "Ensure IAM password policy require at least one number",
|
||||
"Risk": "Password policies are used to enforce password complexity requirements. IAM password policies can be used to ensure password are comprised of different character sets. It is recommended that the password policy require at least one number.",
|
||||
"RelatedUrl": "",
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "",
|
||||
"NativeIaC": "",
|
||||
"Other": "",
|
||||
"Terraform": ""
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "Ensure \"Require at least one number\" is checked under \"Password Policy\".",
|
||||
"Url": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_passwords_account-policy.html"
|
||||
}
|
||||
},
|
||||
"Categories": [],
|
||||
"Tags": {
|
||||
"Tag1Key": "value",
|
||||
"Tag2Key": "value"
|
||||
},
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": "",
|
||||
"Compliance": [
|
||||
{
|
||||
"Control": [
|
||||
"1.8"
|
||||
],
|
||||
"Framework": "CIS-AWS",
|
||||
"Group": [
|
||||
"level1"
|
||||
],
|
||||
"Version": "1.4"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
from lib.check.models import Check, Check_Report
|
||||
from providers.aws.services.iam.iam_client import iam_client
|
||||
|
||||
|
||||
class iam_password_policy_number(Check):
|
||||
def execute(self) -> Check_Report:
|
||||
findings = []
|
||||
report = Check_Report(self.metadata)
|
||||
report.region = iam_client.region
|
||||
report.resource_id = "password_policy"
|
||||
# Check if password policy exists
|
||||
if iam_client.password_policy:
|
||||
# Check if number flag is set
|
||||
if iam_client.password_policy.numbers:
|
||||
report.status = "PASS"
|
||||
report.status_extended = (
|
||||
"IAM password policy does not require at least one number"
|
||||
)
|
||||
else:
|
||||
report.status = "FAIL"
|
||||
report.status_extended = (
|
||||
"IAM password policy require at least one number."
|
||||
)
|
||||
else:
|
||||
report.status = "FAIL"
|
||||
report.status_extended = "There is no password policy."
|
||||
findings.append(report)
|
||||
return findings
|
||||
@@ -0,0 +1,50 @@
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_iam
|
||||
|
||||
|
||||
class Test_iam_password_policy_number:
|
||||
@mock_iam
|
||||
def test_iam_password_policy_no_number_flag(self):
|
||||
iam_client = client("iam")
|
||||
# update password policy
|
||||
iam_client.update_account_password_policy(RequireNumbers=False)
|
||||
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_password_policy_number.iam_password_policy_number.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from providers.aws.services.iam.iam_password_policy_number.iam_password_policy_number import (
|
||||
iam_password_policy_number,
|
||||
)
|
||||
|
||||
check = iam_password_policy_number()
|
||||
result = check.execute()
|
||||
assert result[0].status == "FAIL"
|
||||
|
||||
@mock_iam
|
||||
def test_iam_password_policy_number_flag(self):
|
||||
iam_client = client("iam")
|
||||
# update password policy
|
||||
iam_client.update_account_password_policy(RequireNumbers=True)
|
||||
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_password_policy_number.iam_password_policy_number.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from providers.aws.services.iam.iam_password_policy_number.iam_password_policy_number import (
|
||||
iam_password_policy_number,
|
||||
)
|
||||
|
||||
check = iam_password_policy_number()
|
||||
result = check.execute()
|
||||
assert result[0].status == "PASS"
|
||||
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"Provider": "aws",
|
||||
"CheckID": "iam_password_policy_reuse_24",
|
||||
"CheckTitle": "Ensure IAM password policy prevents password reuse: 24 or greater",
|
||||
"CheckType": ["Software and Configuration Checks", "Industry and Regulatory Standards" ,"CIS AWS Foundations Benchmark"],
|
||||
"ServiceName": "iam",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id",
|
||||
"Severity": "medium",
|
||||
"ResourceType": "AwsIamPasswordPolicy",
|
||||
"Description": "Ensure IAM password policy prevents password reuse: 24 or greater",
|
||||
"Risk": "Password policies are used to enforce password complexity requirements. IAM password policies can be used to ensure password are comprised of different character sets. It is recommended that the password policy prevents at least password reuse of 24 or greater.",
|
||||
"RelatedUrl": "",
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "",
|
||||
"NativeIaC": "",
|
||||
"Other": "",
|
||||
"Terraform": ""
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "Ensure \"Number of passwords to remember\" is set to 24.",
|
||||
"Url": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_passwords_account-policy.html"
|
||||
}
|
||||
},
|
||||
"Categories": [],
|
||||
"Tags": {
|
||||
"Tag1Key": "value",
|
||||
"Tag2Key": "value"
|
||||
},
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": "",
|
||||
"Compliance": [
|
||||
{
|
||||
"Control": [
|
||||
"1.10"
|
||||
],
|
||||
"Framework": "CIS-AWS",
|
||||
"Group": [
|
||||
"level1"
|
||||
],
|
||||
"Version": "1.4"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
from lib.check.models import Check, Check_Report
|
||||
from providers.aws.services.iam.iam_client import iam_client
|
||||
|
||||
|
||||
class iam_password_policy_reuse_24(Check):
|
||||
def execute(self) -> Check_Report:
|
||||
findings = []
|
||||
report = Check_Report(self.metadata)
|
||||
report.region = iam_client.region
|
||||
report.resource_id = "password_policy"
|
||||
# Check if password policy exists
|
||||
if iam_client.password_policy:
|
||||
# Check if reuse prevention flag is set
|
||||
if (
|
||||
iam_client.password_policy.reuse_prevention
|
||||
and iam_client.password_policy.reuse_prevention == 24
|
||||
):
|
||||
report.status = "PASS"
|
||||
report.status_extended = (
|
||||
"IAM password policy reuse prevention is equal to 24."
|
||||
)
|
||||
else:
|
||||
report.status = "FAIL"
|
||||
report.status_extended = (
|
||||
"IAM password policy reuse prevention is less than 24 or not set."
|
||||
)
|
||||
else:
|
||||
report.status = "FAIL"
|
||||
report.status_extended = "Password policy cannot be found"
|
||||
findings.append(report)
|
||||
return findings
|
||||
@@ -0,0 +1,50 @@
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_iam
|
||||
|
||||
|
||||
class Test_iam_password_policy_reuse_24:
|
||||
@mock_iam
|
||||
def test_iam_password_policy_reuse_prevention_equal_24(self):
|
||||
iam_client = client("iam")
|
||||
# update password policy
|
||||
iam_client.update_account_password_policy(PasswordReusePrevention=24)
|
||||
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_password_policy_reuse_24.iam_password_policy_reuse_24.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from providers.aws.services.iam.iam_password_policy_reuse_24.iam_password_policy_reuse_24 import (
|
||||
iam_password_policy_reuse_24,
|
||||
)
|
||||
|
||||
check = iam_password_policy_reuse_24()
|
||||
result = check.execute()
|
||||
assert result[0].status == "PASS"
|
||||
|
||||
@mock_iam
|
||||
def test_iam_password_policy_reuse_prevention_less_24(self):
|
||||
iam_client = client("iam")
|
||||
# update password policy
|
||||
iam_client.update_account_password_policy(PasswordReusePrevention=20)
|
||||
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_password_policy_reuse_24.iam_password_policy_reuse_24.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from providers.aws.services.iam.iam_password_policy_reuse_24.iam_password_policy_reuse_24 import (
|
||||
iam_password_policy_reuse_24,
|
||||
)
|
||||
|
||||
check = iam_password_policy_reuse_24()
|
||||
result = check.execute()
|
||||
assert result[0].status == "FAIL"
|
||||
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"Provider": "aws",
|
||||
"CheckID": "iam_password_policy_symbol",
|
||||
"CheckTitle": "Ensure IAM password policy require at least one symbol",
|
||||
"CheckType": ["Software and Configuration Checks", "Industry and Regulatory Standards" ,"CIS AWS Foundations Benchmark"],
|
||||
"ServiceName": "iam",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id",
|
||||
"Severity": "medium",
|
||||
"ResourceType": "AwsIamPasswordPolicy",
|
||||
"Description": "Ensure IAM password policy require at least one symbol",
|
||||
"Risk": "Password policies are used to enforce password complexity requirements. IAM password policies can be used to ensure password are comprised of different character sets. It is recommended that the password policy require at least one non-alphanumeric character.",
|
||||
"RelatedUrl": "",
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "",
|
||||
"NativeIaC": "",
|
||||
"Other": "",
|
||||
"Terraform": ""
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "Ensure \"Require at least one non-alphanumeric character\" is checked under \"Password Policy\".",
|
||||
"Url": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_passwords_account-policy.html"
|
||||
}
|
||||
},
|
||||
"Categories": [],
|
||||
"Tags": {
|
||||
"Tag1Key": "value",
|
||||
"Tag2Key": "value"
|
||||
},
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": "",
|
||||
"Compliance": [
|
||||
{
|
||||
"Control": [
|
||||
"1.7"
|
||||
],
|
||||
"Framework": "CIS-AWS",
|
||||
"Group": [
|
||||
"level1"
|
||||
],
|
||||
"Version": "1.4"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
from lib.check.models import Check, Check_Report
|
||||
from providers.aws.services.iam.iam_client import iam_client
|
||||
|
||||
|
||||
class iam_password_policy_symbol(Check):
|
||||
def execute(self) -> Check_Report:
|
||||
findings = []
|
||||
report = Check_Report(self.metadata)
|
||||
report.region = iam_client.region
|
||||
report.resource_id = "password_policy"
|
||||
# Check if password policy exists
|
||||
if iam_client.password_policy:
|
||||
# Check if symbol flag is set
|
||||
if iam_client.password_policy.symbols:
|
||||
report.status = "PASS"
|
||||
report.status_extended = (
|
||||
"IAM password policy does not require at least one symbol."
|
||||
)
|
||||
else:
|
||||
report.status = "FAIL"
|
||||
report.status_extended = (
|
||||
"IAM password policy requires at least one symbol."
|
||||
)
|
||||
else:
|
||||
report.status = "FAIL"
|
||||
report.status_extended = "There is no password policy."
|
||||
findings.append(report)
|
||||
return findings
|
||||
@@ -0,0 +1,50 @@
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_iam
|
||||
|
||||
|
||||
class Test_iam_password_policy_symbol:
|
||||
@mock_iam
|
||||
def test_iam_password_policy_no_symbol_flag(self):
|
||||
iam_client = client("iam")
|
||||
# update password policy
|
||||
iam_client.update_account_password_policy(RequireSymbols=False)
|
||||
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_password_policy_symbol.iam_password_policy_symbol.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from providers.aws.services.iam.iam_password_policy_symbol.iam_password_policy_symbol import (
|
||||
iam_password_policy_symbol,
|
||||
)
|
||||
|
||||
check = iam_password_policy_symbol()
|
||||
result = check.execute()
|
||||
assert result[0].status == "FAIL"
|
||||
|
||||
@mock_iam
|
||||
def test_iam_password_policy_symbol_flag(self):
|
||||
iam_client = client("iam")
|
||||
# update password policy
|
||||
iam_client.update_account_password_policy(RequireSymbols=True)
|
||||
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_password_policy_symbol.iam_password_policy_symbol.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from providers.aws.services.iam.iam_password_policy_symbol.iam_password_policy_symbol import (
|
||||
iam_password_policy_symbol,
|
||||
)
|
||||
|
||||
check = iam_password_policy_symbol()
|
||||
result = check.execute()
|
||||
assert result[0].status == "PASS"
|
||||
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"Provider": "aws",
|
||||
"CheckID": "iam_password_policy_uppercase",
|
||||
"CheckTitle": "Ensure IAM password policy requires at least one uppercase letter",
|
||||
"CheckType": ["Software and Configuration Checks", "Industry and Regulatory Standards" ,"CIS AWS Foundations Benchmark"],
|
||||
"ServiceName": "iam",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id",
|
||||
"Severity": "medium",
|
||||
"ResourceType": "AwsIamPasswordPolicy",
|
||||
"Description": "Ensure IAM password policy requires at least one uppercase letter",
|
||||
"Risk": "Password policies are used to enforce password complexity requirements. IAM password policies can be used to ensure password are comprised of different character sets. It is recommended that the password policy require at least one uppercase letter.",
|
||||
"RelatedUrl": "",
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "",
|
||||
"NativeIaC": "",
|
||||
"Other": "",
|
||||
"Terraform": ""
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "Ensure \"Requires at least one uppercase letter\" is checked under \"Password Policy\".",
|
||||
"Url": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_passwords_account-policy.html"
|
||||
}
|
||||
},
|
||||
"Categories": [],
|
||||
"Tags": {
|
||||
"Tag1Key": "value",
|
||||
"Tag2Key": "value"
|
||||
},
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": "",
|
||||
"Compliance": [
|
||||
{
|
||||
"Control": [
|
||||
"1.5"
|
||||
],
|
||||
"Framework": "CIS-AWS",
|
||||
"Group": [
|
||||
"level1"
|
||||
],
|
||||
"Version": "1.4"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
from lib.check.models import Check, Check_Report
|
||||
from providers.aws.services.iam.iam_client import iam_client
|
||||
|
||||
|
||||
class iam_password_policy_uppercase(Check):
|
||||
def execute(self) -> Check_Report:
|
||||
findings = []
|
||||
report = Check_Report(self.metadata)
|
||||
report.region = iam_client.region
|
||||
report.resource_id = "password_policy"
|
||||
# Check if password policy exists
|
||||
if iam_client.password_policy:
|
||||
# Check if uppercase flag is set
|
||||
if iam_client.password_policy.uppercase:
|
||||
report.status = "PASS"
|
||||
report.status_extended = (
|
||||
"IAM password policy requires at least one uppercase letter."
|
||||
)
|
||||
else:
|
||||
report.status = "FAIL"
|
||||
report.status_extended = "IAM password policy does not require at least one uppercase letter."
|
||||
else:
|
||||
report.status = "FAIL"
|
||||
report.status_extended = "There is no password policy."
|
||||
findings.append(report)
|
||||
return findings
|
||||
@@ -0,0 +1,50 @@
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_iam
|
||||
|
||||
|
||||
class Test_iam_password_policy_uppercase:
|
||||
@mock_iam
|
||||
def test_iam_password_policy_no_uppercase_flag(self):
|
||||
iam_client = client("iam")
|
||||
# update password policy
|
||||
iam_client.update_account_password_policy(RequireUppercaseCharacters=False)
|
||||
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_password_policy_uppercase.iam_password_policy_uppercase.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from providers.aws.services.iam.iam_password_policy_uppercase.iam_password_policy_uppercase import (
|
||||
iam_password_policy_uppercase,
|
||||
)
|
||||
|
||||
check = iam_password_policy_uppercase()
|
||||
result = check.execute()
|
||||
assert result[0].status == "FAIL"
|
||||
|
||||
@mock_iam
|
||||
def test_iam_password_policy_uppercase_flag(self):
|
||||
iam_client = client("iam")
|
||||
# update password policy
|
||||
iam_client.update_account_password_policy(RequireUppercaseCharacters=True)
|
||||
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_password_policy_uppercase.iam_password_policy_uppercase.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from providers.aws.services.iam.iam_password_policy_uppercase.iam_password_policy_uppercase import (
|
||||
iam_password_policy_uppercase,
|
||||
)
|
||||
|
||||
check = iam_password_policy_uppercase()
|
||||
result = check.execute()
|
||||
assert result[0].status == "PASS"
|
||||
Reference in New Issue
Block a user