mirror of
https://github.com/ghndrx/prowler.git
synced 2026-02-10 06:45:08 +00:00
feat(iam_check_saml_providers_sts): Check and test (#1413)
This commit is contained in:
@@ -1,37 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Prowler - the handy cloud security tool (copyright 2018) 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_extra733="7.33"
|
||||
CHECK_TITLE_extra733="[extra733] Check if there are SAML Providers then STS can be used"
|
||||
CHECK_SCORED_extra733="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra733="EXTRA"
|
||||
CHECK_SEVERITY_extra733="Low"
|
||||
CHECK_ALTERNATE_check733="extra733"
|
||||
CHECK_ASFF_COMPLIANCE_TYPE_extra733="ens-op.acc.1.aws.iam.1"
|
||||
CHECK_SERVICENAME_extra733="iam"
|
||||
CHECK_RISK_extra733='Without SAML provider users with AWS CLI or AWS API access can use IAM static credentials. SAML helps users to assume role by default each time they authenticate.'
|
||||
CHECK_REMEDIATION_extra733='Enable SAML provider and use temporary credentials. You can use temporary security credentials to make programmatic requests for AWS resources using the AWS CLI or AWS API (using the AWS SDKs ). The temporary credentials provide the same permissions that you have with use long-term security credentials such as IAM user credentials. In case of not having SAML provider capabilities prevent usage of long-lived credentials.'
|
||||
CHECK_DOC_extra733='https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithSAML.html'
|
||||
CHECK_CAF_EPIC_extra733='IAM'
|
||||
|
||||
extra733(){
|
||||
LIST_SAML_PROV=$($AWSCLI iam list-saml-providers $PROFILE_OPT --query 'SAMLProviderList[*].Arn' --output text |grep -v ^None)
|
||||
if [[ $LIST_SAML_PROV ]]; then
|
||||
for provider in $LIST_SAML_PROV; do
|
||||
PROVIDER_NAME=$(echo $provider| cut -d/ -f2)
|
||||
textInfo "$REGION: SAML Provider $PROVIDER_NAME has been found" "$REGION" "$PROVIDER_NAME"
|
||||
done
|
||||
else
|
||||
textFail "$REGION: No SAML Provider found. Add one and use STS" "$REGION" "$PROVIDER_NAME"
|
||||
fi
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"Provider": "aws",
|
||||
"CheckID": "iam-check-saml-providers-sts",
|
||||
"CheckTitle": "Check if there are SAML Providers then STS can be used",
|
||||
"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": "low",
|
||||
"ResourceType": "Other",
|
||||
"Description": "Check if there are SAML Providers then STS can be used",
|
||||
"Risk": "Without SAML provider users with AWS CLI or AWS API access can use IAM static credentials. SAML helps users to assume role by default each time they authenticate.",
|
||||
"RelatedUrl": "",
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "",
|
||||
"NativeIaC": "",
|
||||
"Other": "",
|
||||
"Terraform": ""
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "Enable SAML provider and use temporary credentials. You can use temporary security credentials to make programmatic requests for AWS resources using the AWS CLI or AWS API (using the AWS SDKs ). The temporary credentials provide the same permissions that you have with use long-term security credentials such as IAM user credentials. In case of not having SAML provider capabilities prevent usage of long-lived credentials.",
|
||||
"Url": "https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithSAML.html"
|
||||
}
|
||||
},
|
||||
"Categories": [],
|
||||
"Tags": {
|
||||
"Tag1Key": "value",
|
||||
"Tag2Key": "value"
|
||||
},
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": "",
|
||||
"Compliance": []
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
from lib.check.models import Check, Check_Report
|
||||
from providers.aws.services.iam.iam_client import iam_client
|
||||
|
||||
|
||||
class iam_check_saml_providers_sts(Check):
|
||||
def execute(self) -> Check_Report:
|
||||
findings = []
|
||||
for provider in iam_client.saml_providers:
|
||||
report = Check_Report(self.metadata)
|
||||
provider_name = provider["Arn"].split("/")[1]
|
||||
report.resource_id = provider_name
|
||||
report.resource_arn = provider["Arn"]
|
||||
report.region = iam_client.region
|
||||
report.status = "PASS"
|
||||
report.status_extended = f"SAML Provider {provider_name} has been found"
|
||||
findings.append(report)
|
||||
|
||||
return findings
|
||||
@@ -0,0 +1,58 @@
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_iam
|
||||
|
||||
|
||||
class Test_iam_check_saml_providers_sts:
|
||||
@mock_iam
|
||||
def test_iam_check_saml_providers_sts(self):
|
||||
iam_client = client("iam")
|
||||
xml_template = r"""<EntityDescriptor
|
||||
xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
|
||||
entityID="loadbalancer-9.siroe.com">
|
||||
<SPSSODescriptor
|
||||
AuthnRequestsSigned="false"
|
||||
WantAssertionsSigned="false"
|
||||
protocolSupportEnumeration=
|
||||
"urn:oasis:names:tc:SAML:2.0:protocol">
|
||||
<KeyDescriptor use="signing">
|
||||
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
|
||||
<X509Data>
|
||||
<X509Certificate>
|
||||
MIICYDCCAgqgAwIBAgICBoowDQYJKoZIhvcNAQEEBQAwgZIxCzAJBgNVBAYTAlVTMRMwEQYDVQQI
|
||||
EwpDYWxpZm9ybmlhMRQwEgYDVQQHEwtTYW50YSBDbGFyYTEeMBwGA1UEChMVU3VuIE1pY3Jvc3lz
|
||||
dGVtcyBJbmMuMRowGAYDVQQLExFJZGVudGl0eSBTZXJ2aWNlczEcMBoGA1UEAxMTQ2VydGlmaWNh
|
||||
dGUgTWFuYWdlcjAeFw0wNjExMDIxOTExMzRaFw0xMDA3MjkxOTExMzRaMDcxEjAQBgNVBAoTCXNp
|
||||
cm9lLmNvbTEhMB8GA1UEAxMYbG9hZGJhbGFuY2VyLTkuc2lyb2UuY29tMIGfMA0GCSqGSIb3DQEB
|
||||
AQUAA4GNADCBiQKBgQCjOwa5qoaUuVnknqf5pdgAJSEoWlvx/jnUYbkSDpXLzraEiy2UhvwpoBgB
|
||||
EeTSUaPPBvboCItchakPI6Z/aFdH3Wmjuij9XD8r1C+q//7sUO0IGn0ORycddHhoo0aSdnnxGf9V
|
||||
tREaqKm9dJ7Yn7kQHjo2eryMgYxtr/Z5Il5F+wIDAQABo2AwXjARBglghkgBhvhCAQEEBAMCBkAw
|
||||
DgYDVR0PAQH/BAQDAgTwMB8GA1UdIwQYMBaAFDugITflTCfsWyNLTXDl7cMDUKuuMBgGA1UdEQQR
|
||||
MA+BDW1hbGxhQHN1bi5jb20wDQYJKoZIhvcNAQEEBQADQQB/6DOB6sRqCZu2OenM9eQR0gube85e
|
||||
nTTxU4a7x1naFxzYXK1iQ1vMARKMjDb19QEJIEJKZlDK4uS7yMlf1nFS
|
||||
</X509Certificate>
|
||||
</X509Data>
|
||||
</KeyInfo>
|
||||
</KeyDescriptor>
|
||||
</EntityDescriptor>"""
|
||||
saml_provider_name = "test"
|
||||
iam_client.create_saml_provider(
|
||||
SAMLMetadataDocument=xml_template, Name=saml_provider_name
|
||||
)
|
||||
|
||||
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_check_saml_providers_sts.iam_check_saml_providers_sts.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from providers.aws.services.iam.iam_check_saml_providers_sts.iam_check_saml_providers_sts import (
|
||||
iam_check_saml_providers_sts,
|
||||
)
|
||||
|
||||
check = iam_check_saml_providers_sts()
|
||||
result = check.execute()
|
||||
assert result[0].status == "PASS"
|
||||
@@ -25,6 +25,7 @@ class IAM:
|
||||
self.__list_attached_group_policies__()
|
||||
self.__list_mfa_devices__()
|
||||
self.password_policy = self.__get_password_policy__()
|
||||
self.saml_providers = self.__list_saml_providers__()
|
||||
|
||||
def __get_client__(self):
|
||||
return self.client
|
||||
@@ -237,6 +238,16 @@ class IAM:
|
||||
except Exception as error:
|
||||
logger.error(f"{self.region} -- {error.__class__.__name__}: {error}")
|
||||
|
||||
def __list_saml_providers__(self):
|
||||
try:
|
||||
saml_providers = self.client.list_saml_providers()["SAMLProviderList"]
|
||||
|
||||
except Exception as error:
|
||||
logger.error(f"{self.region} -- {error.__class__.__name__}: {error}")
|
||||
|
||||
finally:
|
||||
return saml_providers
|
||||
|
||||
|
||||
@dataclass
|
||||
class MFADevice:
|
||||
|
||||
@@ -374,3 +374,47 @@ class Test_IAM_Service:
|
||||
assert (
|
||||
iam.groups[0].attached_policies[0]["PolicyArn"] == policy["Policy"]["Arn"]
|
||||
)
|
||||
|
||||
# Test IAM List SAML Providers
|
||||
@mock_iam
|
||||
def test__list_saml_providers__(self):
|
||||
iam_client = client("iam")
|
||||
xml_template = r"""<EntityDescriptor
|
||||
xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
|
||||
entityID="loadbalancer-9.siroe.com">
|
||||
<SPSSODescriptor
|
||||
AuthnRequestsSigned="false"
|
||||
WantAssertionsSigned="false"
|
||||
protocolSupportEnumeration=
|
||||
"urn:oasis:names:tc:SAML:2.0:protocol">
|
||||
<KeyDescriptor use="signing">
|
||||
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
|
||||
<X509Data>
|
||||
<X509Certificate>
|
||||
MIICYDCCAgqgAwIBAgICBoowDQYJKoZIhvcNAQEEBQAwgZIxCzAJBgNVBAYTAlVTMRMwEQYDVQQI
|
||||
EwpDYWxpZm9ybmlhMRQwEgYDVQQHEwtTYW50YSBDbGFyYTEeMBwGA1UEChMVU3VuIE1pY3Jvc3lz
|
||||
dGVtcyBJbmMuMRowGAYDVQQLExFJZGVudGl0eSBTZXJ2aWNlczEcMBoGA1UEAxMTQ2VydGlmaWNh
|
||||
dGUgTWFuYWdlcjAeFw0wNjExMDIxOTExMzRaFw0xMDA3MjkxOTExMzRaMDcxEjAQBgNVBAoTCXNp
|
||||
cm9lLmNvbTEhMB8GA1UEAxMYbG9hZGJhbGFuY2VyLTkuc2lyb2UuY29tMIGfMA0GCSqGSIb3DQEB
|
||||
AQUAA4GNADCBiQKBgQCjOwa5qoaUuVnknqf5pdgAJSEoWlvx/jnUYbkSDpXLzraEiy2UhvwpoBgB
|
||||
EeTSUaPPBvboCItchakPI6Z/aFdH3Wmjuij9XD8r1C+q//7sUO0IGn0ORycddHhoo0aSdnnxGf9V
|
||||
tREaqKm9dJ7Yn7kQHjo2eryMgYxtr/Z5Il5F+wIDAQABo2AwXjARBglghkgBhvhCAQEEBAMCBkAw
|
||||
DgYDVR0PAQH/BAQDAgTwMB8GA1UdIwQYMBaAFDugITflTCfsWyNLTXDl7cMDUKuuMBgGA1UdEQQR
|
||||
MA+BDW1hbGxhQHN1bi5jb20wDQYJKoZIhvcNAQEEBQADQQB/6DOB6sRqCZu2OenM9eQR0gube85e
|
||||
nTTxU4a7x1naFxzYXK1iQ1vMARKMjDb19QEJIEJKZlDK4uS7yMlf1nFS
|
||||
</X509Certificate>
|
||||
</X509Data>
|
||||
</KeyInfo>
|
||||
</KeyDescriptor>
|
||||
</EntityDescriptor>"""
|
||||
saml_provider_name = "test"
|
||||
iam_client.create_saml_provider(
|
||||
SAMLMetadataDocument=xml_template, Name=saml_provider_name
|
||||
)
|
||||
|
||||
# IAM client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
iam = IAM(audit_info)
|
||||
|
||||
assert len(iam.saml_providers) == 1
|
||||
assert iam.saml_providers[0]["Arn"].split("/")[1] == saml_provider_name
|
||||
|
||||
Reference in New Issue
Block a user