Compare commits

...
Author SHA1 Message Date
Prowler Botandprowler-bot 73ae2eb194 chore(api): Update prowler dependency to v5.42 for release 5.42.0 (#12796)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
2026-09-11 10:47:22 +02:00
Prowler Botandprowler-bot 4727da7ca7 chore(changelog): v5.42.0 (#12794)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
2026-09-11 10:21:17 +02:00
Pedro Martín b378f15798 fix(aws): guard checks reading iam roles when unlisted (#12785) 2026-09-11 08:37:20 +02:00
StylusFrostandpedrooot f9c02da90a feat(aws): support the ISO partitions for region resolution and scanning (#12759)
Co-authored-by: pedrooot <pedromarting3@gmail.com>
2026-09-10 17:15:13 +02:00
Pedro Martín 865eebe7fb fix(aws): configurable boto3 timeouts, 10s connect default (#12774) 2026-09-10 08:21:27 +02:00
Alejandro Bailo 8270979ec8 fix(ui): align scan filters and actions (#12781) 2026-09-09 23:05:09 +02:00
César Arrobaandpedrooot 369f852837 fix(aws): lead the partition bootstrap regions with the configured region (#12764)
Co-authored-by: pedrooot <pedromarting3@gmail.com>
2026-09-09 18:07:22 +02:00
César Arroba 1e8454a3cb fix(mcp): patch the six high libuuid CVEs in the container image (#12780) 2026-09-09 17:21:27 +02:00
César Arrobaandalejandrobailo 6f6ae88a66 fix(ui): patch the Next.js and sharp image-handling vulnerabilities (#12778)
Co-authored-by: alejandrobailo <alejandrobailo94@gmail.com>
2026-09-09 17:11:43 +02:00
César Arrobaandpedrooot c71f226e5c fix(image): honour TRIVY_CACHE_DIR when it is set (#12773)
Co-authored-by: pedrooot <pedromarting3@gmail.com>
2026-09-09 17:00:50 +02:00
Pedro Martín bbf5e1fa9f fix(tests): isolate secretsmanager policy test (#12782) 2026-09-09 16:58:35 +02:00
César Arroba 9cab9b8653 fix(ci): suppress grpc xDS DoS CVE from the Trivy binary (#12777) 2026-09-09 14:30:22 +02:00
César Arroba 806be2d061 chore(ci): bump agilepathway/label-checker to v1.6.66 (#12760) 2026-09-08 11:58:06 +02:00
Alejandro Bailo 2769cb9876 fix(ui): patch dependency vulnerabilities flagged by dependabot and pnpm audit (#12758) 2026-09-08 11:42:09 +02:00
César Arroba 623dc3125a chore(codeowners): consolidate retired teams under engineering (#12755) 2026-09-07 19:11:56 +02:00
Pedro Martínandalejandrobailo 1edcf6e5de fix(jira): fix connection check timeout (#12742)
Co-authored-by: alejandrobailo <alejandrobailo94@gmail.com>
2026-09-04 15:51:09 +02:00
Pedro Martín 8bdb597921 perf(api): speed up compliance overview ingestion (#12738) 2026-09-04 11:13:25 +02:00
Pedro Martín 1746e1052b fix(ci): suppress unfixed x/crypto CVEs from Trivy binary (#12740) 2026-09-04 10:09:17 +02:00
Pedro Martín 6827eef347 fix(ci): don't fail setup-python-uv on empty grep match (#12737) 2026-09-04 09:12:15 +02:00
90fc815d3c chore(release): Bump versions to v5.42.0 (#12713)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
Co-authored-by: Pepe Fagoaga <pepe@prowler.com>
Co-authored-by: pedrooot <pedromarting3@gmail.com>
2026-09-03 14:23:50 +02:00
Pedro Martín 8f35fff255 fix(compliance): remove duplicate ids and stale check refs (#12717) 2026-09-03 13:39:12 +02:00
Pedro Martín ab51d09543 fix(tests): isolate mock class attrs leaking across tests (#12728) 2026-09-03 12:20:33 +02:00
Pedro Martín 12faeb9aa2 chore(trivy): suppress fast-uri CVEs from Teams SPDX manifest (#12727) 2026-09-03 11:09:13 +02:00
Alejandro Bailo 9ed07de610 feat(ui): separate PostHog hosts and enable Toolbar in development (#12582) 2026-09-03 10:36:47 +02:00
Alejandro Bailo 8007501574 fix(ui): avoid missing selector in scan tour (#12705) 2026-09-03 10:23:24 +02:00
Pedro Martín 36514534cb chore(trivy): suppress CVE-2026-84304 in embedded grpc (#12720) 2026-09-03 10:17:14 +02:00
Pedro Martín 9621bdfb9c fix(tests): isolate provider mock in agentcore passrole (#12724) 2026-09-03 10:15:49 +02:00
158 changed files with 6554 additions and 1983 deletions
+1 -1
View File
@@ -158,7 +158,7 @@ SENTRY_RELEASE=local
# REO_DEV_CLIENT_ID=
#### Prowler release version ####
NEXT_PUBLIC_PROWLER_RELEASE_VERSION=v5.41.0
NEXT_PUBLIC_PROWLER_RELEASE_VERSION=v5.42.0
# Social login credentials
SOCIAL_GOOGLE_OAUTH_CALLBACK_URL="${AUTH_URL}/api/auth/callback/google"
+13 -13
View File
@@ -1,23 +1,23 @@
# SDK
/* @prowler-cloud/detection-remediation
/prowler/ @prowler-cloud/detection-remediation
/tests/ @prowler-cloud/detection-remediation
/dashboard/ @prowler-cloud/detection-remediation
/docs/ @prowler-cloud/detection-remediation
/examples/ @prowler-cloud/detection-remediation
/util/ @prowler-cloud/detection-remediation
/contrib/ @prowler-cloud/detection-remediation
/permissions/ @prowler-cloud/detection-remediation
/codecov.yml @prowler-cloud/detection-remediation @prowler-cloud/api
/* @prowler-cloud/engineering
/prowler/ @prowler-cloud/engineering
/tests/ @prowler-cloud/engineering
/dashboard/ @prowler-cloud/engineering
/docs/ @prowler-cloud/engineering
/examples/ @prowler-cloud/engineering
/util/ @prowler-cloud/engineering
/contrib/ @prowler-cloud/engineering
/permissions/ @prowler-cloud/engineering
/codecov.yml @prowler-cloud/engineering
# API
/api/ @prowler-cloud/api
/api/ @prowler-cloud/engineering
# UI
/ui/ @prowler-cloud/ui
/ui/ @prowler-cloud/engineering
# AI
/mcp_server/ @prowler-cloud/detection-remediation
/mcp_server/ @prowler-cloud/engineering
# Platform
/.github/ @prowler-cloud/platform
@@ -46,6 +46,17 @@ runs:
env:
GITHUB_TOKEN: ${{ github.token }}
run: |
if grep -q "prowler-cloud/prowler" uv.lock; then
:
else
status=$?
if [ "$status" -ne 1 ]; then
echo "::error::grep failed reading uv.lock (exit code $status)."
exit "$status"
fi
echo "No prowler-cloud/prowler entry in uv.lock, nothing to update."
exit 0
fi
LATEST_COMMIT=$(curl -sf --retry 3 --retry-all-errors --retry-delay 2 --retry-max-time 60 \
-H "Authorization: Bearer ${GITHUB_TOKEN}" \
-H "Accept: application/vnd.github+json" \
@@ -66,6 +77,17 @@ runs:
env:
GITHUB_TOKEN: ${{ github.token }}
run: |
if grep -q "prowler-cloud/prowler" uv.lock; then
:
else
status=$?
if [ "$status" -ne 1 ]; then
echo "::error::grep failed reading uv.lock (exit code $status)."
exit "$status"
fi
echo "No prowler-cloud/prowler entry in uv.lock, nothing to update."
exit 0
fi
LATEST_COMMIT=$(curl -sf --retry 3 --retry-all-errors --retry-delay 2 --retry-max-time 60 \
-H "Authorization: Bearer ${GITHUB_TOKEN}" \
-H "Accept: application/vnd.github+json" \
+1 -1
View File
@@ -39,7 +39,7 @@ jobs:
- name: Check labels
id: label_check
uses: agilepathway/label-checker@c3d16ad512e7cea5961df85ff2486bb774caf3c5 # v1.6.65
uses: agilepathway/label-checker@c324842522fbd012e4f590afe3b4e591301322ed # v1.6.66
with:
allow_failure: true
prefix_mode: true
@@ -44,7 +44,10 @@ jobs:
cache: 'pip'
- name: Install dependencies
run: pip install boto3
# Pinned to the versions in pyproject.toml: the ISO partitions region
# data comes from the endpoints.json bundled with botocore, so the
# botocore version is itself a data source and must be deterministic
run: pip install boto3==1.40.61 botocore==1.40.61
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@d979d5b3a71173a29b74b5b88418bfda9437d885 # v6.1.1
+34
View File
@@ -17,6 +17,40 @@ ignore:
- vulnerability: CVE-2026-71556
package:
name: github.com/go-git/go-git/v5
# CVE-2026-84304 is the same temporary exception documented in .trivyignore.yaml:
# Trivy 0.74.0 still embeds grpc 1.82.1, while the 1.83.1 fix is not in any release.
# Prowler only runs `trivy image` / `trivy fs`, never client/server mode, so no gRPC
# endpoint exists in the image. Pinned to the embedded version so the rule stops
# matching on its own once Trivy bumps grpc. Remove with the Trivy exception by 2026-10-15.
# https://github.com/aquasecurity/trivy/pull/11176
- vulnerability: CVE-2026-84304
package:
name: google.golang.org/grpc
version: v1.82.1
# CVE-2026-84445 is the same temporary exception documented in .trivyignore.yaml:
# Trivy 0.74.0 still embeds grpc 1.82.1, while the 1.82.2 / 1.83.2 fix is not in any
# release. The panic needs a gRPC server built with `xds.NewGRPCServer()`; Prowler only
# runs `trivy image` / `trivy fs`, so the image serves no gRPC at all. Pinned to the
# embedded version so the rule stops matching on its own once Trivy bumps grpc. Remove
# with the Trivy exception by 2026-10-15.
# https://github.com/advisories/GHSA-2v4p-qf9q-27wj
- vulnerability: CVE-2026-84445
package:
name: google.golang.org/grpc
version: v1.82.1
# CVE-2026-56855 / CVE-2026-78662 are the same temporary exception documented in
# .trivyignore.yaml: Trivy 0.74.0 still embeds golang.org/x/crypto v0.55.0, while the
# 0.56.0 fix (published 2026-09-02) hasn't reached any Trivy release, or even Trivy
# main, yet. Pinned to the embedded version so the rule stops matching on its own once
# Trivy bumps it. Remove with the Trivy exception by 2026-10-15.
- vulnerability: CVE-2026-56855
package:
name: golang.org/x/crypto
version: v0.55.0
- vulnerability: CVE-2026-78662
package:
name: golang.org/x/crypto
version: v0.55.0
- vulnerability: CVE-2026-56852
package:
name: golang.org/x/text
+68
View File
@@ -113,6 +113,18 @@ vulnerabilities:
purls:
- "pkg:npm/fast-uri"
expired_at: 2027-01-31
- id: CVE-2026-75899
purls:
- "pkg:npm/fast-uri"
expired_at: 2027-01-31
- id: CVE-2026-75975
purls:
- "pkg:npm/fast-uri"
expired_at: 2027-01-31
- id: CVE-2026-76172
purls:
- "pkg:npm/fast-uri"
expired_at: 2027-01-31
- id: CVE-2026-69192
purls:
- "pkg:npm/ip-address"
@@ -148,6 +160,62 @@ vulnerabilities:
- "pkg:golang/github.com/go-git/go-git/v5"
expired_at: 2026-09-15
# CVE-2026-84304 is a DoS in grpc-go <= 1.83.0: a peer fragments a gRPC stream into
# millions of tiny HTTP/2 DATA frames until the receiver runs out of heap. Fixed in
# 1.83.1 (published 2026-09-01). Trivy 0.74.0, the latest published release and the
# version the images ship, pins 1.82.1 as an indirect dependency:
# https://github.com/aquasecurity/trivy/blob/v0.74.0/go.mod
# Upstream bump still open: https://github.com/aquasecurity/trivy/pull/11176
# Trivy only speaks gRPC in client/server mode (`trivy server`, `--server`). Prowler
# invokes it exclusively as `trivy image` and `trivy fs` on a local path, so no gRPC
# listener or connection ever exists in the image and the affected path is not
# reachable. Remove this temporary suppression as soon as a Trivy release pins
# grpc >= 1.83.1.
- id: CVE-2026-84304
purls:
- "pkg:golang/google.golang.org/grpc"
expired_at: 2026-10-15
# CVE-2026-84445 is a DoS in grpc-go servers built with `xds.NewGRPCServer()`: a request
# carrying neither `:authority` nor `Host` reaches the xDS routing interceptor, which
# indexes an empty slice of authorities and panics. The per-RPC goroutine does not
# recover, so the whole server process dies. Fixed in 1.82.2 and 1.83.2 (published
# 2026-09-08). Trivy 0.74.0, the latest published release and the version the images
# ship, pins 1.82.1 as an indirect dependency:
# https://github.com/aquasecurity/trivy/blob/v0.74.0/go.mod
# Trivy main already carries 1.83.2, but no published release includes it yet.
# The reachability argument is the one made for CVE-2026-84304 above, only narrower:
# this panic needs an xDS-managed gRPC server. Prowler invokes Trivy exclusively as
# `trivy image` and `trivy fs` on a local path, never `trivy server`, so the image runs
# no gRPC server at all, xDS or otherwise. Remove this temporary suppression as soon as
# a Trivy release pins grpc >= 1.83.2.
# https://github.com/advisories/GHSA-2v4p-qf9q-27wj
- id: CVE-2026-84445
purls:
- "pkg:golang/google.golang.org/grpc@v1.82.1"
expired_at: 2026-10-15
# CVE-2026-56855 and CVE-2026-78662 are DoS deadlocks in x/crypto/ssh: a malicious peer
# can flood or misuse channel messages (RFC 4254) to block the whole connection.
# Fixed in golang.org/x/crypto v0.56.0 (published 2026-09-02). Trivy 0.74.0, the latest
# published release and the version the images ship, still pins v0.55.0, and Trivy main
# has not bumped it either:
# https://github.com/aquasecurity/trivy/blob/v0.74.0/go.mod
# x/crypto/ssh is pulled in transitively through go-git's ssh transport, the same
# dependency chain as the CVE-2026-71556 entry above. Prowler invokes Trivy only with
# `fs` on an existing local path or with `image`; it never asks Trivy to clone over SSH
# or to run `trivy server`, so no SSH connection -- as client or server -- ever exists in
# the image and the affected code path is not reachable. Remove this temporary
# suppression as soon as a fixed Trivy release is available.
- id: CVE-2026-56855
purls:
- "pkg:golang/golang.org/x/crypto@v0.55.0"
expired_at: 2026-10-15
- id: CVE-2026-78662
purls:
- "pkg:golang/golang.org/x/crypto@v0.55.0"
expired_at: 2026-10-15
- id: CVE-2026-56852
purls:
- "pkg:golang/golang.org/x/text"
+8
View File
@@ -4,6 +4,14 @@ All notable changes to the **Prowler API** are documented in this file.
<!-- changelog: release notes start -->
## [1.43.0] (Prowler v5.42.0)
### 🔄 Changed
- Speed up compliance overview ingestion by reading ThreatScore mappings from the compliance template instead of each finding, generating time-ordered `uuid7` row ids and grouping inserted rows by framework and requirement [(#12738)](https://github.com/prowler-cloud/prowler/pull/12738)
---
## [1.42.0] (Prowler v5.41.0)
### 🚀 Added
+2 -2
View File
@@ -45,7 +45,7 @@ dependencies = [
"gunicorn==26.0.0",
"uvloop==0.22.1",
"lxml==6.1.0",
"prowler @ git+https://github.com/prowler-cloud/prowler.git@master",
"prowler @ git+https://github.com/prowler-cloud/prowler.git@v5.42",
"psycopg2-binary==2.9.9",
"pytest-celery[redis] (==1.3.0)",
"sentry-sdk[django] (==2.56.0)",
@@ -71,7 +71,7 @@ name = "prowler-api"
package-mode = false
# Needed for the SDK compatibility
requires-python = ">=3.11,<3.13"
version = "1.42.0"
version = "1.43.0"
# Shared ruff baseline (kept in sync with mcp_server/pyproject.toml).
# target-version tracks this project's lowest supported Python.
+1 -1
View File
@@ -1,7 +1,7 @@
openapi: 3.0.3
info:
title: Prowler API
version: 1.42.0
version: 1.43.0
description: |-
Prowler API specification.
+57 -36
View File
@@ -5,7 +5,6 @@ import json
import random
import re
import time
import uuid
from collections import defaultdict
from collections.abc import Callable, Iterable
from datetime import UTC, datetime
@@ -73,6 +72,7 @@ from tasks.jobs.queries import (
COMPLIANCE_UPSERT_TENANT_SUMMARY_SQL,
)
from tasks.utils import CustomEncoder, batched
from uuid6 import uuid7
logger = get_task_logger(__name__)
@@ -1756,32 +1756,27 @@ def aggregate_findings(tenant_id: str, scan_id: str):
def _aggregate_findings_by_region(
tenant_id: str, scan_id: str, modeled_threatscore_compliance_id: str
tenant_id: str,
scan_id: str,
normalized_threatscore_id: str,
threatscore_requirements_by_check: dict[str, list[str]],
) -> tuple[dict, dict]:
"""
Aggregate findings by region using streaming, column-scoped ORM reads.
Reads only the consumed columns as tuples via ``values_list`` and streams
them with ``.iterator()``, using the denormalized ``resource_regions`` array
instead of ``prefetch_related("resources")``. ``resource_regions`` mirrors the
regions of a finding's related resources, so it yields the same per-region
tally without joining the resource table.
Args:
tenant_id: Tenant UUID
scan_id: Scan UUID
modeled_threatscore_compliance_id: ID for ThreatScore compliance framework
instead of ``prefetch_related("resources")``. ThreatScore requirement ids
are resolved per ``check_id`` from ``threatscore_requirements_by_check``.
Returns:
tuple: (check_status_by_region, findings_count_by_compliance)
- check_status_by_region: {region: {check_id: status}}
- findings_count_by_compliance: {region: {normalized_id: {requirement_id: {total, pass}}}}
- findings_count_by_compliance: {region: {normalized_threatscore_id: {requirement_id: {total, pass}}}}
"""
check_status_by_region: dict = {}
findings_count_by_compliance: dict = {}
normalized_id = re.sub(r"[^a-z0-9]", "", modeled_threatscore_compliance_id.lower())
with rls_transaction(tenant_id, using=READ_REPLICA_ALIAS):
findings = (
Finding.all_objects.filter(
@@ -1790,14 +1785,12 @@ def _aggregate_findings_by_region(
muted=False,
status__in=["PASS", "FAIL"],
)
.values_list("check_id", "status", "resource_regions", "compliance")
.values_list("check_id", "status", "resource_regions")
.iterator(chunk_size=DJANGO_FINDINGS_BATCH_SIZE)
)
for check_id, status, resource_regions, compliance in findings:
threatscore_requirements = (compliance or {}).get(
modeled_threatscore_compliance_id
)
for check_id, status, resource_regions in findings:
threatscore_requirements = threatscore_requirements_by_check.get(check_id)
for region in resource_regions or ():
# Priority: FAIL > any other status
@@ -1809,7 +1802,7 @@ def _aggregate_findings_by_region(
if threatscore_requirements:
compliance_key = findings_count_by_compliance.setdefault(
region, {}
).setdefault(normalized_id, {})
).setdefault(normalized_threatscore_id, {})
for requirement_id in threatscore_requirements:
requirement_stats = compliance_key.setdefault(
@@ -1848,15 +1841,28 @@ def create_compliance_requirements(tenant_id: str, scan_id: str):
compliance_template = PROWLER_COMPLIANCE_OVERVIEW_TEMPLATE[
provider_instance.provider
]
modeled_threatscore_compliance_id = "ProwlerThreatScore-1.0"
normalized_threatscore_id = _normalized_compliance_key(
"ProwlerThreatScore", "1.0"
)
requirement_lookup: dict[str, list[tuple[str, str]]] = {}
threatscore_requirements_by_check: dict[str, list[str]] = {}
for compliance_id, compliance in compliance_template.items():
is_threatscore = (
_normalized_compliance_key(
compliance["framework"], compliance["version"]
)
== normalized_threatscore_id
)
for requirement_id, requirement in compliance["requirements"].items():
for check_id in requirement["checks"].keys():
requirement_lookup.setdefault(check_id, []).append(
(compliance_id, requirement_id)
)
if is_threatscore:
threatscore_requirements_by_check.setdefault(
check_id, []
).append(requirement_id)
regions = []
requirements_created = 0
@@ -1869,7 +1875,10 @@ def create_compliance_requirements(tenant_id: str, scan_id: str):
# Aggregate findings by region using SQL for optimal performance
check_status_by_region, findings_count_by_compliance = (
_aggregate_findings_by_region(
tenant_id, scan_id, modeled_threatscore_compliance_id
tenant_id,
scan_id,
normalized_threatscore_id,
threatscore_requirements_by_check,
)
)
@@ -1934,23 +1943,35 @@ def create_compliance_requirements(tenant_id: str, scan_id: str):
# Yield rows lazily (consumed batch-by-batch by COPY) so peak memory
# stays bounded; tally requirement_statuses in the same pass. The
# ORM fallback re-iterates from scratch, so the tally resets first.
# Region is the innermost loop so consecutive rows share the leading
# columns of the table's secondary indexes.
def _iter_compliance_requirement_rows():
requirement_statuses.clear()
for region in regions:
region_stats = region_requirement_stats.get(region, {})
region_findings = findings_count_by_compliance.get(region, {})
for (
compliance_id,
framework,
version,
modeled_compliance_id,
requirements,
) in compliance_plan:
compliance_stats = region_stats.get(compliance_id, {})
compliance_findings = region_findings.get(
modeled_compliance_id, {}
for (
compliance_id,
framework,
version,
modeled_compliance_id,
requirements,
) in compliance_plan:
stats_by_region = [
(
region,
region_requirement_stats.get(region, {}).get(
compliance_id, {}
),
findings_count_by_compliance.get(region, {}).get(
modeled_compliance_id, {}
),
)
for requirement_id, description, total_checks in requirements:
for region in regions
]
for requirement_id, description, total_checks in requirements:
for (
region,
compliance_stats,
compliance_findings,
) in stats_by_region:
stats = compliance_stats.get(requirement_id)
if stats:
passed_checks = stats["passed_checks"]
@@ -1981,7 +2002,7 @@ def create_compliance_requirements(tenant_id: str, scan_id: str):
requirement_statuses[key]["pass_count"] += 1
yield {
"id": uuid.uuid4(),
"id": uuid7(),
"tenant_id": tenant_id_str,
"inserted_at": utc_datetime_now,
"compliance_id": compliance_id,
+229 -66
View File
@@ -1,6 +1,5 @@
import csv
import json
import re
import uuid
from collections.abc import MutableMapping
from contextlib import contextmanager
@@ -10,6 +9,7 @@ from unittest.mock import MagicMock, patch
import pytest
from api.db_router import MainRouter
from api.db_utils import rls_transaction
from api.exceptions import ProviderConnectionError, ProviderDeletedException
from api.models import (
Finding,
@@ -2795,6 +2795,167 @@ class TestCreateComplianceRequirements:
assert count_after_first > 0
assert count_after_second == count_after_first
with rls_transaction(tenant_id):
row_versions = {
row_id.version
for row_id in ComplianceRequirementOverview.objects.filter(
scan_id=scan_id
).values_list("id", flat=True)
}
assert row_versions == {7}
def test_create_compliance_requirements_threatscore_counts_from_template(
self,
tenants_fixture,
scans_fixture,
aws_provider,
findings_fixture,
):
"""ThreatScore finding counts are derived from the template mapping,
not from each finding's stored ``compliance`` payload."""
from api.models import ComplianceRequirementOverview
with patch(
"tasks.jobs.scan.PROWLER_COMPLIANCE_OVERVIEW_TEMPLATE"
) as mock_compliance_template:
tenant_id = str(tenants_fixture[0].id)
scan_id = str(scans_fixture[0].id)
mock_compliance_template.__getitem__.return_value = {
"prowler_threatscore_aws": {
"framework": "ProwlerThreatScore",
"version": "1.0",
"requirements": {
"1.1.1": {
"description": "ThreatScore requirement",
"checks": {"test_check_id": None},
},
"1.1.2": {
"description": "Unrelated requirement",
"checks": {"other_check_id": None},
},
},
},
"other_framework": {
"framework": "Other",
"version": "2.0",
"requirements": {
"a": {
"description": "Same check, other framework",
"checks": {"test_check_id": None},
},
},
},
}
create_compliance_requirements(tenant_id, scan_id)
with rls_transaction(tenant_id):
counted = sum(
len(finding.resource_regions or [])
for finding in Finding.all_objects.filter(
scan_id=scan_id,
muted=False,
status__in=["PASS", "FAIL"],
check_id="test_check_id",
)
)
rows = list(
ComplianceRequirementOverview.objects.filter(
scan_id=scan_id
).values_list("compliance_id", "requirement_id", "total_findings")
)
assert counted > 0
assert (
sum(
total
for compliance_id, requirement_id, total in rows
if (compliance_id, requirement_id)
== ("prowler_threatscore_aws", "1.1.1")
)
== counted
)
assert all(
total == 0
for compliance_id, requirement_id, total in rows
if (compliance_id, requirement_id) == ("prowler_threatscore_aws", "1.1.2")
)
assert all(
total == 0
for compliance_id, _, total in rows
if compliance_id == "other_framework"
)
def test_create_compliance_requirements_rows_across_regions_and_frameworks(
self,
tenants_fixture,
scans_fixture,
aws_provider,
):
from api.models import ComplianceRequirementOverview
tenant_id = str(tenants_fixture[0].id)
scan_id = str(scans_fixture[0].id)
check_status_by_region = {
"us-east-1": {"check_a": "FAIL", "check_b": "PASS"},
"eu-west-1": {"check_a": "PASS"},
}
template = {
"fw_one": {
"framework": "One",
"version": "1",
"requirements": {
"r1": {"description": "a", "checks": {"check_a": None}},
"r2": {
"description": "a+b",
"checks": {"check_a": None, "check_b": None},
},
},
},
"fw_two": {
"framework": "Two",
"version": "2",
"requirements": {
"m1": {"description": "manual", "checks": {}},
},
},
}
with (
patch(
"tasks.jobs.scan.PROWLER_COMPLIANCE_OVERVIEW_TEMPLATE"
) as mock_compliance_template,
patch(
"tasks.jobs.scan._aggregate_findings_by_region",
return_value=(check_status_by_region, {}),
),
):
mock_compliance_template.__getitem__.return_value = template
result = create_compliance_requirements(tenant_id, scan_id)
assert result["requirements_created"] == 6
with rls_transaction(tenant_id):
rows = set(
ComplianceRequirementOverview.objects.filter(
scan_id=scan_id
).values_list(
"compliance_id",
"requirement_id",
"region",
"requirement_status",
"passed_checks",
"failed_checks",
"total_checks",
)
)
assert rows == {
("fw_one", "r1", "us-east-1", "FAIL", 0, 1, 1),
("fw_one", "r1", "eu-west-1", "PASS", 1, 0, 1),
("fw_one", "r2", "us-east-1", "FAIL", 1, 1, 2),
("fw_one", "r2", "eu-west-1", "PASS", 1, 0, 2),
("fw_two", "m1", "us-east-1", "MANUAL", 0, 0, 0),
("fw_two", "m1", "eu-west-1", "MANUAL", 0, 0, 0),
}
def test_create_compliance_requirements_kubernetes_provider(
self,
@@ -4723,17 +4884,11 @@ class TestAggregateFindingsByRegion:
"""Test function returns correct data structure."""
tenant_id = str(uuid.uuid4())
scan_id = str(uuid.uuid4())
modeled_threatscore_compliance_id = "ProwlerThreatScore-1.0"
normalized_id = "prowlerthreatscore10"
# (check_id, status, resource_regions, compliance) tuples
finding_rows = [
(
"check1",
"FAIL",
["us-east-1"],
{modeled_threatscore_compliance_id: ["req1", "req2"]},
)
]
# (check_id, status, resource_regions) tuples
finding_rows = [("check1", "FAIL", ["us-east-1"])]
threatscore_by_check = {"check1": ["req1", "req2"]}
mock_queryset = MagicMock()
mock_queryset.values_list.return_value = mock_queryset
@@ -4747,13 +4902,16 @@ class TestAggregateFindingsByRegion:
check_status_by_region, findings_count_by_compliance = (
_aggregate_findings_by_region(
tenant_id, scan_id, modeled_threatscore_compliance_id
tenant_id,
scan_id,
normalized_id,
threatscore_by_check,
)
)
# Streaming query contract: column-scoped values_list + iterator
mock_queryset.values_list.assert_called_once_with(
"check_id", "status", "resource_regions", "compliance"
"check_id", "status", "resource_regions"
)
mock_queryset.iterator.assert_called_once()
@@ -4774,13 +4932,14 @@ class TestAggregateFindingsByRegion:
"""Test that FAIL status takes priority over other statuses."""
tenant_id = str(uuid.uuid4())
scan_id = str(uuid.uuid4())
modeled_threatscore_compliance_id = "ProwlerThreatScore-1.0"
normalized_id = "prowlerthreatscore10"
# Same check/region: PASS first, then FAIL — FAIL must win
finding_rows = [
("check1", "PASS", ["us-east-1"], {}),
("check1", "FAIL", ["us-east-1"], {}),
("check1", "PASS", ["us-east-1"]),
("check1", "FAIL", ["us-east-1"]),
]
threatscore_by_check = {}
mock_queryset = MagicMock()
mock_queryset.values_list.return_value = mock_queryset
@@ -4793,12 +4952,15 @@ class TestAggregateFindingsByRegion:
mock_findings_filter.return_value = mock_queryset
check_status_by_region, _ = _aggregate_findings_by_region(
tenant_id, scan_id, modeled_threatscore_compliance_id
tenant_id,
scan_id,
normalized_id,
threatscore_by_check,
)
# Streaming query contract: column-scoped values_list + iterator
mock_queryset.values_list.assert_called_once_with(
"check_id", "status", "resource_regions", "compliance"
"check_id", "status", "resource_regions"
)
mock_queryset.iterator.assert_called_once()
@@ -4813,8 +4975,9 @@ class TestAggregateFindingsByRegion:
"""Test that muted findings are filtered out (muted=False in query)."""
tenant_id = str(uuid.uuid4())
scan_id = str(uuid.uuid4())
modeled_threatscore_compliance_id = "ProwlerThreatScore-1.0"
normalized_id = "prowlerthreatscore10"
threatscore_by_check = {}
mock_queryset = MagicMock()
mock_queryset.values_list.return_value = mock_queryset
mock_queryset.iterator.return_value = []
@@ -4826,12 +4989,15 @@ class TestAggregateFindingsByRegion:
mock_findings_filter.return_value = mock_queryset
_aggregate_findings_by_region(
tenant_id, scan_id, modeled_threatscore_compliance_id
tenant_id,
scan_id,
normalized_id,
threatscore_by_check,
)
# Streaming query contract: column-scoped values_list + iterator
mock_queryset.values_list.assert_called_once_with(
"check_id", "status", "resource_regions", "compliance"
"check_id", "status", "resource_regions"
)
mock_queryset.iterator.assert_called_once()
@@ -4851,23 +5017,14 @@ class TestAggregateFindingsByRegion:
"""Test that ThreatScore compliance counts are processed correctly."""
tenant_id = str(uuid.uuid4())
scan_id = str(uuid.uuid4())
modeled_threatscore_compliance_id = "ProwlerThreatScore-1.0"
normalized_id = "prowlerthreatscore10"
# PASS and FAIL findings mapped to the same ThreatScore requirement
finding_rows = [
(
"check1",
"PASS",
["us-east-1"],
{modeled_threatscore_compliance_id: ["req1"]},
),
(
"check2",
"FAIL",
["us-east-1"],
{modeled_threatscore_compliance_id: ["req1"]},
),
("check1", "PASS", ["us-east-1"]),
("check2", "FAIL", ["us-east-1"]),
]
threatscore_by_check = {"check1": ["req1"], "check2": ["req1"]}
mock_queryset = MagicMock()
mock_queryset.values_list.return_value = mock_queryset
@@ -4880,19 +5037,19 @@ class TestAggregateFindingsByRegion:
mock_findings_filter.return_value = mock_queryset
_, findings_count_by_compliance = _aggregate_findings_by_region(
tenant_id, scan_id, modeled_threatscore_compliance_id
tenant_id,
scan_id,
normalized_id,
threatscore_by_check,
)
# Streaming query contract: column-scoped values_list + iterator
mock_queryset.values_list.assert_called_once_with(
"check_id", "status", "resource_regions", "compliance"
"check_id", "status", "resource_regions"
)
mock_queryset.iterator.assert_called_once()
# Verify compliance counts
normalized_id = re.sub(
r"[^a-z0-9]", "", modeled_threatscore_compliance_id.lower()
)
assert "us-east-1" in findings_count_by_compliance
assert normalized_id in findings_count_by_compliance["us-east-1"]
assert "req1" in findings_count_by_compliance["us-east-1"][normalized_id]
@@ -4909,13 +5066,14 @@ class TestAggregateFindingsByRegion:
"""Test aggregation across multiple regions."""
tenant_id = str(uuid.uuid4())
scan_id = str(uuid.uuid4())
modeled_threatscore_compliance_id = "ProwlerThreatScore-1.0"
normalized_id = "prowlerthreatscore10"
# One finding per region
finding_rows = [
("check1", "FAIL", ["us-east-1"], {}),
("check1", "PASS", ["us-west-2"], {}),
("check1", "FAIL", ["us-east-1"]),
("check1", "PASS", ["us-west-2"]),
]
threatscore_by_check = {}
mock_queryset = MagicMock()
mock_queryset.values_list.return_value = mock_queryset
@@ -4928,12 +5086,15 @@ class TestAggregateFindingsByRegion:
mock_findings_filter.return_value = mock_queryset
check_status_by_region, _ = _aggregate_findings_by_region(
tenant_id, scan_id, modeled_threatscore_compliance_id
tenant_id,
scan_id,
normalized_id,
threatscore_by_check,
)
# Streaming query contract: column-scoped values_list + iterator
mock_queryset.values_list.assert_called_once_with(
"check_id", "status", "resource_regions", "compliance"
"check_id", "status", "resource_regions"
)
mock_queryset.iterator.assert_called_once()
@@ -4951,16 +5112,10 @@ class TestAggregateFindingsByRegion:
"""A finding with multiple resource_regions is tallied in every region."""
tenant_id = str(uuid.uuid4())
scan_id = str(uuid.uuid4())
modeled_threatscore_compliance_id = "ProwlerThreatScore-1.0"
normalized_id = "prowlerthreatscore10"
finding_rows = [
(
"check1",
"FAIL",
["us-east-1", "eu-west-1"],
{modeled_threatscore_compliance_id: ["req1"]},
)
]
finding_rows = [("check1", "FAIL", ["us-east-1", "eu-west-1"])]
threatscore_by_check = {"check1": ["req1"]}
mock_queryset = MagicMock()
mock_queryset.values_list.return_value = mock_queryset
@@ -4974,19 +5129,19 @@ class TestAggregateFindingsByRegion:
check_status_by_region, findings_count_by_compliance = (
_aggregate_findings_by_region(
tenant_id, scan_id, modeled_threatscore_compliance_id
tenant_id,
scan_id,
normalized_id,
threatscore_by_check,
)
)
# Streaming query contract: column-scoped values_list + iterator
mock_queryset.values_list.assert_called_once_with(
"check_id", "status", "resource_regions", "compliance"
"check_id", "status", "resource_regions"
)
mock_queryset.iterator.assert_called_once()
normalized_id = re.sub(
r"[^a-z0-9]", "", modeled_threatscore_compliance_id.lower()
)
for region in ("us-east-1", "eu-west-1"):
assert check_status_by_region[region]["check1"] == "FAIL"
req_stats = findings_count_by_compliance[region][normalized_id]["req1"]
@@ -5000,12 +5155,13 @@ class TestAggregateFindingsByRegion:
"""A finding with no denormalized regions contributes nothing."""
tenant_id = str(uuid.uuid4())
scan_id = str(uuid.uuid4())
modeled_threatscore_compliance_id = "ProwlerThreatScore-1.0"
normalized_id = "prowlerthreatscore10"
finding_rows = [
("check1", "FAIL", [], {modeled_threatscore_compliance_id: ["req1"]}),
("check2", "PASS", None, {}),
("check1", "FAIL", []),
("check2", "PASS", None),
]
threatscore_by_check = {"check1": ["req1"]}
mock_queryset = MagicMock()
mock_queryset.values_list.return_value = mock_queryset
@@ -5019,13 +5175,16 @@ class TestAggregateFindingsByRegion:
check_status_by_region, findings_count_by_compliance = (
_aggregate_findings_by_region(
tenant_id, scan_id, modeled_threatscore_compliance_id
tenant_id,
scan_id,
normalized_id,
threatscore_by_check,
)
)
# Streaming query contract: column-scoped values_list + iterator
mock_queryset.values_list.assert_called_once_with(
"check_id", "status", "resource_regions", "compliance"
"check_id", "status", "resource_regions"
)
mock_queryset.iterator.assert_called_once()
@@ -5040,8 +5199,9 @@ class TestAggregateFindingsByRegion:
"""Test with no findings - should return empty dicts."""
tenant_id = str(uuid.uuid4())
scan_id = str(uuid.uuid4())
modeled_threatscore_compliance_id = "ProwlerThreatScore-1.0"
normalized_id = "prowlerthreatscore10"
threatscore_by_check = {}
mock_queryset = MagicMock()
mock_queryset.values_list.return_value = mock_queryset
mock_queryset.iterator.return_value = []
@@ -5054,13 +5214,16 @@ class TestAggregateFindingsByRegion:
check_status_by_region, findings_count_by_compliance = (
_aggregate_findings_by_region(
tenant_id, scan_id, modeled_threatscore_compliance_id
tenant_id,
scan_id,
normalized_id,
threatscore_by_check,
)
)
# Streaming query contract: column-scoped values_list + iterator
mock_queryset.values_list.assert_called_once_with(
"check_id", "status", "resource_regions", "compliance"
"check_id", "status", "resource_regions"
)
mock_queryset.iterator.assert_called_once()
Generated
+4 -4
View File
@@ -4835,8 +4835,8 @@ wheels = [
[[package]]
name = "prowler"
version = "5.41.0"
source = { git = "https://github.com/prowler-cloud/prowler.git?rev=master#f05a490cd74a2c0f11a5d66d8ce29d03fa5c64a2" }
version = "5.42.0"
source = { git = "https://github.com/prowler-cloud/prowler.git?rev=v5.42#4727da7ca71a87be629a888184705eb3f2e4324e" }
dependencies = [
{ name = "alibabacloud-actiontrail20200706" },
{ name = "alibabacloud-credentials" },
@@ -4938,7 +4938,7 @@ dependencies = [
[[package]]
name = "prowler-api"
version = "1.42.0"
version = "1.43.0"
source = { virtual = "." }
dependencies = [
{ name = "cartography" },
@@ -5038,7 +5038,7 @@ requires-dist = [
{ name = "matplotlib", specifier = "==3.10.8" },
{ name = "neo4j", specifier = "==6.1.0" },
{ name = "openai", specifier = "==1.109.1" },
{ name = "prowler", git = "https://github.com/prowler-cloud/prowler.git?rev=master" },
{ name = "prowler", git = "https://github.com/prowler-cloud/prowler.git?rev=v5.42" },
{ name = "psycopg2-binary", specifier = "==2.9.9" },
{ name = "pytest-celery", extras = ["redis"], specifier = "==1.3.0" },
{ name = "reportlab", specifier = "==4.4.10" },
@@ -2,6 +2,8 @@
title: 'Basic Usage'
---
import { VersionBadge } from "/snippets/version-badge.mdx"
## Running Prowler
Running Prowler requires specifying the provider (e.g. `aws`, `gcp`, `azure`, `kubernetes`, `m365`, `github`, `iac` or `mongodbatlas`):
@@ -91,6 +93,18 @@ By default, `prowler` will scan all AWS regions.
</Note>
See more details about AWS Authentication in the [Authentication Section](/user-guide/providers/aws/authentication) section.
- **AWS Retrier and Timeout Configuration**
<VersionBadge version="5.42.0" />
Tune the Boto3 standard retrier and the endpoint timeouts when AWS throttles the scan or when some endpoints are unreachable from the network Prowler runs in:
```console
prowler aws --aws-retries-max-attempts 5 --aws-connect-timeout 5 --aws-read-timeout 30
```
See the [Boto3 configuration](/user-guide/providers/aws/boto3-configuration) page for defaults and environment variables.
## Azure
Azure requires specifying the auth method:
@@ -128,8 +128,8 @@ To update the environment file:
Edit the `.env` file and change version values:
```env
PROWLER_UI_VERSION="5.40.0"
PROWLER_API_VERSION="5.40.0"
PROWLER_UI_VERSION="5.41.0"
PROWLER_API_VERSION="5.41.0"
```
<Note>
@@ -1,14 +1,39 @@
---
title: "Boto3 Retrier Configuration in Prowler"
title: "Boto3 Retrier and Timeout Configuration in Prowler"
---
import { VersionBadge } from "/snippets/version-badge.mdx"
Prowler's AWS Provider leverages Boto3's [Standard](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/retries.html) retry mode to automatically retry client calls to AWS services when encountering errors or exceptions.
## Timeout Configuration
<VersionBadge version="5.42.0" />
Every AWS API call is bounded by two timeouts:
- Connect timeout: seconds to wait to establish a connection (TCP, proxy tunnel and TLS handshake) to the AWS endpoint. Prowler's default is 10 seconds, configurable via `--aws-connect-timeout 5`.
- Read timeout: seconds to wait for a response once connected. Prowler's default is 60 seconds, configurable via `--aws-read-timeout 30`.
Both timeouts can also be set through environment variables, which is the way to tune them in Prowler Cloud and other deployments without a CLI:
```console
export PROWLER_AWS_BOTO3_CONNECT_TIMEOUT=5
export PROWLER_AWS_BOTO3_READ_TIMEOUT=30
```
CLI flags take precedence over the environment variables. Prowler sets both timeouts explicitly, so `AWS_DEFAULTS_MODE` and a `connect_timeout` in `~/.aws/config` are ignored; use the flag or the environment variable instead.
<Note>
Boto3 defaults both timeouts to 60 seconds. In networks with restricted egress (for example VPC endpoints for a subset of services, GovCloud or private deployments), every AWS service without a reachable endpoint used to cost up to 4 attempts × 60 seconds (the first call plus the 3 retries) for each region. Prowler lowers the connect timeout to 10 seconds so unreachable endpoints fail fast; lower it further together with `--aws-retries-max-attempts 0`, which disables retries and leaves a single attempt per call, if a scan still spends most of its time waiting on unreachable services.
</Note>
## Retry Behavior Overview
Boto3's Standard retry mode includes the following mechanisms:
- Maximum Retry Attempts: Default value set to 3, configurable via the `--aws-retries-max-attempts 5` argument.
- Maximum Retry Attempts: Default value set to 3, configurable via the `--aws-retries-max-attempts 5` argument. `0` disables retries.
- Expanded Error Handling: Retries occur for a comprehensive set of errors.
@@ -21,10 +21,28 @@ When scanning the China (`aws-cn`), European Sovereign Cloud (`aws-eusc`) or Gov
- Specify the regions to audit within that partition using the `-f/--region` flag.
- Declare the partition with the `PROWLER_AWS_PARTITION` environment variable, set to `aws`, `aws-cn`, `aws-eusc` or `aws-us-gov`.
<Note>
Refer to: https://boto3.amazonaws.com/v1/documentation/api/latest/guide/credentials.html#configuring-credentials for more information about the AWS credential configuration.
</Note>
### Declaring the Partition
`PROWLER_AWS_PARTITION` tells Prowler which partition the scan runs against, without relying on a region being configured:
```bash
export PROWLER_AWS_PARTITION="aws-us-gov"
```
It matters most where nothing else says. Resolving an identity means calling STS before anything is known about the credentials, and with no region configured Prowler would otherwise start from the commercial endpoints. Declaring the partition makes that first call go to the right place, which is the difference between a scan that starts and one that fails on an endpoint the credentials cannot use.
A region configured for the session still wins when it belongs to the declared partition, so a deployment in `us-gov-west-1` is not sent to `us-gov-east-1`. A region belonging to a different partition is ignored, since a partition that has been declared explicitly is the more deliberate statement of the two.
<Note>
Set it wherever the scan runs. For deployments that scan from containers, that means the environment of the containers doing the scanning, not only the one accepting the request.
</Note>
### Scanning Specific Regions
To scan a particular AWS region with Prowler, use:
@@ -96,6 +96,29 @@ Install Trivy using one of the following methods:
For additional installation methods, see the [Trivy installation guide](https://trivy.dev/latest/getting-started/installation/).
### Vulnerability Database Cache
<VersionBadge version="5.42.0" />
Trivy keeps its vulnerability database in a cache directory. By default Prowler gives it a temporary one and removes it when the scan ends, so the database is downloaded again for every scan.
Set `TRIVY_CACHE_DIR` to a directory that persists and the database is downloaded once and reused:
```bash
export TRIVY_CACHE_DIR="$HOME/.cache/trivy"
prowler image --image <image>
```
Prowler never deletes a directory you supply. Trivy still creates and updates its cache and database files inside it.
<Note>
A host with no internet access needs a pre-populated vulnerability database in a persistent directory, with `TRIVY_CACHE_DIR` pointing at it. Populate the directory on a machine that does have access and copy it across.
Trivy tries to refresh the database when it considers it stale, and that download fails without network access. Set `TRIVY_SKIP_DB_UPDATE=true` (and `TRIVY_SKIP_JAVA_DB_UPDATE=true` if Java scanning is enabled) so it uses the supplied database as is.
The database ages. A scan run against an old one reports only the vulnerabilities known when it was built, and nothing in the output says so, so keep track of when it was last refreshed.
</Note>
### Supported Scanners
+8
View File
@@ -4,6 +4,14 @@ All notable changes to the **Prowler MCP Server** are documented in this file.
<!-- changelog: release notes start -->
## [0.12.1] (Prowler v5.42.0)
### 🔐 Security
- `libuuid` upgraded to 2.41.6-r1 in the container image, patching CVE-2026-53612, CVE-2026-53613, CVE-2026-53614, CVE-2026-76642, CVE-2026-78408 and CVE-2026-78410 [(#12780)](https://github.com/prowler-cloud/prowler/pull/12780)
---
## [0.12.0] (Prowler v5.41.0)
### 🚀 Added
+4 -1
View File
@@ -32,6 +32,8 @@ LABEL maintainer="https://github.com/prowler-cloud"
# High CVEs fixed in Alpine 3.23 but not yet in the pinned base image:
# sqlite-libs 3.53.4-r0 CVE-2026-11822, CVE-2026-11824 (image ships 3.51.2-r0)
# libcrypto3/libssl3 3.5.8-r0 CVE-2026-14456 (image ships 3.5.7-r0)
# libuuid 2.41.6-r1 CVE-2026-53612, -53613, -53614, -76642, -78408, -78410
# (image ships 2.41.4-r0; -78408 is the one that needs -r1 rather than -r0)
# The base image pins python 3.13.14, which has not been rebuilt since those
# packages were published, so the upgrade is taken here rather than by moving
# the pin -- the newest published python:3.13-alpine3.23 carries the same
@@ -43,7 +45,8 @@ LABEL maintainer="https://github.com/prowler-cloud"
RUN apk add --no-cache --upgrade \
"sqlite-libs>=3.53.4-r0" \
"libcrypto3>=3.5.8-r0" \
"libssl3>=3.5.8-r0"
"libssl3>=3.5.8-r0" \
"libuuid>=2.41.6-r1"
# Create non-root user for security
# Using specific UID/GID for consistency across environments
+27
View File
@@ -4,6 +4,33 @@ All notable changes to the **Prowler SDK** are documented in this file.
<!-- changelog: release notes start -->
## [5.42.0] (Prowler v5.42.0)
### 🚀 Added
- AWS ISO partitions (`aws-iso`, `aws-iso-b`, `aws-iso-e` and `aws-iso-f`) to the AWS service region matrix, generated from the endpoints data bundled with botocore [(#12759)](https://github.com/prowler-cloud/prowler/pull/12759)
- `--aws-connect-timeout` and `--aws-read-timeout` CLI flags, plus `PROWLER_AWS_BOTO3_CONNECT_TIMEOUT` and `PROWLER_AWS_BOTO3_READ_TIMEOUT` environment variables, to bound how long each AWS API call waits for an endpoint [(#12774)](https://github.com/prowler-cloud/prowler/pull/12774)
### 🔄 Changed
- AWS provider default Boto3 connect timeout lowered from 60 to 10 seconds, so scans in restricted-egress networks (VPC endpoints for a subset of services, GovCloud, private deployments) no longer spend 4 minutes per region on every service whose endpoint is unreachable [(#12774)](https://github.com/prowler-cloud/prowler/pull/12774)
### 🐞 Fixed
- Duplicate requirement ids, checks listed twice in a requirement and references to non-existent checks across compliance frameworks, now guarded by a catalog integrity test [(#12717)](https://github.com/prowler-cloud/prowler/pull/12717)
- Duplicate requirement `3.2.1` in ProwlerThreatScore for Azure (SQL auditing retention is now `3.2.4`) and doubled check id in requirement `1.2.1` of ProwlerThreatScore for GCP [(#12717)](https://github.com/prowler-cloud/prowler/pull/12717)
- Jira connection checks no longer log an error when a single project has no issue types visible to the integration user (typically a missing "create issue" permission on that project), a case the caller already treats as non-fatal [(#12742)](https://github.com/prowler-cloud/prowler/pull/12742)
- `Jira.test_connection()` now fetches each project's issue types concurrently instead of one request at a time, so accounts with many Jira projects no longer take tens of seconds (unbounded, scaling with the project count) to verify the connection [(#12742)](https://github.com/prowler-cloud/prowler/pull/12742)
- `AwsProvider.get_available_aws_service_regions()` now returns an empty set for an unknown service or partition instead of raising `KeyError`, so a service unavailable in the audited partition is skipped [(#12759)](https://github.com/prowler-cloud/prowler/pull/12759)
- `AwsProvider.generate_regional_clients()` now returns an empty dict instead of `None` when the regional clients cannot be built, a failure that surfaced later as `AttributeError: 'NoneType' object has no attribute 'values'` [(#12759)](https://github.com/prowler-cloud/prowler/pull/12759)
- `AwsProvider.get_global_region()` now returns a real region for each ISO partition instead of the `aws-iso-global` pseudo endpoint, which collapsed the four partitions into one answer [(#12759)](https://github.com/prowler-cloud/prowler/pull/12759)
- Bootstrap STS calls now use the session region when `PROWLER_AWS_PARTITION` is set and the region belongs to that partition, instead of always going to the partition's global STS region, which a deployment reached only through its own region's VPC endpoints cannot route to [(#12764)](https://github.com/prowler-cloud/prowler/pull/12764)
- The Image provider now uses the directory named by `TRIVY_CACHE_DIR` when one is set, instead of a fresh temporary directory it deletes afterwards, so a deployment can supply a vulnerability database it already holds and one with network access stops re-downloading the database for every image it scans [(#12773)](https://github.com/prowler-cloud/prowler/pull/12773)
- `--aws-retries-max-attempts 0` now disables Boto3 retries instead of being silently ignored in favour of the default of 3 [(#12774)](https://github.com/prowler-cloud/prowler/pull/12774)
- `rolesanywhere_profile_restricts_session_permissions`, `iam_role_service_trust_restricts_source_to_account` and `codebuild_project_uses_allowed_github_organizations` crashing with `TypeError` when `iam:ListRoles` is denied [(#12785)](https://github.com/prowler-cloud/prowler/pull/12785)
---
## [5.41.0] (Prowler v5.41.0)
### 🚀 Added
@@ -277,7 +277,6 @@
}
],
"Checks": [
"guardduty_is_enabled",
"guardduty_is_enabled"
],
"ConfigRequirements": [
@@ -497,7 +496,7 @@
"Checks": []
},
{
"Id": "Create Cost Anomaly Detection monitors to alert spending anomalies",
"Id": "Create Cost Anomaly Detection monitors to alert spending anomalies (Prod)",
"Description": "Develop monitoring systems for detecting cost anomalies and generating alerts for irregular spending patterns.",
"Attributes": [
{
@@ -510,7 +509,7 @@
"Checks": []
},
{
"Id": "Create Cost Anomaly Detection monitors to alert spending anomalies",
"Id": "Create Cost Anomaly Detection monitors to alert spending anomalies (QA)",
"Description": "Establish monitoring systems for cost anomaly detection to promptly notify about unusual spending patterns.",
"Attributes": [
{
@@ -618,7 +617,7 @@
]
},
{
"Id": "Export scan results as metrics in centralized collector",
"Id": "Export scan results as metrics in centralized collector (EC2)",
"Description": "Export scan results as metrics to a centralized collector.",
"Attributes": [
{
@@ -667,7 +666,7 @@
]
},
{
"Id": "Export scan results as metrics in centralized collector",
"Id": "Export scan results as metrics in centralized collector (ECR)",
"Description": "Generate metric data from scan results and store it in a centralized collector.",
"Attributes": [
{
@@ -1189,7 +1188,7 @@
]
},
{
"Id": "Export metrics in centralized collector",
"Id": "Export metrics in centralized collector (Shield Advanced)",
"Description": "Exporting metrics to a centralized collector for data aggregation and analysis.",
"Attributes": [
{
@@ -1367,7 +1366,7 @@
"Checks": []
},
{
"Id": "Export metrics in centralized collector",
"Id": "Export metrics in centralized collector (WAFv2)",
"Description": "Exporting metrics to a centralized collector for comprehensive data aggregation.",
"Attributes": [
{
@@ -334,7 +334,6 @@
"iam_role_cross_service_confused_deputy_prevention",
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_root_hardware_mfa_enabled",
"iam_user_hardware_mfa_enabled",
"iam_user_mfa_enabled_console_access",
"iam_administrator_access_with_mfa"
@@ -472,11 +472,9 @@
"emr_cluster_publicly_accesible",
"glacier_vaults_policy_public_access",
"awslambda_function_not_publicly_accessible",
"awslambda_function_not_publicly_accessible",
"rds_instance_no_public_access",
"rds_snapshots_public_access",
"kms_key_not_publicly_accessible",
"opensearch_service_domains_not_publicly_accessible",
"redshift_cluster_public_access",
"s3_account_level_public_access_blocks",
"s3_bucket_public_access",
@@ -493,7 +491,6 @@
"eks_cluster_not_publicly_accessible",
"elb_internet_facing",
"elbv2_internet_facing",
"s3_account_level_public_access_blocks",
"sns_topics_not_publicly_accessible",
"sqs_queues_not_publicly_accessible",
"ssm_documents_set_as_public",
@@ -553,7 +550,6 @@
"awslambda_function_invoke_api_operations_cloudtrail_logging_enabled",
"cloudfront_distributions_logging_enabled",
"cloudtrail_bedrock_logging_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"cloudtrail_logs_s3_bucket_access_logging_enabled",
"directoryservice_directory_log_forwarding_enabled",
"eks_control_plane_logging_all_types_enabled",
@@ -771,7 +767,6 @@
"ec2_securitygroup_not_used",
"ec2_securitygroup_with_many_ingress_egress_rules",
"elbv2_desync_mitigation_mode",
"elbv2_desync_mitigation_mode",
"route53_domains_privacy_protection_enabled",
"route53_domains_transferlock_enabled",
"shield_advanced_protection_in_associated_elastic_ips",
+3 -17
View File
@@ -268,7 +268,6 @@
"iam_role_administratoraccess_policy",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_unattached_policy_no_administrative_privileges",
"iam_role_administratoraccess_policy",
"iam_user_administrator_access_policy",
"organizations_delegated_administrators",
"cloudwatch_changes_to_network_route_tables_alarm_configured",
@@ -1936,9 +1935,7 @@
"cloudwatch_changes_to_network_acls_alarm_configured",
"cloudwatch_changes_to_network_gateways_alarm_configured",
"cloudwatch_changes_to_network_route_tables_alarm_configured",
"cloudwatch_changes_to_vpcs_alarm_configured",
"cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled",
"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled"
"cloudwatch_changes_to_vpcs_alarm_configured"
]
},
{
@@ -3866,7 +3863,6 @@
}
],
"Checks": [
"acm_certificates_transparency_logs_enabled",
"acm_certificates_transparency_logs_enabled",
"apigateway_restapi_logging_enabled",
"apigatewayv2_api_access_logging_enabled",
@@ -3945,7 +3941,6 @@
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_user_hardware_mfa_enabled",
"iam_user_mfa_enabled_console_access",
"s3_bucket_no_mfa_delete"
]
},
@@ -5219,8 +5214,6 @@
"iam_customer_unattached_policy_no_administrative_privileges",
"iam_group_administrator_access_policy",
"iam_inline_policy_no_administrative_privileges",
"iam_policy_cloudshell_admin_not_attached",
"iam_role_administratoraccess_policy",
"iam_user_administrator_access_policy",
"organizations_delegated_administrators",
"rds_cluster_default_admin",
@@ -5291,8 +5284,6 @@
"iam_customer_unattached_policy_no_administrative_privileges",
"iam_group_administrator_access_policy",
"iam_inline_policy_no_administrative_privileges",
"iam_policy_cloudshell_admin_not_attached",
"iam_role_administratoraccess_policy",
"iam_user_administrator_access_policy",
"organizations_delegated_administrators",
"rds_cluster_default_admin",
@@ -6357,8 +6348,7 @@
],
"Checks": [
"cognito_user_pool_blocks_compromised_credentials_sign_in_attempts",
"cognito_user_pool_blocks_potential_malicious_sign_in_attempts",
"cognito_user_pool_blocks_compromised_credentials_sign_in_attempts"
"cognito_user_pool_blocks_potential_malicious_sign_in_attempts"
]
},
{
@@ -6670,7 +6660,6 @@
"sagemaker_training_jobs_intercontainer_encryption_enabled",
"sagemaker_training_jobs_volume_and_output_encryption_enabled",
"sns_topics_kms_encryption_at_rest_enabled",
"sqs_queues_server_side_encryption_enabled",
"storagegateway_fileshare_encryption_enabled",
"transfer_server_in_transit_encryption_enabled",
"workspaces_volume_encryption_enabled"
@@ -7696,13 +7685,11 @@
"dynamodb_accelerator_cluster_in_transit_encryption_enabled",
"transfer_server_in_transit_encryption_enabled",
"dms_endpoint_redis_in_transit_encryption_enabled",
"dynamodb_accelerator_cluster_in_transit_encryption_enabled",
"ec2_transitgateway_auto_accept_vpc_attachments",
"elasticache_redis_cluster_in_transit_encryption_enabled",
"kafka_cluster_in_transit_encryption_enabled",
"kafka_connector_in_transit_encryption_enabled",
"redshift_cluster_in_transit_encryption_enabled",
"transfer_server_in_transit_encryption_enabled"
"redshift_cluster_in_transit_encryption_enabled"
]
},
{
@@ -10967,7 +10954,6 @@
"kms_cmk_not_multi_region",
"cloudfront_distributions_geo_restrictions_enabled",
"cloudtrail_multi_region_enabled_logging_management_events",
"kms_cmk_not_multi_region",
"organizations_scp_check_deny_regions",
"s3_multi_region_access_point_public_access_block"
]
+1 -1
View File
@@ -204,7 +204,7 @@
]
},
{
"Id": "1.1",
"Id": "1.10",
"Description": "Do not create access keys during initial setup for IAM users with a console password",
"Checks": [
"iam_user_no_setup_initial_access_key"
+1 -21
View File
@@ -58,14 +58,12 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_kms_encryption_enabled",
"cloudtrail_log_file_validation_enabled",
"codebuild_project_user_controlled_buildspec",
"dynamodb_accelerator_cluster_encryption_enabled",
"dynamodb_tables_kms_cmk_encryption_enabled",
"dynamodb_tables_pitr_enabled",
"dynamodb_tables_pitr_enabled",
"ec2_ebs_volume_encryption",
"ec2_ebs_public_snapshot",
"ec2_ebs_default_encryption",
@@ -85,7 +83,6 @@
"iam_password_policy_minimum_length_14",
"iam_password_policy_lowercase",
"iam_password_policy_number",
"iam_password_policy_number",
"iam_password_policy_symbol",
"iam_password_policy_uppercase",
"iam_no_custom_policy_permissive_role_assumption",
@@ -97,23 +94,18 @@
"iam_no_root_access_key",
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"kms_cmk_rotation_enabled",
"awslambda_function_not_publicly_accessible",
"awslambda_function_not_publicly_accessible",
"cloudwatch_log_group_kms_encryption_enabled",
"cloudwatch_log_group_kms_encryption_enabled",
"rds_instance_enhanced_monitoring_enabled",
"rds_instance_backup_enabled",
"rds_instance_deletion_protection",
"rds_instance_storage_encrypted",
"rds_instance_backup_enabled",
"rds_instance_integration_cloudwatch_logs",
"rds_instance_multi_az",
"rds_instance_no_public_access",
"rds_instance_storage_encrypted",
"rds_snapshots_public_access",
"redshift_cluster_automated_snapshot",
"redshift_cluster_audit_logging",
@@ -125,7 +117,6 @@
"s3_bucket_policy_public_write_access",
"s3_bucket_object_versioning",
"s3_account_level_public_access_blocks",
"s3_bucket_public_access",
"sagemaker_training_jobs_volume_and_output_encryption_enabled",
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"sagemaker_notebook_instance_encryption_enabled",
@@ -222,7 +213,6 @@
"iam_password_policy_minimum_length_14",
"iam_password_policy_lowercase",
"iam_password_policy_number",
"iam_password_policy_number",
"iam_password_policy_symbol",
"iam_password_policy_uppercase"
]
@@ -246,7 +236,6 @@
"ec2_ebs_default_encryption",
"opensearch_service_domains_encryption_at_rest_enabled",
"rds_instance_storage_encrypted",
"rds_instance_storage_encrypted",
"redshift_cluster_audit_logging",
"s3_bucket_default_encryption",
"sagemaker_training_jobs_volume_and_output_encryption_enabled",
@@ -273,7 +262,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled",
"cloudwatch_log_group_kms_encryption_enabled",
"dynamodb_tables_kms_cmk_encryption_enabled",
@@ -289,18 +277,14 @@
"opensearch_service_domains_cloudwatch_logging_enabled",
"opensearch_service_domains_node_to_node_encryption_enabled",
"awslambda_function_not_publicly_accessible",
"awslambda_function_not_publicly_accessible",
"cloudwatch_log_group_kms_encryption_enabled",
"rds_instance_storage_encrypted",
"rds_instance_integration_cloudwatch_logs",
"rds_instance_no_public_access",
"rds_snapshots_public_access",
"rds_snapshots_public_access",
"redshift_cluster_audit_logging",
"redshift_cluster_public_access",
"s3_bucket_default_encryption",
"s3_bucket_secure_transport_policy",
"redshift_cluster_public_access",
"s3_bucket_server_access_logging_enabled",
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
@@ -349,7 +333,6 @@
"elbv2_deletion_protection",
"rds_instance_backup_enabled",
"rds_instance_deletion_protection",
"rds_instance_backup_enabled",
"redshift_cluster_automated_snapshot",
"s3_bucket_object_versioning"
]
@@ -409,11 +392,9 @@
}
],
"Checks": [
"dynamodb_tables_pitr_enabled",
"dynamodb_tables_pitr_enabled",
"efs_have_backup_enabled",
"rds_instance_backup_enabled",
"rds_instance_backup_enabled",
"redshift_cluster_automated_snapshot",
"s3_bucket_object_versioning"
]
@@ -432,8 +413,7 @@
"Checks": [
"iam_user_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_user_mfa_enabled_console_access",
"iam_user_hardware_mfa_enabled"
"iam_user_mfa_enabled_console_access"
]
},
{
@@ -34,9 +34,7 @@
"config_recorder_all_regions_enabled",
"ec2_instance_managed_by_ssm",
"ec2_instance_older_than_specific_days",
"ssm_managed_compliant_patching",
"ssm_managed_instance_compliance_association_compliant",
"ssm_managed_instance_compliance_patch_compliant"
"ssm_managed_compliant_patching"
],
"ConfigRequirements": [
{
@@ -63,7 +61,7 @@
"autoscaling_group_multiple_instance_types",
"autoscaling_group_capacity_rebalance_enabled",
"dynamodb_tables_pitr_enabled",
"dynamodb_tables_deletion_protection_enabled",
"dynamodb_table_deletion_protection_enabled",
"ec2_instance_imdsv2_enabled",
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_default_restrict_traffic",
@@ -73,13 +71,12 @@
"eks_cluster_private_nodes_enabled",
"eks_cluster_uses_a_supported_version",
"elb_cross_zone_load_balancing_enabled",
"elbv2_alb_multi_az_scheme",
"elbv2_is_in_multiple_az",
"elbv2_waf_acl_attached",
"rds_instance_multi_az",
"rds_cluster_multi_az",
"vpc_subnet_auto_assign_public_ip_disabled",
"vpc_default_security_group_restricts_traffic",
"vpc_peering_connection_routing_tables_with_least_privilege",
"vpc_subnet_no_public_ip_by_default",
"vpc_peering_routing_tables_with_least_privilege",
"ec2_confidential_workload_host_imdsv2_not_enforced"
]
},
@@ -143,11 +140,9 @@
"guardduty_centrally_managed",
"guardduty_ec2_malware_protection_enabled",
"guardduty_eks_audit_log_enabled",
"guardduty_eks_protection_enabled",
"guardduty_eks_runtime_monitoring_enabled",
"guardduty_is_enabled",
"guardduty_lambda_protection_enabled",
"guardduty_malware_protection_enabled",
"guardduty_no_high_severity_findings",
"guardduty_rds_protection_enabled",
"guardduty_s3_protection_enabled",
@@ -193,7 +188,7 @@
"cloudwatch_log_group_kms_encryption_enabled",
"cloudwatch_log_group_retention_policy_specific_days_enabled",
"ecs_cluster_container_insights_enabled",
"eks_cluster_control_plane_audit_logging_enabled",
"eks_control_plane_logging_all_types_enabled",
"elb_logging_enabled",
"elbv2_logging_enabled",
"inspector2_is_enabled",
@@ -227,8 +222,7 @@
"organizations_delegated_administrators",
"organizations_scp_check_deny_regions",
"organizations_tags_policies_enabled_and_attached",
"resourceexplorer_indexes_found",
"ssm_managed_instance_compliance_association_compliant",
"resourceexplorer2_indexes_found",
"trustedadvisor_premium_support_plan_subscribed"
],
"ConfigRequirements": [
@@ -257,15 +251,12 @@
"backup_vaults_exist",
"backup_vaults_encrypted",
"backup_recovery_point_encrypted",
"backup_recovery_point_manual_deletion_disabled",
"backup_recovery_point_minimum_retention_days",
"dlm_ebs_snapshot_lifecycle_policy_exists",
"dynamodb_tables_pitr_enabled",
"dynamodb_tables_deletion_protection_enabled",
"dynamodb_table_deletion_protection_enabled",
"efs_have_backup_enabled",
"fsx_file_system_copy_tags_to_backups",
"fsx_file_system_copy_tags_to_backups_enabled",
"rds_instance_backup_enabled",
"rds_instance_backup_retention_policy",
"rds_instance_deletion_protection",
"rds_cluster_deletion_protection",
"rds_snapshots_encrypted",
@@ -287,33 +278,28 @@
"acm_certificates_expiration_check",
"apigateway_restapi_cache_encrypted",
"cloudtrail_kms_encryption_enabled",
"dax_cluster_encryption_enabled",
"dynamodb_table_encryption_enabled",
"dynamodb_table_encryption_uses_cmks",
"ebs_volume_encryption_enabled",
"dynamodb_accelerator_cluster_encryption_enabled",
"dynamodb_tables_kms_cmk_encryption_enabled",
"ec2_ebs_volume_encryption",
"ec2_ebs_default_encryption",
"ec2_instance_ebs_optimized",
"efs_encryption_at_rest_enabled",
"eks_cluster_envelope_encryption_enabled",
"elasticache_redis_cluster_encryption_at_rest_enabled",
"elasticache_redis_cluster_encryption_at_transit_enabled",
"eks_cluster_kms_cmk_encryption_in_secrets_enabled",
"elasticache_redis_cluster_rest_encryption_enabled",
"elasticache_redis_cluster_in_transit_encryption_enabled",
"elbv2_ssl_listeners",
"fsx_file_system_encryption_at_rest_enabled",
"kinesis_stream_encrypted_at_rest",
"kms_cmk_rotation_enabled",
"kms_cmk_not_scheduled_for_deletion",
"kms_cmk_not_deleted_unintentionally",
"kms_key_not_publicly_accessible",
"rds_instance_storage_encrypted",
"rds_instance_storage_encrypted_with_cmk",
"rds_cluster_storage_encrypted",
"redshift_cluster_encryption_at_rest",
"redshift_cluster_encryption_in_transit",
"s3_bucket_server_side_encryption_enabled",
"redshift_cluster_encrypted_at_rest",
"redshift_cluster_in_transit_encryption_enabled",
"s3_bucket_default_encryption",
"s3_bucket_secure_transport_policy",
"sagemaker_notebook_instance_encryption_enabled",
"sns_topics_kms_encryption_at_rest_enabled",
"sqs_queue_server_side_encryption_enabled",
"sqs_queues_server_side_encryption_enabled",
"kms_key_enclave_attestation_not_enforced"
]
},
@@ -332,7 +318,7 @@
"ecr_registry_scan_images_on_push_enabled",
"ecr_repositories_lifecycle_policy_enabled",
"ecr_repositories_not_publicly_accessible",
"ecr_repositories_scan_on_push_enabled",
"ecr_repositories_scan_images_on_push_enabled",
"ecr_repositories_scan_vulnerabilities_in_latest_image",
"ecr_repositories_tag_immutability",
"inspector2_active_findings_exist",
@@ -382,7 +368,7 @@
"cloudwatch_log_group_retention_policy_specific_days_enabled",
"config_recorder_all_regions_enabled",
"inspector2_is_enabled",
"resourceexplorer_indexes_found"
"resourceexplorer2_indexes_found"
],
"ConfigRequirements": [
{
@@ -21,7 +21,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_log_file_validation_enabled",
"cloudwatch_changes_to_network_acls_alarm_configured",
"opensearch_service_domains_cloudwatch_logging_enabled",
@@ -127,8 +126,7 @@
"securityhub_enabled",
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port"
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22"
],
"ConfigRequirements": [
{
@@ -161,7 +159,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_log_file_validation_enabled",
"elbv2_logging_enabled",
"rds_instance_integration_cloudwatch_logs",
@@ -226,7 +223,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudwatch_changes_to_network_acls_alarm_configured",
"ec2_instance_imdsv2_enabled",
"elbv2_waf_acl_attached",
@@ -276,13 +272,11 @@
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
"s3_account_level_public_access_blocks",
"s3_bucket_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"ssm_managed_compliant_patching",
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port"
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22"
]
},
{
@@ -299,7 +293,6 @@
"Checks": [
"ec2_instance_managed_by_ssm",
"guardduty_is_enabled",
"ssm_managed_compliant_patching",
"ssm_managed_compliant_patching"
],
"ConfigRequirements": [
@@ -323,11 +316,9 @@
}
],
"Checks": [
"dynamodb_tables_pitr_enabled",
"dynamodb_tables_pitr_enabled",
"efs_have_backup_enabled",
"rds_instance_backup_enabled",
"rds_instance_backup_enabled",
"redshift_cluster_automated_snapshot",
"s3_bucket_object_versioning"
]
@@ -344,13 +335,11 @@
}
],
"Checks": [
"dynamodb_tables_pitr_enabled",
"dynamodb_tables_pitr_enabled",
"efs_have_backup_enabled",
"elbv2_deletion_protection",
"rds_instance_backup_enabled",
"rds_instance_multi_az",
"rds_instance_backup_enabled",
"redshift_cluster_automated_snapshot",
"s3_bucket_object_versioning"
]
@@ -371,7 +360,6 @@
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_no_root_access_key",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access"
]
},
@@ -482,12 +470,10 @@
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
"s3_account_level_public_access_blocks",
"s3_bucket_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port"
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22"
]
},
{
@@ -29,7 +29,6 @@
"iam_no_root_access_key",
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_role_access_not_stale_to_bedrock",
"iam_user_access_not_stale_to_bedrock",
"iam_user_access_not_stale_to_sagemaker",
@@ -68,7 +67,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"cloudwatch_changes_to_network_acls_alarm_configured",
"cloudwatch_changes_to_network_gateways_alarm_configured",
@@ -149,7 +147,6 @@
"iam_no_root_access_key",
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_role_access_not_stale_to_bedrock",
"iam_user_access_not_stale_to_bedrock",
"iam_user_access_not_stale_to_sagemaker",
@@ -174,7 +171,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"opensearch_service_domains_cloudwatch_logging_enabled",
"guardduty_is_enabled",
@@ -220,7 +216,6 @@
"iam_no_root_access_key",
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_role_access_not_stale_to_bedrock",
"iam_user_access_not_stale_to_bedrock",
"iam_user_access_not_stale_to_sagemaker",
@@ -312,7 +307,6 @@
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
"s3_account_level_public_access_blocks",
"s3_bucket_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"ec2_confidential_workload_host_imdsv2_not_enforced",
"kms_key_enclave_attestation_not_enforced"
@@ -345,7 +339,6 @@
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port",
"ec2_confidential_workload_host_public_ip"
]
},
@@ -426,7 +419,6 @@
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
"s3_account_level_public_access_blocks",
"s3_bucket_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"ec2_confidential_workload_host_imdsv2_not_enforced",
"kms_key_enclave_attestation_bypassable_path"
@@ -457,13 +449,11 @@
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
"s3_account_level_public_access_blocks",
"s3_bucket_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"securityhub_enabled",
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port"
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22"
],
"ConfigRequirements": [
{
@@ -521,10 +511,8 @@
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
"s3_account_level_public_access_blocks",
"s3_bucket_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
"ec2_networkacl_allow_ingress_any_port"
]
},
@@ -545,7 +533,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_bedrock_logging_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"elbv2_logging_enabled",
@@ -572,7 +559,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"elbv2_logging_enabled",
"elb_logging_enabled",
@@ -599,7 +585,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"cloudwatch_changes_to_network_acls_alarm_configured",
"cloudwatch_changes_to_network_gateways_alarm_configured",
@@ -723,7 +708,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_bedrock_logging_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"elbv2_logging_enabled",
@@ -750,7 +734,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudwatch_changes_to_network_acls_alarm_configured",
"cloudwatch_changes_to_network_gateways_alarm_configured",
"cloudwatch_changes_to_network_route_tables_alarm_configured",
@@ -804,13 +787,11 @@
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
"s3_account_level_public_access_blocks",
"s3_bucket_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"ssm_managed_compliant_patching",
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port"
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22"
]
},
{
@@ -863,7 +844,6 @@
"Checks": [
"ec2_instance_managed_by_ssm",
"guardduty_is_enabled",
"ssm_managed_compliant_patching",
"ssm_managed_compliant_patching"
],
"ConfigRequirements": [
@@ -888,11 +868,9 @@
}
],
"Checks": [
"dynamodb_tables_pitr_enabled",
"dynamodb_tables_pitr_enabled",
"efs_have_backup_enabled",
"rds_instance_backup_enabled",
"rds_instance_backup_enabled",
"redshift_cluster_automated_snapshot",
"s3_bucket_object_versioning"
]
@@ -909,13 +887,11 @@
}
],
"Checks": [
"dynamodb_tables_pitr_enabled",
"dynamodb_tables_pitr_enabled",
"efs_have_backup_enabled",
"elbv2_deletion_protection",
"rds_instance_backup_enabled",
"rds_instance_multi_az",
"rds_instance_backup_enabled",
"redshift_cluster_automated_snapshot",
"s3_bucket_object_versioning"
]
@@ -935,7 +911,6 @@
"Checks": [
"iam_root_mfa_enabled",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_root_hardware_mfa_enabled"
]
},
@@ -954,7 +929,6 @@
"Checks": [
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access"
]
},
@@ -1056,42 +1030,6 @@
}
]
},
{
"Id": "ir-4-1",
"Name": "IR-4(1) Automated Incident Handling Processes",
"Description": "The organization employs automated mechanisms to support the incident handling process.",
"Attributes": [
{
"ItemId": "ir-4-1",
"Section": "Incident Response (IR)",
"SubSection": "Incident Handling (IR-4)",
"Service": "aws"
}
],
"Checks": [
"cloudwatch_changes_to_network_acls_alarm_configured",
"cloudwatch_changes_to_network_gateways_alarm_configured",
"cloudwatch_changes_to_network_route_tables_alarm_configured",
"cloudwatch_changes_to_vpcs_alarm_configured",
"guardduty_is_enabled",
"guardduty_no_high_severity_findings",
"securityhub_enabled"
],
"ConfigRequirements": [
{
"Check": "guardduty_is_enabled",
"ConfigKey": "mute_non_default_regions",
"Operator": "eq",
"Value": false
},
{
"Check": "securityhub_enabled",
"ConfigKey": "mute_non_default_regions",
"Operator": "eq",
"Value": false
}
]
},
{
"Id": "ir-6-1",
"Name": "IR-6(1) Automated Reporting",
@@ -1266,12 +1204,10 @@
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
"s3_account_level_public_access_blocks",
"s3_bucket_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port"
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22"
]
},
{
@@ -1326,12 +1262,10 @@
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
"s3_account_level_public_access_blocks",
"s3_bucket_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port",
"ec2_confidential_workload_host_public_ip"
]
},
@@ -1362,12 +1296,10 @@
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
"s3_account_level_public_access_blocks",
"s3_bucket_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port",
"ec2_confidential_workload_host_public_ip"
]
},
@@ -1485,15 +1417,12 @@
"Checks": [
"cloudtrail_kms_encryption_enabled",
"ec2_ebs_volume_encryption",
"ec2_ebs_volume_encryption",
"efs_encryption_at_rest_enabled",
"opensearch_service_domains_encryption_at_rest_enabled",
"cloudwatch_log_group_kms_encryption_enabled",
"rds_instance_storage_encrypted",
"rds_instance_storage_encrypted",
"redshift_cluster_audit_logging",
"s3_bucket_default_encryption",
"s3_bucket_default_encryption",
"sagemaker_notebook_instance_encryption_enabled",
"sns_topics_kms_encryption_at_rest_enabled",
"kms_key_enclave_debug_attestation_detected"
@@ -1513,7 +1442,6 @@
],
"Checks": [
"ec2_instance_managed_by_ssm",
"ssm_managed_compliant_patching",
"ssm_managed_compliant_patching"
]
},
@@ -1557,7 +1485,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"guardduty_is_enabled",
"redshift_cluster_audit_logging",
"securityhub_enabled"
@@ -1593,7 +1520,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudwatch_changes_to_network_acls_alarm_configured",
"cloudwatch_changes_to_network_gateways_alarm_configured",
"cloudwatch_changes_to_network_route_tables_alarm_configured",
@@ -1636,7 +1562,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudwatch_changes_to_network_acls_alarm_configured",
"cloudwatch_changes_to_network_gateways_alarm_configured",
"cloudwatch_changes_to_network_route_tables_alarm_configured",
@@ -1677,7 +1602,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudwatch_changes_to_network_acls_alarm_configured",
"cloudwatch_changes_to_network_gateways_alarm_configured",
"cloudwatch_changes_to_network_route_tables_alarm_configured",
@@ -1790,10 +1714,8 @@
"Checks": [
"cloudwatch_log_group_retention_policy_specific_days_enabled",
"dynamodb_tables_pitr_enabled",
"dynamodb_tables_pitr_enabled",
"efs_have_backup_enabled",
"rds_instance_backup_enabled",
"rds_instance_backup_enabled",
"redshift_cluster_automated_snapshot",
"s3_bucket_object_versioning"
]
+4 -22
View File
@@ -60,7 +60,6 @@
}
],
"Checks": [
"rds_instance_backup_enabled",
"rds_instance_backup_enabled",
"rds_instance_multi_az",
"redshift_cluster_automated_snapshot"
@@ -115,7 +114,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"cloudwatch_log_group_retention_policy_specific_days_enabled",
"elbv2_logging_enabled",
@@ -145,7 +143,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"elbv2_logging_enabled",
"elb_logging_enabled",
@@ -365,7 +362,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"elbv2_logging_enabled",
"elb_logging_enabled",
@@ -392,7 +388,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"elbv2_logging_enabled",
"elb_logging_enabled",
@@ -437,7 +432,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"elbv2_logging_enabled",
"elb_logging_enabled",
@@ -571,8 +565,7 @@
],
"Checks": [
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port"
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22"
]
},
{
@@ -716,7 +709,6 @@
"iam_password_policy_minimum_length_14",
"iam_password_policy_lowercase",
"iam_password_policy_number",
"iam_password_policy_number",
"iam_password_policy_symbol",
"iam_password_policy_uppercase",
"iam_aws_attached_policy_no_administrative_privileges",
@@ -726,7 +718,6 @@
"iam_root_mfa_enabled",
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_user_accesskey_unused",
"iam_user_console_access_unused"
]
@@ -747,7 +738,6 @@
"iam_password_policy_minimum_length_14",
"iam_password_policy_lowercase",
"iam_password_policy_number",
"iam_password_policy_number",
"iam_password_policy_symbol",
"iam_password_policy_uppercase"
]
@@ -795,12 +785,10 @@
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
"s3_account_level_public_access_blocks",
"s3_bucket_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port"
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22"
]
},
{
@@ -820,8 +808,7 @@
"elbv2_waf_acl_attached",
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port"
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22"
]
},
{
@@ -859,7 +846,6 @@
],
"Checks": [
"ec2_instance_managed_by_ssm",
"ssm_managed_compliant_patching",
"ssm_managed_compliant_patching"
]
},
@@ -879,7 +865,6 @@
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port",
"ec2_confidential_workload_host_vsock_proxy_exposed"
]
},
@@ -933,8 +918,7 @@
"Checks": [
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port"
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22"
]
},
{
@@ -1002,7 +986,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"cloudwatch_changes_to_network_acls_alarm_configured",
"cloudwatch_changes_to_network_gateways_alarm_configured",
@@ -1066,7 +1049,6 @@
"rds_instance_backup_enabled",
"rds_instance_deletion_protection",
"rds_instance_multi_az",
"rds_instance_backup_enabled",
"s3_bucket_object_versioning"
]
}
-11
View File
@@ -30,12 +30,6 @@
"iam_password_policy_symbol",
"iam_password_policy_uppercase",
"iam_password_policy_reuse_24",
"iam_password_policy_minimum_length_14",
"iam_password_policy_lowercase",
"iam_password_policy_number",
"iam_password_policy_number",
"iam_password_policy_symbol",
"iam_password_policy_uppercase",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_inline_policy_no_administrative_privileges",
@@ -85,7 +79,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"cloudtrail_kms_encryption_enabled",
"config_recorder_all_regions_enabled",
@@ -122,8 +115,6 @@
"cloudtrail_log_file_validation_enabled",
"dynamodb_accelerator_cluster_encryption_enabled",
"dynamodb_tables_kms_cmk_encryption_enabled",
"dynamodb_tables_kms_cmk_encryption_enabled",
"ec2_ebs_volume_encryption",
"ec2_ebs_volume_encryption",
"efs_encryption_at_rest_enabled",
"elb_ssl_listeners",
@@ -133,11 +124,9 @@
"rds_instance_storage_encrypted",
"rds_instance_backup_enabled",
"rds_instance_integration_cloudwatch_logs",
"rds_instance_storage_encrypted",
"redshift_cluster_automated_snapshot",
"redshift_cluster_audit_logging",
"s3_bucket_default_encryption",
"s3_bucket_default_encryption",
"s3_bucket_secure_transport_policy",
"sagemaker_notebook_instance_encryption_enabled",
"sns_topics_kms_encryption_at_rest_enabled",
@@ -24,11 +24,9 @@
"elbv2_deletion_protection",
"rds_instance_backup_enabled",
"rds_instance_deletion_protection",
"rds_instance_backup_enabled",
"rds_instance_multi_az",
"redshift_cluster_automated_snapshot",
"s3_bucket_object_versioning",
"ssm_managed_compliant_patching",
"ssm_managed_compliant_patching"
]
},
@@ -47,7 +45,6 @@
"cloudtrail_kms_encryption_enabled",
"cloudwatch_log_group_retention_policy_specific_days_enabled",
"rds_instance_storage_encrypted",
"rds_instance_storage_encrypted",
"rds_snapshots_public_access",
"redshift_cluster_audit_logging",
"redshift_cluster_public_access",
@@ -80,7 +77,6 @@
"iam_password_policy_minimum_length_14",
"iam_password_policy_lowercase",
"iam_password_policy_number",
"iam_password_policy_number",
"iam_password_policy_symbol",
"iam_password_policy_uppercase",
"iam_policy_attached_only_to_group_or_roles",
@@ -92,7 +88,6 @@
"iam_no_root_access_key",
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"awslambda_function_not_publicly_accessible",
@@ -103,13 +98,11 @@
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
"s3_account_level_public_access_blocks",
"s3_bucket_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"secretsmanager_automatic_rotation_enabled",
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port",
"ec2_confidential_workload_host_imdsv2_not_enforced",
"ec2_confidential_workload_host_public_ip"
]
@@ -130,7 +123,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"cloudwatch_log_group_retention_policy_specific_days_enabled",
"elbv2_logging_enabled",
@@ -168,7 +160,6 @@
"iam_password_policy_minimum_length_14",
"iam_password_policy_lowercase",
"iam_password_policy_number",
"iam_password_policy_number",
"iam_password_policy_symbol",
"iam_password_policy_uppercase",
"iam_policy_attached_only_to_group_or_roles",
@@ -180,7 +171,6 @@
"iam_no_root_access_key",
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"awslambda_function_not_publicly_accessible",
@@ -191,13 +181,11 @@
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
"s3_account_level_public_access_blocks",
"s3_bucket_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"secretsmanager_automatic_rotation_enabled",
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port",
"ec2_confidential_workload_host_imdsv2_not_enforced",
"ec2_confidential_workload_host_public_ip"
]
@@ -215,7 +203,6 @@
],
"Checks": [
"ec2_instance_managed_by_ssm",
"ssm_managed_compliant_patching",
"ssm_managed_compliant_patching"
]
},
@@ -246,7 +233,6 @@
"s3_bucket_policy_public_write_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
"ec2_networkacl_allow_ingress_any_port"
]
},
@@ -280,10 +266,8 @@
"kms_cmk_rotation_enabled",
"cloudwatch_log_group_kms_encryption_enabled",
"rds_instance_storage_encrypted",
"rds_instance_storage_encrypted",
"redshift_cluster_audit_logging",
"s3_bucket_default_encryption",
"s3_bucket_default_encryption",
"s3_bucket_secure_transport_policy",
"sagemaker_notebook_instance_encryption_enabled",
"sns_topics_kms_encryption_at_rest_enabled"
@@ -304,14 +288,12 @@
"iam_password_policy_minimum_length_14",
"iam_password_policy_lowercase",
"iam_password_policy_number",
"iam_password_policy_number",
"iam_password_policy_symbol",
"iam_password_policy_uppercase",
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_no_root_access_key",
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access"
]
},
@@ -330,7 +312,6 @@
"iam_password_policy_minimum_length_14",
"iam_password_policy_lowercase",
"iam_password_policy_number",
"iam_password_policy_number",
"iam_password_policy_symbol",
"iam_password_policy_uppercase",
"iam_rotate_access_key_90_days",
@@ -41,12 +41,9 @@
}
],
"Checks": [
"dynamodb_tables_pitr_enabled",
"dynamodb_tables_pitr_enabled",
"efs_have_backup_enabled",
"rds_instance_backup_enabled",
"rds_instance_backup_enabled",
"rds_instance_backup_enabled",
"redshift_cluster_automated_snapshot",
"s3_bucket_object_versioning"
]
@@ -66,7 +63,6 @@
"cloudtrail_kms_encryption_enabled",
"dynamodb_accelerator_cluster_encryption_enabled",
"dynamodb_tables_kms_cmk_encryption_enabled",
"dynamodb_tables_kms_cmk_encryption_enabled",
"dynamodb_tables_pitr_enabled",
"ec2_ebs_volume_encryption",
"ec2_ebs_default_encryption",
@@ -76,12 +72,9 @@
"cloudwatch_log_group_kms_encryption_enabled",
"rds_instance_backup_enabled",
"rds_instance_storage_encrypted",
"rds_instance_backup_enabled",
"rds_instance_storage_encrypted",
"redshift_cluster_automated_snapshot",
"redshift_cluster_audit_logging",
"s3_bucket_default_encryption",
"s3_bucket_default_encryption",
"s3_bucket_object_versioning",
"sagemaker_notebook_instance_encryption_enabled",
"sns_topics_kms_encryption_at_rest_enabled"
@@ -101,10 +94,7 @@
"Checks": [
"rds_instance_backup_enabled",
"dynamodb_tables_pitr_enabled",
"dynamodb_tables_pitr_enabled",
"efs_have_backup_enabled",
"rds_instance_backup_enabled",
"rds_instance_backup_enabled",
"redshift_cluster_automated_snapshot",
"s3_bucket_object_versioning"
]
@@ -192,12 +182,8 @@
}
],
"Checks": [
"dynamodb_tables_pitr_enabled",
"dynamodb_tables_pitr_enabled",
"efs_have_backup_enabled",
"efs_have_backup_enabled",
"rds_instance_backup_enabled",
"rds_instance_backup_enabled",
"rds_instance_backup_enabled",
"redshift_cluster_automated_snapshot",
"s3_bucket_object_versioning"
@@ -215,12 +201,8 @@
}
],
"Checks": [
"dynamodb_tables_pitr_enabled",
"dynamodb_tables_pitr_enabled",
"efs_have_backup_enabled",
"efs_have_backup_enabled",
"rds_instance_backup_enabled",
"rds_instance_backup_enabled",
"rds_instance_backup_enabled",
"redshift_cluster_automated_snapshot",
"s3_bucket_object_versioning"
@@ -299,12 +281,8 @@
}
],
"Checks": [
"dynamodb_tables_pitr_enabled",
"dynamodb_tables_pitr_enabled",
"efs_have_backup_enabled",
"efs_have_backup_enabled",
"rds_instance_backup_enabled",
"rds_instance_backup_enabled",
"rds_instance_backup_enabled",
"redshift_cluster_automated_snapshot",
"s3_bucket_object_versioning"
-42
View File
@@ -70,7 +70,6 @@
"rds_instance_backup_enabled",
"rds_instance_storage_encrypted",
"rds_instance_multi_az",
"rds_instance_storage_encrypted",
"rds_snapshots_public_access",
"redshift_cluster_audit_logging",
"redshift_cluster_public_access",
@@ -85,7 +84,6 @@
"sns_topics_kms_encryption_at_rest_enabled",
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port",
"ec2_confidential_workload_host_public_ip"
]
},
@@ -106,7 +104,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"cloudtrail_kms_encryption_enabled",
"cloudtrail_log_file_validation_enabled",
@@ -179,14 +176,12 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"elbv2_logging_enabled",
"elb_logging_enabled",
"guardduty_is_enabled",
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"redshift_cluster_audit_logging",
"s3_bucket_server_access_logging_enabled",
"securityhub_enabled",
@@ -276,8 +271,6 @@
"cloudtrail_kms_encryption_enabled",
"dynamodb_accelerator_cluster_encryption_enabled",
"dynamodb_tables_kms_cmk_encryption_enabled",
"dynamodb_tables_kms_cmk_encryption_enabled",
"ec2_ebs_volume_encryption",
"ec2_ebs_volume_encryption",
"ec2_ebs_default_encryption",
"efs_encryption_at_rest_enabled",
@@ -289,11 +282,9 @@
"rds_instance_storage_encrypted",
"rds_instance_backup_enabled",
"rds_instance_integration_cloudwatch_logs",
"rds_instance_storage_encrypted",
"redshift_cluster_automated_snapshot",
"redshift_cluster_audit_logging",
"s3_bucket_default_encryption",
"s3_bucket_default_encryption",
"sagemaker_notebook_instance_encryption_enabled",
"sns_topics_kms_encryption_at_rest_enabled"
]
@@ -353,7 +344,6 @@
],
"Checks": [
"ec2_instance_managed_by_ssm",
"ssm_managed_compliant_patching",
"ssm_managed_compliant_patching"
]
},
@@ -463,7 +453,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"elbv2_logging_enabled",
"elb_logging_enabled",
@@ -502,14 +491,10 @@
}
],
"Checks": [
"dynamodb_tables_pitr_enabled",
"dynamodb_tables_pitr_enabled",
"efs_have_backup_enabled",
"efs_have_backup_enabled",
"rds_instance_backup_enabled",
"rds_instance_backup_enabled",
"rds_instance_multi_az",
"rds_instance_backup_enabled",
"redshift_cluster_automated_snapshot",
"s3_bucket_object_versioning"
]
@@ -526,14 +511,10 @@
}
],
"Checks": [
"dynamodb_tables_pitr_enabled",
"dynamodb_tables_pitr_enabled",
"efs_have_backup_enabled",
"efs_have_backup_enabled",
"rds_instance_backup_enabled",
"rds_instance_backup_enabled",
"rds_instance_multi_az",
"rds_instance_backup_enabled",
"redshift_cluster_automated_snapshot",
"s3_bucket_object_versioning"
]
@@ -550,14 +531,10 @@
}
],
"Checks": [
"dynamodb_tables_pitr_enabled",
"dynamodb_tables_pitr_enabled",
"efs_have_backup_enabled",
"efs_have_backup_enabled",
"rds_instance_backup_enabled",
"rds_instance_backup_enabled",
"rds_instance_multi_az",
"rds_instance_backup_enabled",
"redshift_cluster_automated_snapshot",
"s3_bucket_object_versioning"
]
@@ -574,14 +551,10 @@
}
],
"Checks": [
"dynamodb_tables_pitr_enabled",
"dynamodb_tables_pitr_enabled",
"efs_have_backup_enabled",
"efs_have_backup_enabled",
"rds_instance_backup_enabled",
"rds_instance_backup_enabled",
"rds_instance_multi_az",
"rds_instance_backup_enabled",
"redshift_cluster_automated_snapshot",
"s3_bucket_object_versioning"
]
@@ -642,7 +615,6 @@
"redshift_cluster_public_access",
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
"s3_bucket_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"ec2_confidential_workload_host_public_ip",
"ec2_confidential_workload_host_imdsv2_not_enforced",
@@ -679,12 +651,8 @@
}
],
"Checks": [
"dynamodb_tables_pitr_enabled",
"dynamodb_tables_pitr_enabled",
"efs_have_backup_enabled",
"efs_have_backup_enabled",
"rds_instance_backup_enabled",
"rds_instance_backup_enabled",
"rds_instance_backup_enabled",
"redshift_cluster_automated_snapshot",
"s3_bucket_object_versioning"
@@ -705,7 +673,6 @@
"cloudtrail_kms_encryption_enabled",
"dynamodb_accelerator_cluster_encryption_enabled",
"dynamodb_tables_kms_cmk_encryption_enabled",
"dynamodb_tables_kms_cmk_encryption_enabled",
"ec2_ebs_volume_encryption",
"ec2_ebs_default_encryption",
"efs_encryption_at_rest_enabled",
@@ -714,10 +681,8 @@
"kms_cmk_rotation_enabled",
"cloudwatch_log_group_kms_encryption_enabled",
"rds_instance_storage_encrypted",
"rds_instance_storage_encrypted",
"redshift_cluster_audit_logging",
"s3_bucket_default_encryption",
"s3_bucket_default_encryption",
"s3_bucket_secure_transport_policy",
"sagemaker_notebook_instance_encryption_enabled",
"sns_topics_kms_encryption_at_rest_enabled",
@@ -741,7 +706,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"cloudtrail_log_file_validation_enabled",
"cloudwatch_log_group_retention_policy_specific_days_enabled",
@@ -828,7 +792,6 @@
"iam_password_policy_reuse_24",
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access"
]
},
@@ -852,7 +815,6 @@
"s3_bucket_secure_transport_policy",
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port",
"ec2_confidential_workload_host_unrestricted_ingress",
"ec2_confidential_workload_host_vsock_proxy_exposed"
]
@@ -872,7 +834,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"elb_ssl_listeners",
"guardduty_is_enabled",
@@ -910,7 +871,6 @@
"cloudtrail_kms_encryption_enabled",
"dynamodb_accelerator_cluster_encryption_enabled",
"dynamodb_tables_kms_cmk_encryption_enabled",
"dynamodb_tables_kms_cmk_encryption_enabled",
"ec2_ebs_volume_encryption",
"ec2_ebs_default_encryption",
"efs_encryption_at_rest_enabled",
@@ -919,10 +879,8 @@
"opensearch_service_domains_encryption_at_rest_enabled",
"cloudwatch_log_group_kms_encryption_enabled",
"rds_instance_storage_encrypted",
"rds_instance_storage_encrypted",
"redshift_cluster_audit_logging",
"s3_bucket_default_encryption",
"s3_bucket_default_encryption",
"s3_bucket_secure_transport_policy",
"sagemaker_notebook_instance_encryption_enabled",
"sns_topics_kms_encryption_at_rest_enabled"
+4 -24
View File
@@ -259,16 +259,7 @@
"iam_rotate_access_key_90_days",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"iam_no_root_access_key",
"iam_password_policy_expires_passwords_within_90_days_or_less",
"iam_password_policy_reuse_24",
"iam_password_policy_minimum_length_14",
"iam_password_policy_number",
"iam_password_policy_symbol",
"iam_password_policy_lowercase",
"iam_password_policy_uppercase",
"iam_user_mfa_enabled_console_access",
"iam_rotate_access_key_90_days"
"iam_no_root_access_key"
]
},
{
@@ -997,11 +988,9 @@
"emr_cluster_publicly_accesible",
"glacier_vaults_policy_public_access",
"awslambda_function_not_publicly_accessible",
"awslambda_function_not_publicly_accessible",
"rds_instance_no_public_access",
"rds_snapshots_public_access",
"kms_key_not_publicly_accessible",
"opensearch_service_domains_not_publicly_accessible",
"redshift_cluster_public_access",
"s3_account_level_public_access_blocks",
"s3_bucket_public_access",
@@ -1018,7 +1007,6 @@
"eks_cluster_not_publicly_accessible",
"elb_internet_facing",
"elbv2_internet_facing",
"s3_account_level_public_access_blocks",
"sns_topics_not_publicly_accessible",
"sqs_queues_not_publicly_accessible",
"ssm_documents_set_as_public",
@@ -1091,11 +1079,10 @@
}
],
"Checks": [
"codebuild_project_artifact_encryption",
"codebuild_project_envvar_awscred_check",
"codebuild_project_no_secrets_in_variables",
"codebuild_project_logging_enabled",
"codebuild_project_older_90_days",
"codebuild_project_source_repo_url_check",
"codebuild_project_source_repo_url_no_sensitive_credentials",
"codebuild_project_user_controlled_buildspec"
]
},
@@ -1378,7 +1365,6 @@
"apigateway_restapi_logging_enabled",
"apigatewayv2_api_access_logging_enabled",
"appsync_field_level_logging_enabled",
"athena_workgroup_logging_enabled",
"awslambda_function_invoke_api_operations_cloudtrail_logging_enabled",
"bedrock_model_invocation_logging_enabled",
"bedrock_model_invocation_logs_encryption_enabled",
@@ -1631,7 +1617,6 @@
"ec2_securitygroup_from_launch_wizard",
"ec2_securitygroup_not_used",
"ec2_securitygroup_with_many_ingress_egress_rules",
"ec2_transitgateway_auto_accept_vpc_attachments",
"ec2_confidential_workload_host_imdsv2_not_enforced",
"ec2_confidential_workload_host_public_ip",
"ec2_confidential_workload_host_unrestricted_ingress",
@@ -1730,7 +1715,6 @@
"ec2_securitygroup_from_launch_wizard",
"ec2_securitygroup_not_used",
"ec2_securitygroup_with_many_ingress_egress_rules",
"ec2_transitgateway_auto_accept_vpc_attachments",
"ec2_confidential_workload_host_imdsv2_not_enforced",
"ec2_confidential_workload_host_public_ip",
"ec2_confidential_workload_host_unrestricted_ingress"
@@ -1828,7 +1812,6 @@
"ec2_securitygroup_from_launch_wizard",
"ec2_securitygroup_not_used",
"ec2_securitygroup_with_many_ingress_egress_rules",
"ec2_transitgateway_auto_accept_vpc_attachments",
"ec2_confidential_workload_host_imdsv2_not_enforced",
"ec2_confidential_workload_host_public_ip",
"ec2_confidential_workload_host_unrestricted_ingress"
@@ -1847,7 +1830,7 @@
}
],
"Checks": [
"vpc_default_security_group_closed",
"ec2_securitygroup_default_restrict_traffic",
"vpc_flow_logs_enabled",
"securityhub_enabled"
],
@@ -1931,9 +1914,6 @@
"storagegateway_fileshare_encryption_enabled",
"transfer_server_in_transit_encryption_enabled",
"workspaces_volume_encryption_enabled",
"dynamodb_tables_kms_cmk_encryption_enabled",
"eks_cluster_kms_cmk_encryption_in_secrets_enabled",
"kafka_cluster_encryption_at_rest_uses_cmk",
"kms_cmk_are_used",
"kms_cmk_not_deleted_unintentionally",
"kms_cmk_not_multi_region",
@@ -2603,7 +2603,6 @@
"cloudwatch_changes_to_network_gateways_alarm_configured",
"cloudwatch_changes_to_network_route_tables_alarm_configured",
"cloudwatch_changes_to_vpcs_alarm_configured",
"cloudwatch_log_group_no_critical_pii_in_logs",
"cloudwatch_log_group_no_secrets_in_logs",
"cloudwatch_log_group_retention_policy_specific_days_enabled",
"codebuild_project_logging_enabled",
@@ -2793,7 +2792,6 @@
"cloudwatch_changes_to_vpcs_alarm_configured",
"cloudwatch_cross_account_sharing_disabled",
"cloudwatch_log_group_kms_encryption_enabled",
"cloudwatch_log_group_no_critical_pii_in_logs",
"cloudwatch_log_group_no_secrets_in_logs",
"cloudwatch_log_group_not_publicly_accessible",
"cloudwatch_log_group_retention_policy_specific_days_enabled",
@@ -2991,7 +2989,6 @@
"cloudwatch_changes_to_vpcs_alarm_configured",
"cloudwatch_cross_account_sharing_disabled",
"cloudwatch_log_group_kms_encryption_enabled",
"cloudwatch_log_group_no_critical_pii_in_logs",
"cloudwatch_log_group_no_secrets_in_logs",
"cloudwatch_log_group_not_publicly_accessible",
"cloudwatch_log_group_retention_policy_specific_days_enabled",
@@ -2606,7 +2606,6 @@
"cloudwatch_changes_to_network_gateways_alarm_configured",
"cloudwatch_changes_to_network_route_tables_alarm_configured",
"cloudwatch_changes_to_vpcs_alarm_configured",
"cloudwatch_log_group_no_critical_pii_in_logs",
"cloudwatch_log_group_no_secrets_in_logs",
"cloudwatch_log_group_retention_policy_specific_days_enabled",
"codebuild_project_logging_enabled",
@@ -2796,7 +2795,6 @@
"cloudwatch_changes_to_vpcs_alarm_configured",
"cloudwatch_cross_account_sharing_disabled",
"cloudwatch_log_group_kms_encryption_enabled",
"cloudwatch_log_group_no_critical_pii_in_logs",
"cloudwatch_log_group_no_secrets_in_logs",
"cloudwatch_log_group_not_publicly_accessible",
"cloudwatch_log_group_retention_policy_specific_days_enabled",
@@ -2994,7 +2992,6 @@
"cloudwatch_changes_to_vpcs_alarm_configured",
"cloudwatch_cross_account_sharing_disabled",
"cloudwatch_log_group_kms_encryption_enabled",
"cloudwatch_log_group_no_critical_pii_in_logs",
"cloudwatch_log_group_no_secrets_in_logs",
"cloudwatch_log_group_not_publicly_accessible",
"cloudwatch_log_group_retention_policy_specific_days_enabled",
-1
View File
@@ -326,7 +326,6 @@
"cloudwatch_changes_to_vpcs_alarm_configured",
"cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled",
"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled",
"cloudwatch_log_metric_filter_aws_organizations_changes",
"cloudwatch_log_metric_filter_for_s3_bucket_policy_changes",
"cloudwatch_log_metric_filter_policy_changes",
"cloudwatch_log_metric_filter_security_group_changes"
@@ -29,7 +29,6 @@
"iam_root_mfa_enabled",
"iam_no_root_access_key",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_role_access_not_stale_to_bedrock",
"iam_user_access_not_stale_to_bedrock",
"iam_user_access_not_stale_to_sagemaker",
@@ -46,8 +45,7 @@
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port"
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22"
]
},
{
@@ -74,7 +72,6 @@
"iam_root_mfa_enabled",
"iam_no_root_access_key",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_role_access_not_stale_to_bedrock",
"iam_user_access_not_stale_to_bedrock",
"iam_user_access_not_stale_to_sagemaker",
@@ -91,8 +88,7 @@
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port"
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22"
]
},
{
@@ -122,8 +118,7 @@
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port"
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22"
]
},
{
@@ -223,7 +218,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"elbv2_logging_enabled",
"elb_logging_enabled",
"guardduty_is_enabled",
@@ -286,8 +280,7 @@
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port"
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22"
]
},
{
@@ -305,8 +298,7 @@
"s3_account_level_public_access_blocks",
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port"
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22"
]
},
{
@@ -325,7 +317,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"cloudwatch_log_group_retention_policy_specific_days_enabled",
"elbv2_logging_enabled",
@@ -367,7 +358,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"guardduty_is_enabled",
"rds_instance_integration_cloudwatch_logs",
@@ -398,7 +388,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"rds_instance_integration_cloudwatch_logs",
"s3_bucket_server_access_logging_enabled",
@@ -571,7 +560,6 @@
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port",
"ec2_confidential_workload_host_vsock_proxy_exposed"
]
},
@@ -604,7 +592,6 @@
],
"Checks": [
"iam_root_mfa_enabled",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access"
]
},
@@ -622,7 +609,6 @@
"Checks": [
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access"
]
},
@@ -928,7 +914,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_log_file_validation_enabled",
"elbv2_logging_enabled",
"elb_logging_enabled",
@@ -944,8 +929,7 @@
"securityhub_enabled",
"vpc_flow_logs_enabled",
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port"
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22"
],
"ConfigRequirements": [
{
@@ -988,7 +972,6 @@
"rds_instance_integration_cloudwatch_logs",
"rds_instance_multi_az",
"rds_instance_no_public_access",
"rds_instance_backup_enabled",
"redshift_cluster_public_access",
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
@@ -1060,7 +1043,6 @@
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port",
"ec2_confidential_workload_host_public_ip"
]
},
@@ -1077,8 +1059,7 @@
],
"Checks": [
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port"
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22"
]
},
{
@@ -1155,7 +1136,6 @@
"Checks": [
"cloudtrail_kms_encryption_enabled",
"dynamodb_tables_kms_cmk_encryption_enabled",
"dynamodb_tables_kms_cmk_encryption_enabled",
"ec2_ebs_volume_encryption",
"efs_encryption_at_rest_enabled",
"opensearch_service_domains_encryption_at_rest_enabled",
@@ -1212,7 +1192,6 @@
"ec2_instance_managed_by_ssm",
"guardduty_is_enabled",
"securityhub_enabled",
"ssm_managed_compliant_patching",
"ssm_managed_compliant_patching"
],
"ConfigRequirements": [
@@ -1300,7 +1279,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"elbv2_logging_enabled",
"elb_logging_enabled",
"guardduty_is_enabled",
@@ -1340,7 +1318,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"elbv2_logging_enabled",
"elb_logging_enabled",
"guardduty_is_enabled",
@@ -108,7 +108,6 @@
}
],
"Checks": [
"cloudtrail_multi_region_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"cloudwatch_changes_to_network_acls_alarm_configured",
@@ -239,8 +238,7 @@
"redshift_cluster_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
"s3_bucket_public_access"
"s3_bucket_policy_public_write_access"
]
},
{
@@ -266,12 +264,10 @@
"redshift_cluster_public_access",
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
"s3_bucket_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port"
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22"
]
},
{
@@ -340,7 +336,6 @@
"redshift_cluster_public_access",
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
"s3_bucket_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured"
]
},
@@ -425,7 +420,6 @@
"redshift_cluster_public_access",
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
"s3_bucket_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured"
]
},
@@ -445,7 +439,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"elbv2_logging_enabled",
"elb_logging_enabled",
@@ -471,7 +464,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"elbv2_logging_enabled",
"elb_logging_enabled",
@@ -633,7 +625,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"elbv2_logging_enabled",
"elb_logging_enabled",
@@ -746,7 +737,6 @@
],
"Checks": [
"ec2_instance_managed_by_ssm",
"ssm_managed_compliant_patching",
"ssm_managed_compliant_patching"
]
},
@@ -764,7 +754,6 @@
"Checks": [
"dynamodb_tables_pitr_enabled",
"efs_have_backup_enabled",
"rds_instance_backup_enabled",
"rds_instance_backup_enabled"
]
},
@@ -784,7 +773,6 @@
"efs_have_backup_enabled",
"elbv2_deletion_protection",
"rds_instance_backup_enabled",
"rds_instance_backup_enabled",
"rds_instance_multi_az",
"s3_bucket_object_versioning"
]
@@ -804,7 +792,6 @@
"Checks": [
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access"
]
},
@@ -821,7 +808,6 @@
}
],
"Checks": [
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access"
]
},
@@ -840,7 +826,6 @@
"Checks": [
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access"
]
},
@@ -1101,8 +1086,7 @@
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port"
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22"
]
},
{
@@ -1135,8 +1119,7 @@
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port"
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22"
]
},
{
@@ -1237,7 +1220,6 @@
"opensearch_service_domains_encryption_at_rest_enabled",
"cloudwatch_log_group_kms_encryption_enabled",
"rds_instance_storage_encrypted",
"rds_instance_storage_encrypted",
"redshift_cluster_audit_logging",
"s3_bucket_default_encryption",
"sagemaker_notebook_instance_encryption_enabled",
@@ -1258,7 +1240,6 @@
],
"Checks": [
"ec2_instance_managed_by_ssm",
"ssm_managed_compliant_patching",
"ssm_managed_compliant_patching"
]
},
@@ -1513,7 +1494,6 @@
"dynamodb_tables_pitr_enabled",
"efs_have_backup_enabled",
"rds_instance_backup_enabled",
"rds_instance_backup_enabled",
"s3_bucket_object_versioning"
]
}
@@ -28,7 +28,6 @@
"iam_no_root_access_key",
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_role_access_not_stale_to_bedrock",
"iam_user_access_not_stale_to_bedrock",
"iam_user_access_not_stale_to_sagemaker",
@@ -162,7 +161,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"rds_instance_integration_cloudwatch_logs",
"redshift_cluster_audit_logging",
@@ -201,7 +199,6 @@
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
"s3_account_level_public_access_blocks",
"s3_bucket_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured"
]
},
@@ -336,7 +333,6 @@
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
"s3_account_level_public_access_blocks",
"s3_bucket_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"ec2_confidential_workload_host_imdsv2_not_enforced",
"kms_key_enclave_attestation_not_enforced"
@@ -357,7 +353,6 @@
"Checks": [
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"rds_instance_integration_cloudwatch_logs",
@@ -380,7 +375,6 @@
"Checks": [
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access"
]
},
@@ -408,7 +402,6 @@
"iam_no_root_access_key",
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
@@ -439,7 +432,6 @@
"iam_no_root_access_key",
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
@@ -470,7 +462,6 @@
"iam_no_root_access_key",
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
@@ -501,7 +492,6 @@
"iam_no_root_access_key",
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
@@ -532,7 +522,6 @@
"iam_no_root_access_key",
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
@@ -563,7 +552,6 @@
"iam_no_root_access_key",
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
@@ -594,7 +582,6 @@
"iam_no_root_access_key",
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
@@ -625,7 +612,6 @@
"iam_no_root_access_key",
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
@@ -655,7 +641,6 @@
"iam_no_root_access_key",
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
@@ -686,7 +671,6 @@
"iam_no_root_access_key",
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
@@ -710,7 +694,6 @@
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_rotate_access_key_90_days",
"iam_no_root_access_key",
"iam_root_mfa_enabled",
@@ -748,7 +731,6 @@
"iam_no_root_access_key",
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
@@ -779,7 +761,6 @@
"iam_no_root_access_key",
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
@@ -810,7 +791,6 @@
"iam_no_root_access_key",
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
@@ -848,7 +828,6 @@
"redshift_cluster_public_access",
"s3_bucket_policy_public_write_access",
"s3_account_level_public_access_blocks",
"s3_bucket_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured"
]
},
@@ -876,7 +855,6 @@
"iam_no_root_access_key",
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_role_access_not_stale_to_bedrock",
"iam_user_access_not_stale_to_bedrock",
"iam_user_access_not_stale_to_sagemaker",
@@ -901,7 +879,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"rds_instance_integration_cloudwatch_logs",
"redshift_cluster_audit_logging",
@@ -933,7 +910,6 @@
"iam_no_root_access_key",
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
@@ -988,7 +964,6 @@
"iam_no_root_access_key",
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
@@ -1019,7 +994,6 @@
"iam_no_root_access_key",
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
@@ -1050,7 +1024,6 @@
"iam_no_root_access_key",
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
@@ -1100,11 +1073,9 @@
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
"s3_account_level_public_access_blocks",
"s3_bucket_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
"ec2_networkacl_allow_ingress_any_port",
"ec2_confidential_workload_host_public_ip"
]
},
@@ -1144,7 +1115,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"elbv2_logging_enabled",
"elb_logging_enabled",
@@ -1178,7 +1148,6 @@
"iam_no_root_access_key",
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
@@ -1238,7 +1207,6 @@
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
"s3_account_level_public_access_blocks",
"s3_bucket_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"ec2_confidential_workload_host_imdsv2_not_enforced",
"kms_key_enclave_attestation_bypassable_path"
@@ -1298,7 +1266,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"rds_instance_integration_cloudwatch_logs",
"redshift_cluster_audit_logging",
@@ -1340,7 +1307,6 @@
"iam_password_policy_minimum_length_14",
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access"
]
},
@@ -1361,7 +1327,6 @@
"iam_password_policy_minimum_length_14",
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access"
]
},
@@ -1405,12 +1370,10 @@
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
"s3_account_level_public_access_blocks",
"s3_bucket_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port"
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22"
]
},
{
@@ -1437,12 +1400,10 @@
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
"s3_account_level_public_access_blocks",
"s3_bucket_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port"
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22"
]
},
{
@@ -1488,10 +1449,8 @@
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
"s3_account_level_public_access_blocks",
"s3_bucket_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
"ec2_networkacl_allow_ingress_any_port"
]
},
@@ -1519,12 +1478,10 @@
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
"s3_account_level_public_access_blocks",
"s3_bucket_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port"
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22"
]
},
{
@@ -1551,12 +1508,10 @@
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
"s3_account_level_public_access_blocks",
"s3_bucket_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port"
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22"
]
},
{
@@ -1582,7 +1537,6 @@
"iam_no_root_access_key",
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
@@ -1624,7 +1578,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_bedrock_logging_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"elbv2_logging_enabled",
@@ -1677,7 +1630,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"elbv2_logging_enabled",
"elb_logging_enabled",
@@ -1704,7 +1656,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"elbv2_logging_enabled",
"elb_logging_enabled",
@@ -1731,7 +1682,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"elbv2_logging_enabled",
"elb_logging_enabled",
@@ -1758,7 +1708,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"elbv2_logging_enabled",
"elb_logging_enabled",
@@ -1785,7 +1734,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"elbv2_logging_enabled",
"elb_logging_enabled",
@@ -1812,7 +1760,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"elbv2_logging_enabled",
"elb_logging_enabled",
@@ -1890,7 +1837,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"cloudwatch_log_group_retention_policy_specific_days_enabled",
"elbv2_logging_enabled",
@@ -1918,7 +1864,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"cloudwatch_log_group_retention_policy_specific_days_enabled",
"elbv2_logging_enabled",
@@ -1982,7 +1927,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"cloudwatch_log_group_retention_policy_specific_days_enabled",
"elbv2_logging_enabled",
@@ -2010,7 +1954,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"cloudwatch_log_group_retention_policy_specific_days_enabled",
"elbv2_logging_enabled",
@@ -2054,7 +1997,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"elbv2_logging_enabled",
"elb_logging_enabled",
@@ -2120,7 +2062,6 @@
"opensearch_service_domains_node_to_node_encryption_enabled",
"cloudwatch_log_group_kms_encryption_enabled",
"rds_instance_storage_encrypted",
"rds_instance_storage_encrypted",
"redshift_cluster_audit_logging",
"s3_bucket_default_encryption",
"s3_bucket_secure_transport_policy",
@@ -2160,7 +2101,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"cloudwatch_log_group_retention_policy_specific_days_enabled",
"elbv2_logging_enabled",
@@ -2219,7 +2159,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_bedrock_logging_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"elbv2_logging_enabled",
@@ -2247,7 +2186,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_bedrock_logging_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"elbv2_logging_enabled",
@@ -2275,7 +2213,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"cloudwatch_log_group_retention_policy_specific_days_enabled",
"elbv2_logging_enabled",
@@ -2303,7 +2240,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"cloudwatch_log_group_retention_policy_specific_days_enabled",
"elbv2_logging_enabled",
@@ -2331,7 +2267,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"cloudwatch_changes_to_network_acls_alarm_configured",
"cloudwatch_changes_to_network_gateways_alarm_configured",
@@ -2380,7 +2315,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"elbv2_logging_enabled",
"elb_logging_enabled",
@@ -2407,7 +2341,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"cloudwatch_changes_to_network_acls_alarm_configured",
"cloudwatch_changes_to_network_gateways_alarm_configured",
@@ -2456,7 +2389,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"cloudwatch_changes_to_network_acls_alarm_configured",
"cloudwatch_changes_to_network_gateways_alarm_configured",
@@ -2505,7 +2437,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"elbv2_logging_enabled",
"elb_logging_enabled",
@@ -2633,7 +2564,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"cloudwatch_changes_to_network_acls_alarm_configured",
"cloudwatch_changes_to_network_gateways_alarm_configured",
@@ -2882,7 +2812,6 @@
"iam_no_root_access_key",
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
@@ -2906,7 +2835,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"elbv2_logging_enabled",
"elb_logging_enabled",
@@ -3045,7 +2973,6 @@
"Checks": [
"ec2_instance_managed_by_ssm",
"guardduty_is_enabled",
"ssm_managed_compliant_patching",
"ssm_managed_compliant_patching"
],
"ConfigRequirements": [
@@ -3317,7 +3244,6 @@
"efs_have_backup_enabled",
"rds_instance_backup_enabled",
"redshift_cluster_automated_snapshot",
"rds_instance_backup_enabled",
"dynamodb_tables_pitr_enabled",
"s3_bucket_object_versioning"
]
@@ -3432,7 +3358,6 @@
"elbv2_deletion_protection",
"rds_instance_backup_enabled",
"rds_instance_deletion_protection",
"rds_instance_backup_enabled",
"rds_instance_multi_az",
"redshift_cluster_automated_snapshot",
"s3_bucket_object_versioning",
@@ -3470,7 +3395,6 @@
"Checks": [
"efs_have_backup_enabled",
"rds_instance_backup_enabled",
"rds_instance_backup_enabled",
"redshift_cluster_automated_snapshot",
"s3_bucket_object_versioning"
]
@@ -3490,7 +3414,6 @@
"Checks": [
"efs_have_backup_enabled",
"rds_instance_backup_enabled",
"rds_instance_backup_enabled",
"redshift_cluster_automated_snapshot",
"s3_bucket_object_versioning"
]
@@ -3511,7 +3434,6 @@
"dynamodb_tables_pitr_enabled",
"efs_have_backup_enabled",
"rds_instance_backup_enabled",
"rds_instance_backup_enabled",
"rds_instance_multi_az",
"redshift_cluster_automated_snapshot",
"s3_bucket_object_versioning"
@@ -3533,7 +3455,6 @@
"dynamodb_tables_pitr_enabled",
"efs_have_backup_enabled",
"rds_instance_backup_enabled",
"rds_instance_backup_enabled",
"redshift_cluster_automated_snapshot",
"redshift_cluster_automatic_upgrades",
"s3_bucket_object_versioning"
@@ -3555,7 +3476,6 @@
"dynamodb_tables_pitr_enabled",
"efs_have_backup_enabled",
"rds_instance_backup_enabled",
"rds_instance_backup_enabled",
"redshift_cluster_automated_snapshot",
"redshift_cluster_automatic_upgrades",
"s3_bucket_object_versioning"
@@ -3577,7 +3497,6 @@
"efs_have_backup_enabled",
"rds_instance_backup_enabled",
"redshift_cluster_automated_snapshot",
"rds_instance_backup_enabled",
"dynamodb_tables_pitr_enabled",
"redshift_cluster_automatic_upgrades",
"s3_bucket_object_versioning"
@@ -3603,10 +3522,8 @@
"opensearch_service_domains_encryption_at_rest_enabled",
"cloudwatch_log_group_kms_encryption_enabled",
"rds_instance_storage_encrypted",
"rds_instance_storage_encrypted",
"redshift_cluster_audit_logging",
"s3_bucket_default_encryption",
"s3_bucket_default_encryption",
"sagemaker_notebook_instance_encryption_enabled",
"sns_topics_kms_encryption_at_rest_enabled"
]
@@ -3625,7 +3542,6 @@
],
"Checks": [
"rds_instance_storage_encrypted",
"s3_bucket_default_encryption",
"s3_bucket_default_encryption"
]
},
@@ -3644,7 +3560,6 @@
"dynamodb_tables_pitr_enabled",
"efs_have_backup_enabled",
"rds_instance_backup_enabled",
"rds_instance_backup_enabled",
"rds_instance_multi_az",
"redshift_cluster_automated_snapshot",
"s3_bucket_object_versioning",
@@ -3667,7 +3582,6 @@
"dynamodb_tables_pitr_enabled",
"efs_have_backup_enabled",
"rds_instance_backup_enabled",
"rds_instance_backup_enabled",
"redshift_cluster_automated_snapshot",
"s3_bucket_object_versioning"
]
@@ -3702,7 +3616,6 @@
"Checks": [
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access"
]
},
@@ -3721,7 +3634,6 @@
"Checks": [
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access"
]
},
@@ -3740,7 +3652,6 @@
"Checks": [
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access"
]
},
@@ -3760,7 +3671,6 @@
"Checks": [
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access"
]
},
@@ -3779,7 +3689,6 @@
"Checks": [
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access"
]
},
@@ -3800,7 +3709,6 @@
"cloudtrail_multi_region_enabled",
"apigateway_restapi_logging_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"elbv2_logging_enabled",
@@ -4040,23 +3948,6 @@
"iam_password_policy_minimum_length_14"
]
},
{
"Id": "ia_5_1_h",
"Name": "IA-5(1)(h)",
"Description": "For password-based authentication: (h) Enforce the following composition and complexity rules: [Assignment: organization-defined composition and complexity rules].",
"Attributes": [
{
"ItemId": "ia_5_1_h",
"Section": "Identification and Authentication (IA)",
"SubSection": "Authenticator Management (IA-5)",
"SubGroup": "IA-5(1) Password-Based Authentication",
"Service": "iam"
}
],
"Checks": [
"iam_password_policy_minimum_length_14"
]
},
{
"Id": "ia_5_8",
"Name": "IA-5(8) Multiple System Accounts",
@@ -4173,7 +4064,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"elbv2_logging_enabled",
"elb_logging_enabled",
@@ -4214,7 +4104,6 @@
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
"s3_account_level_public_access_blocks",
"s3_bucket_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured"
]
},
@@ -4302,7 +4191,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"cloudwatch_changes_to_network_acls_alarm_configured",
"cloudwatch_changes_to_network_gateways_alarm_configured",
@@ -4351,7 +4239,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"cloudwatch_changes_to_network_acls_alarm_configured",
"cloudwatch_changes_to_network_gateways_alarm_configured",
@@ -4459,7 +4346,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"cloudwatch_changes_to_network_acls_alarm_configured",
"cloudwatch_changes_to_network_gateways_alarm_configured",
@@ -4844,7 +4730,6 @@
"rds_instance_backup_enabled",
"rds_instance_deletion_protection",
"rds_instance_multi_az",
"rds_instance_backup_enabled",
"redshift_cluster_automated_snapshot",
"redshift_cluster_automatic_upgrades",
"s3_bucket_object_versioning"
@@ -4987,7 +4872,6 @@
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
"s3_account_level_public_access_blocks",
"s3_bucket_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured"
]
},
@@ -5015,7 +4899,6 @@
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
"s3_account_level_public_access_blocks",
"s3_bucket_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"ec2_confidential_workload_host_public_ip"
]
@@ -5078,7 +4961,6 @@
"s3_bucket_secure_transport_policy",
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
"ec2_networkacl_allow_ingress_any_port",
"ec2_confidential_workload_host_unrestricted_ingress"
]
},
@@ -5105,12 +4987,10 @@
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
"s3_account_level_public_access_blocks",
"s3_bucket_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port"
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22"
]
},
{
@@ -5138,7 +5018,6 @@
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
"s3_account_level_public_access_blocks",
"s3_bucket_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured"
]
},
@@ -5160,7 +5039,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"elbv2_logging_enabled",
"elb_logging_enabled",
@@ -5193,12 +5071,10 @@
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
"s3_account_level_public_access_blocks",
"s3_bucket_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port",
"ec2_confidential_workload_host_public_ip"
]
},
@@ -5230,8 +5106,7 @@
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port"
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22"
]
},
{
@@ -5262,8 +5137,7 @@
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port"
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22"
]
},
{
@@ -5290,7 +5164,6 @@
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
"s3_account_level_public_access_blocks",
"s3_bucket_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured"
]
},
@@ -5318,12 +5191,10 @@
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
"s3_account_level_public_access_blocks",
"s3_bucket_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port"
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22"
]
},
{
@@ -5351,12 +5222,10 @@
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
"s3_account_level_public_access_blocks",
"s3_bucket_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port"
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22"
]
},
{
@@ -5382,7 +5251,6 @@
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
"s3_account_level_public_access_blocks",
"s3_bucket_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
@@ -5412,7 +5280,6 @@
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
"s3_account_level_public_access_blocks",
"s3_bucket_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
@@ -5442,7 +5309,6 @@
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
"s3_account_level_public_access_blocks",
"s3_bucket_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
@@ -5472,7 +5338,6 @@
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
"s3_account_level_public_access_blocks",
"s3_bucket_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
@@ -5503,12 +5368,10 @@
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
"s3_account_level_public_access_blocks",
"s3_bucket_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port",
"ec2_confidential_workload_host_unrestricted_ingress"
]
},
@@ -5536,7 +5399,6 @@
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
"s3_account_level_public_access_blocks",
"s3_bucket_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured"
]
},
@@ -5564,12 +5426,10 @@
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
"s3_account_level_public_access_blocks",
"s3_bucket_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port"
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22"
]
},
{
@@ -5657,10 +5517,8 @@
"opensearch_service_domains_node_to_node_encryption_enabled",
"cloudwatch_log_group_kms_encryption_enabled",
"rds_instance_storage_encrypted",
"rds_instance_storage_encrypted",
"redshift_cluster_audit_logging",
"s3_bucket_default_encryption",
"s3_bucket_default_encryption",
"s3_bucket_secure_transport_policy",
"sagemaker_notebook_instance_encryption_enabled",
"sns_topics_kms_encryption_at_rest_enabled"
@@ -5690,10 +5548,8 @@
"opensearch_service_domains_node_to_node_encryption_enabled",
"cloudwatch_log_group_kms_encryption_enabled",
"rds_instance_storage_encrypted",
"rds_instance_storage_encrypted",
"redshift_cluster_audit_logging",
"s3_bucket_default_encryption",
"s3_bucket_default_encryption",
"s3_bucket_secure_transport_policy",
"sagemaker_notebook_instance_encryption_enabled",
"sns_topics_kms_encryption_at_rest_enabled"
@@ -5792,10 +5648,8 @@
"opensearch_service_domains_node_to_node_encryption_enabled",
"cloudwatch_log_group_kms_encryption_enabled",
"rds_instance_storage_encrypted",
"rds_instance_storage_encrypted",
"redshift_cluster_audit_logging",
"s3_bucket_default_encryption",
"s3_bucket_default_encryption",
"s3_bucket_secure_transport_policy",
"sagemaker_notebook_instance_encryption_enabled",
"sns_topics_kms_encryption_at_rest_enabled"
@@ -5879,7 +5733,6 @@
"iam_no_root_access_key",
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
@@ -5932,7 +5785,6 @@
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
"s3_account_level_public_access_blocks",
"s3_bucket_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured"
]
},
@@ -5957,10 +5809,8 @@
"opensearch_service_domains_encryption_at_rest_enabled",
"cloudwatch_log_group_kms_encryption_enabled",
"rds_instance_storage_encrypted",
"rds_instance_storage_encrypted",
"redshift_cluster_audit_logging",
"s3_bucket_default_encryption",
"s3_bucket_default_encryption",
"sagemaker_notebook_instance_encryption_enabled",
"sns_topics_kms_encryption_at_rest_enabled",
"kms_key_enclave_attestation_not_enforced",
@@ -6080,7 +5930,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"rds_instance_integration_cloudwatch_logs",
"redshift_cluster_audit_logging",
@@ -6189,7 +6038,6 @@
],
"Checks": [
"ec2_instance_managed_by_ssm",
"ssm_managed_compliant_patching",
"ssm_managed_compliant_patching"
]
},
@@ -6235,7 +6083,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"rds_instance_integration_cloudwatch_logs",
"redshift_cluster_audit_logging",
@@ -6419,7 +6266,6 @@
"Checks": [
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"guardduty_is_enabled",
@@ -6621,7 +6467,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"cloudwatch_log_group_retention_policy_specific_days_enabled",
"elbv2_logging_enabled",
@@ -6648,7 +6493,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"rds_instance_integration_cloudwatch_logs",
"redshift_cluster_audit_logging",
@@ -6823,7 +6667,6 @@
"cloudtrail_multi_region_enabled",
"apigateway_restapi_logging_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"elbv2_logging_enabled",
@@ -6868,7 +6711,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"rds_instance_integration_cloudwatch_logs",
"redshift_cluster_audit_logging",
@@ -6908,7 +6750,6 @@
"rds_instance_backup_enabled",
"rds_instance_deletion_protection",
"rds_instance_multi_az",
"rds_instance_backup_enabled",
"redshift_cluster_automated_snapshot",
"s3_bucket_object_versioning"
]
@@ -6934,10 +6775,8 @@
"opensearch_service_domains_encryption_at_rest_enabled",
"cloudwatch_log_group_kms_encryption_enabled",
"rds_instance_storage_encrypted",
"rds_instance_storage_encrypted",
"redshift_cluster_audit_logging",
"s3_bucket_default_encryption",
"s3_bucket_default_encryption",
"sagemaker_notebook_instance_encryption_enabled"
]
}
+6 -37
View File
@@ -20,7 +20,6 @@
"Checks": [
"apigateway_restapi_logging_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"elbv2_logging_enabled",
"elb_logging_enabled",
@@ -29,8 +28,7 @@
"ec2_securitygroup_default_restrict_traffic",
"vpc_flow_logs_enabled",
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port"
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22"
]
},
{
@@ -81,7 +79,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"elbv2_logging_enabled",
"elb_logging_enabled",
@@ -106,7 +103,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"elbv2_logging_enabled",
"elb_logging_enabled",
"guardduty_is_enabled",
@@ -165,7 +161,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"elbv2_logging_enabled",
"elb_logging_enabled",
"guardduty_is_enabled",
@@ -259,7 +254,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"guardduty_is_enabled",
"s3_bucket_server_access_logging_enabled",
"securityhub_enabled"
@@ -365,7 +359,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"guardduty_is_enabled",
"s3_bucket_server_access_logging_enabled",
"securityhub_enabled"
@@ -402,7 +395,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"elbv2_logging_enabled",
"elb_logging_enabled",
"guardduty_is_enabled",
@@ -537,7 +529,6 @@
"Checks": [
"apigateway_restapi_logging_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_multi_region_enabled",
"elbv2_logging_enabled",
"elb_logging_enabled",
"redshift_cluster_audit_logging",
@@ -838,7 +829,6 @@
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"awslambda_function_not_publicly_accessible",
"awslambda_function_url_public",
"rds_instance_no_public_access",
@@ -850,8 +840,7 @@
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port"
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22"
]
},
{
@@ -908,8 +897,7 @@
"sagemaker_notebook_instance_without_direct_internet_access_configured",
"ec2_securitygroup_default_restrict_traffic",
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port"
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22"
]
},
{
@@ -925,7 +913,6 @@
}
],
"Checks": [
"cloudtrail_multi_region_enabled",
"cloudtrail_multi_region_enabled",
"redshift_cluster_audit_logging",
"s3_bucket_server_access_logging_enabled"
@@ -946,7 +933,6 @@
"Checks": [
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access"
]
},
@@ -1047,7 +1033,6 @@
"cloudtrail_multi_region_enabled",
"cloudtrail_s3_dataevents_read_enabled",
"cloudtrail_s3_dataevents_write_enabled",
"cloudtrail_multi_region_enabled",
"ec2_ebs_public_snapshot",
"elbv2_logging_enabled",
"elb_logging_enabled",
@@ -1247,7 +1232,6 @@
"s3_bucket_public_access",
"s3_bucket_policy_public_write_access",
"s3_account_level_public_access_blocks",
"s3_bucket_public_access",
"sagemaker_notebook_instance_without_direct_internet_access_configured"
]
},
@@ -1265,13 +1249,10 @@
],
"Checks": [
"dynamodb_tables_pitr_enabled",
"dynamodb_tables_pitr_enabled",
"efs_have_backup_enabled",
"efs_have_backup_enabled",
"elbv2_deletion_protection",
"rds_instance_backup_enabled",
"rds_instance_multi_az",
"rds_instance_backup_enabled",
"redshift_cluster_automated_snapshot",
"s3_bucket_object_versioning"
]
@@ -1291,7 +1272,6 @@
"Checks": [
"config_recorder_all_regions_enabled",
"ec2_instance_managed_by_ssm",
"ssm_managed_compliant_patching",
"ssm_managed_compliant_patching"
],
"ConfigRequirements": [
@@ -1316,7 +1296,6 @@
}
],
"Checks": [
"cloudtrail_multi_region_enabled",
"cloudtrail_multi_region_enabled"
]
},
@@ -1335,7 +1314,6 @@
"Checks": [
"apigateway_restapi_logging_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"elbv2_logging_enabled",
"elb_logging_enabled",
@@ -1386,8 +1364,7 @@
"rds_instance_no_public_access",
"redshift_cluster_public_access",
"ec2_networkacl_allow_ingress_any_port",
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
"ec2_networkacl_allow_ingress_any_port"
"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22"
]
},
{
@@ -1410,12 +1387,12 @@
]
},
{
"Id": "rp_1",
"Id": "rc_rp_1",
"Name": "RC.RP-1",
"Description": "Recovery plan is executed during or after a cybersecurity incident.",
"Attributes": [
{
"ItemId": "rp_1",
"ItemId": "rc_rp_1",
"Section": "Recover (RC)",
"SubSection": "Recovery Planning (RC.RP)",
"Service": "aws"
@@ -1423,14 +1400,10 @@
],
"Checks": [
"dynamodb_tables_pitr_enabled",
"dynamodb_tables_pitr_enabled",
"efs_have_backup_enabled",
"efs_have_backup_enabled",
"elbv2_deletion_protection",
"rds_instance_backup_enabled",
"rds_instance_backup_enabled",
"rds_instance_multi_az",
"rds_instance_backup_enabled",
"redshift_cluster_automated_snapshot",
"s3_bucket_object_versioning"
]
@@ -1481,14 +1454,10 @@
],
"Checks": [
"dynamodb_tables_pitr_enabled",
"dynamodb_tables_pitr_enabled",
"efs_have_backup_enabled",
"efs_have_backup_enabled",
"elbv2_deletion_protection",
"rds_instance_backup_enabled",
"rds_instance_backup_enabled",
"rds_instance_multi_az",
"rds_instance_backup_enabled",
"redshift_cluster_automated_snapshot",
"s3_bucket_object_versioning"
]
+25 -34
View File
@@ -277,7 +277,7 @@
"Checks": [
"ec2_ebs_public_snapshot",
"rds_instance_no_public_access",
"eks_endpoints_not_publicly_accessible",
"eks_cluster_not_publicly_accessible",
"bedrock_vpc_endpoints_configured",
"vpc_endpoint_for_ec2_enabled",
"s3_account_level_public_access_blocks",
@@ -474,7 +474,7 @@
"s3_bucket_cross_region_replication",
"ec2_ebs_public_snapshot",
"rds_instance_no_public_access",
"eks_endpoints_not_publicly_accessible",
"eks_cluster_not_publicly_accessible",
"vpc_endpoint_for_ec2_enabled",
"s3_account_level_public_access_blocks",
"awslambda_function_not_publicly_accessible",
@@ -506,7 +506,7 @@
"Checks": [
"ec2_ebs_public_snapshot",
"rds_instance_no_public_access",
"eks_endpoints_not_publicly_accessible",
"eks_cluster_not_publicly_accessible",
"vpc_endpoint_for_ec2_enabled",
"s3_account_level_public_access_blocks",
"awslambda_function_not_publicly_accessible",
@@ -742,7 +742,7 @@
"elbv2_logging_enabled",
"apigateway_restapi_logging_enabled",
"cloudtrail_multi_region_enabled",
"wafv2_web_acl_logging_enabled",
"wafv2_webacl_logging_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"s3_bucket_lifecycle_enabled"
],
@@ -763,7 +763,7 @@
"elbv2_logging_enabled",
"apigateway_restapi_logging_enabled",
"cloudtrail_multi_region_enabled",
"wafv2_web_acl_logging_enabled",
"wafv2_webacl_logging_enabled",
"cloudtrail_cloudwatch_logging_enabled"
],
"Attributes": [
@@ -794,7 +794,7 @@
"Name": "Render PAN unreadable anywhere it is stored (including on portable digital media, backup media, and in logs) by using approaches like one-way hashes based on strong cryptography, truncation etc",
"Description": "The following approaches should be used to render PAN unreadable anywhere it is stored: One-way hashes based on strong cryptography, (hash must be of the entire PAN), truncation (hashing cannot be used to replace the truncated segment of PAN), index tokens and pads (pads must be securely stored) and strong cryptography with associated key-management processes and procedures. Note: It is a relatively trivial effort for a malicious individual to reconstruct original PAN data if they have access to both the truncated and hashed version of a PAN. Where hashed and truncated versions of the same PAN are present in an entity's environment, additional controls must be in place to ensure that the hashed and truncated versions cannot be correlated to reconstruct the original PAN. PANs stored in primary storage (databases, or flat files such as text files spreadsheets) as well as non-primary storage (backup, audit logs, exception or troubleshooting logs) must all be protected. One-way hash functions based on strong cryptography can be used to render cardholder data unreadable. Hash functions are appropriate when there is no need to retrieve the original number (one-way hashes are irreversible). It is recommended, but not currently a requirement, that an additional, random input value be added to the cardholder data prior to hashing to reduce the feasibility of an attacker comparing the data against (and deriving the PAN from) tables of pre- computed hash values. The intent of truncation is to permanently remove a segment of PAN data so that only a portion (generally not to exceed the first six and last four digits) of the PAN is stored. An index token is a cryptographic token that replaces the PAN based on a given index for an unpredictable value. A one-time pad is a system in which a randomly generated private key is used only once to encrypt a message that is then decrypted using a matching one-time pad and key. The intent of strong cryptography (as defined in the PCI DSS and PA-DSS Glossary of Terms, Abbreviations, and Acronyms) is that the encryption be based on an industry-tested and accepted algorithm (not a proprietary or `home- grown` algorithm) with strong cryptographic keys. By correlating hashed and truncated versions of a given PAN, a malicious individual may easily derive the original PAN value. Controls that prevent the correlation of this data will help ensure that the original PAN remains unreadable.",
"Checks": [
"dynamodb_table_encryption_enabled",
"dynamodb_tables_kms_cmk_encryption_enabled",
"cloudtrail_kms_encryption_enabled",
"sagemaker_notebook_instance_encryption_enabled",
"cloudwatch_log_group_kms_encryption_enabled",
@@ -807,7 +807,6 @@
"opensearch_service_domains_encryption_at_rest_enabled",
"sns_topics_kms_encryption_at_rest_enabled",
"dynamodb_accelerator_cluster_encryption_enabled",
"dynamodb_tables_kms_cmk_encryption_enabled",
"ec2_ebs_volume_encryption",
"rds_instance_storage_encrypted",
"redshift_cluster_audit_logging",
@@ -816,7 +815,7 @@
"elbv2_logging_enabled",
"apigateway_restapi_logging_enabled",
"cloudtrail_multi_region_enabled",
"wafv2_web_acl_logging_enabled",
"wafv2_webacl_logging_enabled",
"cloudtrail_cloudwatch_logging_enabled"
],
"Attributes": [
@@ -832,7 +831,7 @@
"Name": "If disk encryption is used (rather than file- or column-level database encryption), logical access must be managed separately and independently of native operating system authentication and access control mechanisms (for example, by not using local user account databases or general network login credentials)",
"Description": "Decryption keys must not be associated with user accounts. Note: This requirement applies in addition to all other PCI DSS encryption and key- management requirements. PANs stored in primary storage (databases, or flat files such as text files spreadsheets) as well as non-primary storage (backup, audit logs, exception or troubleshooting logs) must all be protected. One-way hash functions based on strong cryptography can be used to render cardholder data unreadable. Hash functions are appropriate when there is no need to retrieve the original number (one-way hashes are irreversible). It is recommended, but not currently a requirement, that an additional, random input value be added to the cardholder data prior to hashing to reduce the feasibility of an attacker comparing the data against (and deriving the PAN from) tables of pre- computed hash values. The intent of truncation is to permanently remove a segment of PAN data so that only a portion (generally not to exceed the first six and last four digits) of the PAN is stored. An index token is a cryptographic token that replaces the PAN based on a given index for an unpredictable value. A one-time pad is a system in which a randomly generated private key is used only once to encrypt a message that is then decrypted using a matching one-time pad and key. The intent of strong cryptography (as defined in the PCI DSS and PA-DSS Glossary of Terms, Abbreviations, and Acronyms) is that the encryption be based on an industry-tested and accepted algorithm (not a proprietary or `home-grown` algorithm) with strong cryptographic keys. By correlating hashed and truncated versions of a given PAN, a malicious individual may easily derive the original PAN value. Controls that prevent the correlation of this data will help ensure that the original PAN remains unreadable.",
"Checks": [
"dynamodb_table_encryption_enabled",
"dynamodb_tables_kms_cmk_encryption_enabled",
"cloudtrail_kms_encryption_enabled",
"sagemaker_notebook_instance_encryption_enabled",
"cloudwatch_log_group_kms_encryption_enabled",
@@ -845,7 +844,6 @@
"opensearch_service_domains_encryption_at_rest_enabled",
"sns_topics_kms_encryption_at_rest_enabled",
"dynamodb_accelerator_cluster_encryption_enabled",
"dynamodb_tables_kms_cmk_encryption_enabled",
"ec2_ebs_volume_encryption",
"rds_instance_storage_encrypted",
"redshift_cluster_audit_logging"
@@ -863,7 +861,7 @@
"Name": "If disk encryption is used, inspect the configuration and observe the authentication process to verify that logical access to encrypted file systems is implemented via a mechanism that is separate from the native operating system's authentication mechanism (for example, not using local user account databases or general network login credentials)",
"Description": "The intent of this requirement is to address the acceptability of disk-level encryption for rendering cardholder data unreadable. Disk-level encryption encrypts the entire disk/partition on a computer and automatically decrypts the information when an authorized user requests it. Many disk- encryption solutions intercept operating system read/write operations and carry out the appropriate cryptographic transformations without any special action by the user other than supplying a password or pass phrase upon system startup or at the beginning of a session. Based on these characteristics of disk-level encryption, to be compliant with this requirement, the method cannot: 1) Use the same user account authenticator as the operating system, or 2) Use a decryption key that is associated with or derived from the system's local user account database or general network login credentials. Full disk encryption helps to protect data in the event of physical loss of a disk and therefore may be appropriate for portable devices that store cardholder data.",
"Checks": [
"dynamodb_table_encryption_enabled",
"dynamodb_tables_kms_cmk_encryption_enabled",
"cloudtrail_kms_encryption_enabled",
"sagemaker_notebook_instance_encryption_enabled",
"cloudwatch_log_group_kms_encryption_enabled",
@@ -876,7 +874,6 @@
"opensearch_service_domains_encryption_at_rest_enabled",
"sns_topics_kms_encryption_at_rest_enabled",
"dynamodb_accelerator_cluster_encryption_enabled",
"dynamodb_tables_kms_cmk_encryption_enabled",
"ec2_ebs_volume_encryption",
"rds_instance_storage_encrypted",
"redshift_cluster_audit_logging"
@@ -894,7 +891,7 @@
"Name": "Examine the configurations and observe the processes to verify that cardholder data on removable media is encrypted wherever stored",
"Description": "Note: If disk encryption is not used to encrypt removable media, the data stored on this media will need to be rendered unreadable through some other method. The intent of this requirement is to address the acceptability of disk-level encryption for rendering cardholder data unreadable. Disk-level encryption encrypts the entire disk/partition on a computer and automatically decrypts the information when an authorized user requests it. Many disk- encryption solutions intercept operating system read/write operations and carry out the appropriate cryptographic transformations without any special action by the user other than supplying a password or pass phrase upon system startup or at the beginning of a session. Based on these characteristics of disk-level encryption, to be compliant with this requirement, the method cannot: 1) Use the same user account authenticator as the operating system, or 2) Use a decryption key that is associated with or derived from the system's local user account database or general network login credentials. Full disk encryption helps to protect data in the event of physical loss of a disk and therefore may be appropriate for portable devices that store cardholder data.",
"Checks": [
"dynamodb_table_encryption_enabled",
"dynamodb_tables_kms_cmk_encryption_enabled",
"cloudtrail_kms_encryption_enabled",
"sagemaker_notebook_instance_encryption_enabled",
"cloudwatch_log_group_kms_encryption_enabled",
@@ -907,7 +904,6 @@
"opensearch_service_domains_encryption_at_rest_enabled",
"sns_topics_kms_encryption_at_rest_enabled",
"dynamodb_accelerator_cluster_encryption_enabled",
"dynamodb_tables_kms_cmk_encryption_enabled",
"ec2_ebs_volume_encryption",
"rds_instance_storage_encrypted",
"redshift_cluster_audit_logging"
@@ -925,7 +921,7 @@
"Name": "Examine documentation about the system used to protect the PAN, including the vendor, type of system/process, and the encryption algorithms (if applicable) to verify that the PAN is rendered unreadable using methods like truncation,one-way hashes based on strong cryptography etc",
"Description": "Verify documentation about the system used to protect the PAN, including the vendor, type of system/process, and the encryption algorithms (if applicable) to verify that the PAN is rendered unreadable using any of the following methods: One-way hashes based on strong cryptography, truncation, index tokens and pads with the pads being securely stored, strong cryptography, with associated key-management processes and procedures. PANs stored in primary storage (databases, or flat files such as text files spreadsheets) as well as non-primary storage (backup, audit logs, exception or troubleshooting logs) must all be protected. One-way hash functions based on strong cryptography can be used to render cardholder data unreadable. Hash functions are appropriate when there is no need to retrieve the original number (one-way hashes are irreversible). It is recommended, but not currently a requirement, that an additional, random input value be added to the cardholder data prior to hashing to reduce the feasibility of an attacker comparing the data against (and deriving the PAN from) tables of pre- computed hash values. The intent of truncation is to permanently remove a segment of PAN data so that only a portion (generally not to exceed the first six and last four digits) of the PAN is stored. An index token is a cryptographic token that replaces the PAN based on a given index for an unpredictable value. A one-time pad is a system in which a randomly generated private key is used only once to encrypt a message that is then decrypted using a matching one-time pad and key. The intent of strong cryptography (as defined in the PCI DSS and PA-DSS Glossary of Terms, Abbreviations, and Acronyms) is that the encryption be based on an industry-tested and accepted algorithm (not a proprietary or `home-grown` algorithm) with strong cryptographic keys. By correlating hashed and truncated versions of a given PAN, a malicious individual may easily derive the original PAN value. Controls that prevent the correlation of this data will help ensure that the original PAN remains unreadable.",
"Checks": [
"dynamodb_table_encryption_enabled",
"dynamodb_tables_kms_cmk_encryption_enabled",
"cloudtrail_kms_encryption_enabled",
"sagemaker_notebook_instance_encryption_enabled",
"cloudwatch_log_group_kms_encryption_enabled",
@@ -933,7 +929,6 @@
"opensearch_service_domains_audit_logging_enabled",
"eks_cluster_kms_cmk_encryption_in_secrets_enabled",
"rds_snapshots_encrypted",
"dynamodb_tables_kms_cmk_encryption_enabled",
"s3_bucket_default_encryption",
"efs_encryption_at_rest_enabled",
"ec2_ebs_default_encryption",
@@ -957,7 +952,7 @@
"Name": "Examine several tables or files from a sample of data repositories to verify the PAN is rendered unreadable (that is, not stored in plain-text)",
"Description": "PANs stored in primary storage (databases, or flat files such as text files spreadsheets) as well as non-primary storage (backup, audit logs, exception or troubleshooting logs) must all be protected. One-way hash functions based on strong cryptography can be used to render cardholder data unreadable. Hash functions are appropriate when there is no need to retrieve the original number (one-way hashes are irreversible). It is recommended, but not currently a requirement, that an additional, random input value be added to the cardholder data prior to hashing to reduce the feasibility of an attacker comparing the data against (and deriving the PAN from) tables of pre- computed hash values. The intent of truncation is to permanently remove a segment of PAN data so that only a portion (generally not to exceed the first six and last four digits) of the PAN is stored. An index token is a cryptographic token that replaces the PAN based on a given index for an unpredictable value. A one-time pad is a system in which a randomly generated private key is used only once to encrypt a message that is then decrypted using a matching one-time pad and key. The intent of strong cryptography (as defined in the PCI DSS and PA-DSS Glossary of Terms, Abbreviations, and Acronyms) is that the encryption be based on an industry-tested and accepted algorithm (not a proprietary or `home- grown` algorithm) with strong cryptographic keys. By correlating hashed and truncated versions of a given PAN, a malicious individual may easily derive the original PAN value. Controls that prevent the correlation of this data will help ensure that the original PAN remains unreadable.",
"Checks": [
"dynamodb_table_encryption_enabled",
"dynamodb_tables_kms_cmk_encryption_enabled",
"cloudtrail_kms_encryption_enabled",
"sagemaker_notebook_instance_encryption_enabled",
"cloudwatch_log_group_kms_encryption_enabled",
@@ -965,7 +960,6 @@
"opensearch_service_domains_audit_logging_enabled",
"eks_cluster_kms_cmk_encryption_in_secrets_enabled",
"rds_snapshots_encrypted",
"dynamodb_tables_kms_cmk_encryption_enabled",
"s3_bucket_default_encryption",
"efs_encryption_at_rest_enabled",
"ec2_ebs_default_encryption",
@@ -997,7 +991,7 @@
"apigateway_restapi_logging_enabled",
"s3_bucket_default_encryption",
"cloudtrail_multi_region_enabled",
"wafv2_web_acl_logging_enabled",
"wafv2_webacl_logging_enabled",
"cloudtrail_cloudwatch_logging_enabled"
],
"Attributes": [
@@ -1084,7 +1078,7 @@
"Description": "Following should be used to safeguard sensitive cardholder data during transmission over open, public networks: only trusted keys and certificates are accepted, the protocol in use only supports secure versions or configurations and the encryption strength is appropriate for the encryption methodology in use. Examples of open, public networks include but are not limited to the Internet, wireless technologies, including 802.11 and Bluetooth, cellular technologies, for example, Global System for Mobile communications (GSM), Code division multiple access (CDMA), general Packet Radio Service (GPRS) and satellite communications. Sensitive information must be encrypted during transmission over public networks, because it is easy and common for a malicious individual to intercept and/or divert data while in transit. Secure transmission of cardholder data requires using trusted keys/certificates, a secure protocol for transport, and proper encryption strength to encrypt cardholder data. Connection requests from systems that do not support the required encryption strength, and that would result in an insecure connection, should not be accepted. Note that some protocol implementations (such as SSL, SSH v1.0, and early TLS) have known vulnerabilities that an attacker can use to gain control of the affected system. Whichever security protocol is used, ensure it is configured to use only secure versions and configurations to prevent use of an insecure connection—for example, by using only trusted certificates and supporting only strong encryption (not supporting weaker, insecure protocols or methods). Verifying that certificates are trusted (for example, have not expired and are issued from a trusted source) helps ensure the integrity of the secure connection. Generally, the web page URL should begin with `HTTPS` and/or the web browser display a padlock icon somewhere in the window of the browser. Many TLS certificate vendors also provide a highly visible verification seal— sometimes referred to as a “security seal,” `secure site seal,` or “secure trust seal”)—which may provide the ability to click on the seal to reveal information about the website. Refer to industry standards and best practices for information on strong cryptography and secure protocols (e.g., NIST SP 800-52 and SP 800-57, OWASP, etc.) Note: SSL/early TLS is not considered strong cryptography and may not be used as a security control, except by POS POI terminals that are verified as not being susceptible to known exploits and the termination points to which they connect as defined in Appendix A2.",
"Checks": [
"acm_certificates_expiration_check",
"s3_bucket_enforces_ssl",
"s3_bucket_secure_transport_policy",
"elbv2_ssl_listeners",
"opensearch_service_domains_node_to_node_encryption_enabled",
"elb_ssl_listeners",
@@ -1110,7 +1104,7 @@
"cloudfront_distributions_using_deprecated_ssl_protocols",
"acm_certificates_expiration_check",
"cloudfront_distributions_origin_traffic_encrypted",
"s3_bucket_enforces_ssl",
"s3_bucket_secure_transport_policy",
"elbv2_ssl_listeners",
"opensearch_service_domains_node_to_node_encryption_enabled",
"elb_ssl_listeners"
@@ -1178,7 +1172,7 @@
"cloudfront_distributions_using_deprecated_ssl_protocols",
"acm_certificates_expiration_check",
"cloudfront_distributions_origin_traffic_encrypted",
"s3_bucket_enforces_ssl",
"s3_bucket_secure_transport_policy",
"elbv2_ssl_listeners",
"opensearch_service_domains_node_to_node_encryption_enabled",
"elb_ssl_listeners"
@@ -1497,7 +1491,7 @@
"Checks": [
"ec2_ebs_public_snapshot",
"rds_instance_no_public_access",
"eks_endpoints_not_publicly_accessible",
"eks_cluster_not_publicly_accessible",
"s3_account_level_public_access_blocks",
"awslambda_function_not_publicly_accessible",
"emr_cluster_master_nodes_no_public_ip",
@@ -1528,7 +1522,7 @@
"Checks": [
"ec2_ebs_public_snapshot",
"rds_instance_no_public_access",
"eks_endpoints_not_publicly_accessible",
"eks_cluster_not_publicly_accessible",
"s3_account_level_public_access_blocks",
"awslambda_function_not_publicly_accessible",
"emr_cluster_master_nodes_no_public_ip",
@@ -1637,7 +1631,7 @@
"iam_password_policy_reuse_24",
"codebuild_project_no_secrets_in_variables",
"codebuild_project_source_repo_url_no_sensitive_credentials",
"s3_bucket_enforces_ssl",
"s3_bucket_secure_transport_policy",
"elbv2_ssl_listeners",
"opensearch_service_domains_node_to_node_encryption_enabled",
"elb_ssl_listeners",
@@ -1652,11 +1646,10 @@
"eks_cluster_kms_cmk_encryption_in_secrets_enabled",
"rds_snapshots_encrypted",
"dynamodb_accelerator_cluster_encryption_enabled",
"dynamodb_table_encryption_enabled",
"dynamodb_tables_kms_cmk_encryption_enabled",
"cloudtrail_kms_encryption_enabled",
"cloudwatch_log_group_kms_encryption_enabled",
"sns_topics_kms_encryption_at_rest_enabled",
"dynamodb_tables_kms_cmk_encryption_enabled",
"redshift_cluster_audit_logging"
],
"Attributes": [
@@ -1674,7 +1667,7 @@
"Checks": [
"codebuild_project_no_secrets_in_variables",
"codebuild_project_source_repo_url_no_sensitive_credentials",
"s3_bucket_enforces_ssl",
"s3_bucket_secure_transport_policy",
"elbv2_ssl_listeners",
"opensearch_service_domains_node_to_node_encryption_enabled",
"elb_ssl_listeners",
@@ -1689,11 +1682,10 @@
"eks_cluster_kms_cmk_encryption_in_secrets_enabled",
"rds_snapshots_encrypted",
"dynamodb_accelerator_cluster_encryption_enabled",
"dynamodb_table_encryption_enabled",
"dynamodb_tables_kms_cmk_encryption_enabled",
"cloudtrail_kms_encryption_enabled",
"cloudwatch_log_group_kms_encryption_enabled",
"sns_topics_kms_encryption_at_rest_enabled",
"dynamodb_tables_kms_cmk_encryption_enabled",
"redshift_cluster_audit_logging"
],
"Attributes": [
@@ -1723,12 +1715,11 @@
"eks_cluster_kms_cmk_encryption_in_secrets_enabled",
"rds_snapshots_encrypted",
"dynamodb_accelerator_cluster_encryption_enabled",
"dynamodb_table_encryption_enabled",
"dynamodb_tables_kms_cmk_encryption_enabled",
"cloudtrail_kms_encryption_enabled",
"cloudwatch_log_group_kms_encryption_enabled",
"s3_bucket_enforces_ssl",
"s3_bucket_secure_transport_policy",
"sns_topics_kms_encryption_at_rest_enabled",
"dynamodb_tables_kms_cmk_encryption_enabled",
"redshift_cluster_audit_logging"
],
"Attributes": [
@@ -2118,7 +2109,7 @@
"cloudwatch_log_group_retention_policy_specific_days_enabled",
"apigateway_restapi_logging_enabled",
"cloudtrail_multi_region_enabled",
"wafv2_web_acl_logging_enabled",
"wafv2_webacl_logging_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"vpc_flow_logs_enabled",
"redshift_cluster_audit_logging"
@@ -109,9 +109,7 @@
"guardduty_no_high_severity_findings",
"rds_instance_minor_version_upgrade_enabled",
"redshift_cluster_automatic_upgrades",
"ssm_managed_compliant_patching",
"ssm_managed_compliant_patching",
"rds_instance_minor_version_upgrade_enabled"
"ssm_managed_compliant_patching"
]
},
{
-2
View File
@@ -643,8 +643,6 @@
"ec2_client_vpn_endpoint_connection_logging_enabled",
"ecs_task_definitions_logging_enabled",
"elasticbeanstalk_environment_cloudwatch_logging_enabled",
"elb_logging_enabled",
"elbv2_logging_enabled",
"glue_etl_jobs_logging_enabled",
"mq_broker_logging_enabled",
"networkfirewall_logging_enabled",
+4 -17
View File
@@ -3157,8 +3157,6 @@
"app_http_logs_enabled",
"defender_auto_provisioning_log_analytics_agent_vms_on",
"keyvault_logging_enabled",
"monitor_storage_account_with_activity_logs_cmk_encrypted",
"monitor_storage_account_with_activity_logs_is_private",
"mysql_flexible_server_audit_log_connection_activated",
"mysql_flexible_server_audit_log_enabled",
"network_flow_log_captured_sent",
@@ -5780,13 +5778,11 @@
"sqlserver_tde_encrypted_with_cmk",
"sqlserver_tde_encryption_enabled",
"vm_ensure_unattached_disks_encrypted_with_cmk",
"entra_conditional_access_policy_require_mfa_for_management_app",
"entra_conditional_access_policy_require_mfa_for_management_api",
"app_minimum_tls_version_12",
"mysql_flexible_server_minimum_tls_version_12",
"sqlserver_recommended_minimal_tls_version",
"storage_ensure_minimum_tls_version_12",
"sqlserver_tde_encrypted_with_cmk",
"sqlserver_tde_encryption_enabled"
"storage_ensure_minimum_tls_version_12"
],
"ConfigRequirements": [
{
@@ -5818,13 +5814,11 @@
"sqlserver_tde_encrypted_with_cmk",
"sqlserver_tde_encryption_enabled",
"vm_ensure_unattached_disks_encrypted_with_cmk",
"entra_conditional_access_policy_require_mfa_for_management_app",
"entra_conditional_access_policy_require_mfa_for_management_api",
"app_minimum_tls_version_12",
"mysql_flexible_server_minimum_tls_version_12",
"sqlserver_recommended_minimal_tls_version",
"storage_ensure_minimum_tls_version_12",
"sqlserver_tde_encrypted_with_cmk",
"sqlserver_tde_encryption_enabled"
"storage_ensure_minimum_tls_version_12"
],
"ConfigRequirements": [
{
@@ -6577,7 +6571,6 @@
"sqlserver_tde_encryption_enabled",
"app_minimum_tls_version_12",
"mysql_flexible_server_minimum_tls_version_12",
"sqlserver_recommended_minimal_tls_version",
"storage_ensure_minimum_tls_version_12"
],
"ConfigRequirements": [
@@ -7077,7 +7070,6 @@
"app_http_logs_enabled",
"defender_auto_provisioning_log_analytics_agent_vms_on",
"keyvault_logging_enabled",
"monitor_storage_account_with_activity_logs_cmk_encrypted",
"monitor_storage_account_with_activity_logs_is_private",
"mysql_flexible_server_audit_log_connection_activated",
"mysql_flexible_server_audit_log_enabled",
@@ -7920,8 +7912,6 @@
"app_http_logs_enabled",
"defender_auto_provisioning_log_analytics_agent_vms_on",
"keyvault_logging_enabled",
"monitor_storage_account_with_activity_logs_cmk_encrypted",
"monitor_storage_account_with_activity_logs_is_private",
"mysql_flexible_server_audit_log_connection_activated",
"mysql_flexible_server_audit_log_enabled",
"network_flow_log_captured_sent",
@@ -7953,8 +7943,6 @@
"app_http_logs_enabled",
"defender_auto_provisioning_log_analytics_agent_vms_on",
"keyvault_logging_enabled",
"monitor_storage_account_with_activity_logs_cmk_encrypted",
"monitor_storage_account_with_activity_logs_is_private",
"mysql_flexible_server_audit_log_connection_activated",
"mysql_flexible_server_audit_log_enabled",
"network_flow_log_captured_sent",
@@ -8991,7 +8979,6 @@
"app_http_logs_enabled",
"defender_auto_provisioning_log_analytics_agent_vms_on",
"keyvault_logging_enabled",
"monitor_storage_account_with_activity_logs_cmk_encrypted",
"mysql_flexible_server_audit_log_connection_activated",
"mysql_flexible_server_audit_log_enabled",
"network_flow_log_captured_sent",
@@ -642,7 +642,7 @@
}
],
"Checks": [
" app_http_logs_enabled"
"app_http_logs_enabled"
]
},
{
@@ -1185,7 +1185,7 @@
]
},
{
"Id": "op.mon.3.az.nw.1",
"Id": "op.mon.3.az.nw.2",
"Description": "Vigilancia",
"Attributes": [
{
@@ -17,26 +17,18 @@
}
],
"Checks": [
"monitor_activity_log_alert_cmk_delete",
"monitor_activity_log_alert_create_policy_assignment",
"monitor_activity_log_alert_create_update_delete_network_sg",
"monitor_activity_log_alert_create_update_delete_network_sg_rule",
"monitor_activity_log_alert_create_update_delete_sql_server_fw_rule",
"monitor_activity_log_alert_create_update_nsg",
"monitor_activity_log_alert_create_update_public_ip_address",
"monitor_activity_log_alert_create_update_security_solution",
"monitor_activity_log_alert_delete_nsg",
"monitor_activity_log_alert_delete_policy_assignment",
"monitor_activity_log_alert_delete_public_ip_address",
"monitor_activity_log_alert_delete_security_solution",
"monitor_log_profile_all_categories",
"monitor_log_profile_all_regions",
"vm_agent_installed",
"vm_antimalware_solution_installed",
"vm_endpoint_protection_installed",
"vm_guest_configuration_installed",
"vm_guest_configuration_with_no_managed_identity",
"vm_guest_configuration_with_user_identity"
"monitor_alert_create_policy_assignment",
"monitor_alert_create_update_sqlserver_fr",
"monitor_alert_delete_sqlserver_fr",
"monitor_alert_create_update_nsg",
"monitor_alert_create_update_public_ip_address_rule",
"monitor_alert_create_update_security_solution",
"monitor_alert_delete_nsg",
"monitor_alert_delete_policy_assignment",
"monitor_alert_delete_public_ip_address_rule",
"monitor_alert_delete_security_solution",
"monitor_diagnostic_setting_with_appropriate_categories",
"defender_assessments_vm_endpoint_protection_installed"
]
},
{
@@ -64,17 +56,11 @@
"keyvault_access_only_through_private_endpoints",
"keyvault_private_endpoints",
"network_bastion_host_exists",
"network_flow_logs_enabled",
"network_security_group_not_empty",
"network_sg_ssh_access_restricted",
"network_sg_rdp_access_restricted",
"network_sg_open_all_ports_to_any_source",
"network_flow_log_captured_sent",
"network_ssh_internet_access_restricted",
"network_rdp_internet_access_restricted",
"network_watcher_enabled",
"postgresql_flexible_server_public_network_access_disabled",
"sqlserver_public_network_access_disabled",
"storage_default_network_access_rule_set_to_deny",
"vm_availability_zones_enabled",
"vm_availability_set_deployed"
"storage_default_network_access_rule_is_denied"
]
},
{
@@ -111,8 +97,7 @@
"app_function_identity_is_configured",
"app_function_identity_without_admin_privileges",
"app_ensure_auth_is_set_up",
"app_register_with_identity",
"vm_managed_identity_enabled"
"app_register_with_identity"
]
},
{
@@ -167,24 +152,16 @@
"defender_auto_provisioning_log_analytics_agent_vms_on",
"defender_auto_provisioning_vulnerabilty_assessments_machines_on",
"keyvault_logging_enabled",
"monitor_activity_log_retention_policy_set",
"monitor_diagnostic_logs_categories",
"monitor_diagnostic_setting_deployed_for_all_resources",
"monitor_diagnostic_settings_captures_proper_categories",
"monitor_log_profile_all_categories",
"monitor_log_profile_all_regions",
"monitor_log_profile_captures_all_activities",
"monitor_log_profile_retention_policy_at_least_365",
"network_flow_logs_enabled",
"network_flow_log_retention_policy_at_least_90",
"monitor_diagnostic_setting_with_appropriate_categories",
"monitor_diagnostic_settings_exists",
"network_flow_log_captured_sent",
"network_flow_log_more_than_90_days",
"network_watcher_enabled",
"postgresql_flexible_server_audit_logs_enabled",
"postgresql_flexible_server_log_checkpoints_enabled",
"postgresql_flexible_server_log_connections_enabled",
"postgresql_flexible_server_log_disconnections_enabled",
"sqlserver_auditing_on",
"sqlserver_auditing_retention_90_days",
"storage_storage_account_logging_queue_read_write_delete_enabled"
"postgresql_flexible_server_log_checkpoints_on",
"postgresql_flexible_server_log_connections_on",
"postgresql_flexible_server_log_disconnections_on",
"sqlserver_auditing_enabled",
"sqlserver_auditing_retention_90_days"
]
},
{
@@ -199,21 +176,13 @@
}
],
"Checks": [
"policy_ensure_asc_for_aks_is_enabled",
"policy_ensure_asc_for_app_services_is_enabled",
"policy_ensure_asc_for_azure_sql_is_enabled",
"policy_ensure_asc_for_key_vault_is_enabled",
"policy_ensure_asc_for_servers_is_enabled",
"policy_ensure_asc_for_sql_servers_is_enabled",
"policy_ensure_asc_for_storage_is_enabled",
"policy_ensure_allowed_extensions_are_installed",
"policy_ensure_allowed_locations_is_enabled",
"policy_ensure_allowed_resource_types_is_enabled",
"policy_ensure_audit_diagnostic_log_enabled_for_all_services",
"policy_ensure_not_allowed_resource_types_is_enabled",
"vm_guest_configuration_installed",
"vm_guest_configuration_with_no_managed_identity",
"vm_guest_configuration_with_user_identity"
"defender_ensure_defender_for_containers_is_on",
"defender_ensure_defender_for_app_services_is_on",
"defender_ensure_defender_for_azure_sql_databases_is_on",
"defender_ensure_defender_for_keyvault_is_on",
"defender_ensure_defender_for_server_is_on",
"defender_ensure_defender_for_sql_servers_is_on",
"defender_ensure_defender_for_storage_is_on"
]
},
{
@@ -229,18 +198,10 @@
],
"Checks": [
"mysql_flexible_server_geo_redundant_backup_enabled",
"mysql_flexible_server_retain_backup_35_days",
"postgresql_flexible_server_geo_redundant_backup_enabled",
"postgresql_flexible_server_backup_retention_period_35_days",
"recovery_services_vault_uses_private_link",
"recovery_services_vault_uses_private_link_for_backup",
"sqlserver_database_long_term_geo_redundant_backup",
"sqlserver_database_retention_policy_exceeds_90_days",
"storage_default_storage_account_encrypted_with_cmk_not_stored_in_storage_account",
"storage_geo_redundant_enabled",
"storage_infrastructure_encryption_is_enabled",
"storage_soft_delete_containers_enabled",
"storage_soft_delete_enabled",
"storage_ensure_soft_delete_is_enabled",
"vm_backup_enabled",
"vm_sufficient_daily_backup_retention_period"
]
@@ -266,26 +227,18 @@
"keyvault_key_expiration_set_in_non_rbac",
"keyvault_key_rotation_enabled",
"keyvault_non_rbac_secret_expiration_set",
"mysql_flexible_server_encrypted_at_rest_using_cmk",
"mysql_flexible_server_encrypted_in_transit",
"mysql_flexible_server_minimum_tls_version_tls12",
"postgresql_flexible_server_encrypted_at_rest_using_cmk",
"postgresql_flexible_server_encrypted_in_transit",
"postgresql_flexible_server_minimum_tls_version_tls12",
"sqlserver_advanced_data_security_enabled",
"sqlserver_database_encryption_with_cmk",
"sqlserver_database_tde_encryption_enabled",
"sqlserver_minimum_tls_version_12",
"storage_secure_transfer_required_enabled",
"storage_default_storage_account_encrypted_with_cmk",
"mysql_flexible_server_ssl_connection_enabled",
"mysql_flexible_server_minimum_tls_version_12",
"postgresql_flexible_server_enforce_ssl_enabled",
"defender_ensure_defender_for_sql_servers_is_on",
"sqlserver_tde_encrypted_with_cmk",
"sqlserver_tde_encryption_enabled",
"sqlserver_recommended_minimal_tls_version",
"storage_secure_transfer_required_is_enabled",
"storage_ensure_encryption_with_customer_managed_keys",
"storage_infrastructure_encryption_is_enabled",
"storage_storage_account_encrypted_with_cmk",
"storage_storage_account_minimum_tls_version_tls12",
"vm_encrypted_at_host",
"vm_data_disks_encrypted_with_cmk",
"vm_managed_disks_encrypted_with_cmk",
"vm_os_disk_are_encrypted_with_cmk",
"vm_temporary_disks_and_cache_encrypted"
"storage_ensure_minimum_tls_version_12",
"vm_ensure_attached_disks_encrypted_with_cmk"
]
},
{
@@ -307,11 +260,7 @@
"defender_container_images_resolved_vulnerabilities",
"defender_container_images_scan_enabled",
"defender_ensure_system_updates_are_applied",
"vm_agent_installed",
"vm_antimalware_solution_installed",
"vm_endpoint_protection_installed",
"vm_os_update_system_updates",
"vm_security_patch_assessment"
"defender_assessments_vm_endpoint_protection_installed"
]
},
{
@@ -332,8 +281,7 @@
"entra_user_with_vm_access_has_mfa",
"iam_custom_role_has_permissions_to_administer_resource_locks",
"iam_role_user_access_admin_restricted",
"app_function_identity_is_configured",
"vm_managed_identity_enabled"
"app_function_identity_is_configured"
]
},
{
@@ -348,10 +296,8 @@
}
],
"Checks": [
"monitor_log_profile_all_categories",
"monitor_log_profile_all_regions",
"monitor_log_profile_captures_all_activities",
"monitor_diagnostic_setting_deployed_for_all_resources",
"monitor_diagnostic_setting_with_appropriate_categories",
"monitor_diagnostic_settings_exists",
"network_watcher_enabled"
]
}
@@ -1056,7 +1056,9 @@
"entra_policy_guest_invite_only_for_admin_roles",
"entra_policy_guest_users_access_restrictions",
"entra_policy_restricts_user_consent_for_apps",
"entra_policy_user_consent_for_verified_apps storage_blob_public_access_level_is_disabled storage_ensure_azure_services_are_trusted_to_access_is_enabled"
"entra_policy_user_consent_for_verified_apps",
"storage_blob_public_access_level_is_disabled",
"storage_ensure_azure_services_are_trusted_to_access_is_enabled"
]
},
{
@@ -1106,8 +1108,9 @@
],
"Checks": [
"entra_authentication_methods_policy_strong_auth_enforced",
"entra_conditional_access_policy_require_mfa_for_management_app",
"entra_non_privileged_user_has_mfa entra_privileged_user_has_mfa",
"entra_conditional_access_policy_require_mfa_for_management_api",
"entra_non_privileged_user_has_mfa",
"entra_privileged_user_has_mfa",
"entra_user_with_vm_access_has_mfa",
"app_minimum_tls_version_12",
"sqlserver_tde_encryption_enabled",
@@ -29,7 +29,6 @@
"app_ensure_php_version_is_latest",
"app_ensure_python_version_is_latest",
"defender_assessments_vm_endpoint_protection_installed",
"defender_assessments_vm_endpoint_protection_installed",
"defender_auto_provisioning_log_analytics_agent_vms_on",
"defender_auto_provisioning_vulnerabilty_assessments_machines_on",
"defender_container_images_resolved_vulnerabilities",
@@ -1601,8 +1600,6 @@
"mysql_flexible_server_minimum_tls_version_12",
"mysql_flexible_server_ssl_connection_enabled",
"postgresql_flexible_server_enforce_ssl_enabled",
"sqlserver_tde_encrypted_with_cmk",
"sqlserver_tde_encryption_enabled",
"storage_blob_public_access_level_is_disabled",
"storage_ensure_azure_services_are_trusted_to_access_is_enabled",
"storage_ensure_encryption_with_customer_managed_keys",
-1
View File
@@ -1565,7 +1565,6 @@
"containerregistry_uses_private_link",
"cosmosdb_account_use_private_endpoints",
"keyvault_private_endpoints",
"monitor_storage_account_with_activity_logs_is_private",
"storage_ensure_private_endpoints_in_storage_accounts"
],
"Attributes": [
@@ -743,24 +743,6 @@
}
]
},
{
"Id": "3.2.1",
"Description": "Ensure that 'Auditing' Retention is 'greater than 90 days'",
"Checks": [
"sqlserver_auditing_retention_90_days"
],
"Attributes": [
{
"Title": "Auditing' Retention is 'greater than 90 days'",
"Section": "3. Logging and Monitoring",
"SubSection": "3.2 Retention",
"AttributeDescription": "Configure SQL Server Audit Retention to retain logs for more than 90 days to ensure long-term visibility into database activity and security events.",
"AdditionalInformation": "Maintaining audit logs for over 90 days helps detect anomalies, security breaches, and unauthorized access. Longer retention periods allow organizations to analyze historical data, support compliance requirements, and strengthen forensic investigations.",
"LevelOfRisk": 3,
"Weight": 10
}
]
},
{
"Id": "3.2.1",
"Description": "Ensure that Network Watcher flow log retention period is '0 or at least 90 days'",
@@ -815,6 +797,24 @@
}
]
},
{
"Id": "3.2.4",
"Description": "Ensure that 'Auditing' Retention is 'greater than 90 days'",
"Checks": [
"sqlserver_auditing_retention_90_days"
],
"Attributes": [
{
"Title": "Auditing' Retention is 'greater than 90 days'",
"Section": "3. Logging and Monitoring",
"SubSection": "3.2 Retention",
"AttributeDescription": "Configure SQL Server Audit Retention to retain logs for more than 90 days to ensure long-term visibility into database activity and security events.",
"AdditionalInformation": "Maintaining audit logs for over 90 days helps detect anomalies, security breaches, and unauthorized access. Longer retention periods allow organizations to analyze historical data, support compliance requirements, and strengthen forensic investigations.",
"LevelOfRisk": 3,
"Weight": 10
}
]
},
{
"Id": "3.3.1",
"Description": "Ensure that 'Auditing' is set to 'On' ",
+1 -1
View File
@@ -1692,7 +1692,7 @@
]
},
{
"Id": "mp.com.4.gcp.vpc.1",
"Id": "mp.com.4.gcp.vpc.2",
"Description": "Separación de flujos de información en la red",
"Attributes": [
{
+35 -55
View File
@@ -18,8 +18,7 @@
],
"Checks": [
"iam_cloud_asset_inventory_enabled",
"securitycenter_security_health_analytics_enabled",
"essentialcontacts_security_contacts_configured"
"iam_organization_essential_contacts_configured"
]
},
{
@@ -34,23 +33,20 @@
}
],
"Checks": [
"cloudstorage_bucket_encryption",
"cloudstorage_bucket_public_access",
"cloudstorage_bucket_uniform_access",
"cloudsql_instance_automatic_backups_enabled",
"cloudsql_instance_encryption_enabled",
"cloudstorage_bucket_uniform_bucket_level_access",
"cloudsql_instance_automated_backups",
"cloudsql_instance_cmek_encryption_enabled",
"cloudsql_instance_public_access",
"compute_instance_public_ip",
"compute_disk_encryption_enabled",
"compute_firewall_rdp_access_from_internet_restricted",
"compute_firewall_ssh_access_from_internet_restricted",
"compute_network_legacy_network_not_used",
"gke_cluster_master_authorized_networks_enabled",
"gke_cluster_private_cluster_enabled",
"compute_instance_encryption_with_csek_enabled",
"compute_firewall_rdp_access_from_the_internet_allowed",
"compute_firewall_ssh_access_from_the_internet_allowed",
"compute_network_not_legacy",
"iam_sa_no_administrative_privileges",
"iam_no_service_roles_at_project_level",
"bigquery_dataset_public_access",
"bigquery_dataset_cmek_encryption",
"bigquery_dataset_cmk_encryption",
"kms_key_rotation_enabled",
"gemini_api_disabled"
]
@@ -148,8 +144,7 @@
}
],
"Checks": [
"securitycenter_security_health_analytics_enabled",
"essentialcontacts_security_contacts_configured",
"iam_organization_essential_contacts_configured",
"logging_sink_created"
]
},
@@ -165,9 +160,7 @@
}
],
"Checks": [
"cloudsql_instance_automatic_backups_enabled",
"compute_disk_snapshot_encryption_enabled",
"gke_cluster_stackdriver_logging_enabled"
"cloudsql_instance_automated_backups"
]
},
{
@@ -182,9 +175,8 @@
}
],
"Checks": [
"cloudsql_instance_automatic_backups_enabled",
"cloudstorage_bucket_object_versioning",
"compute_disk_snapshot_encryption_enabled"
"cloudsql_instance_automated_backups",
"cloudstorage_bucket_versioning_enabled"
]
},
{
@@ -199,9 +191,8 @@
}
],
"Checks": [
"cloudsql_instance_automatic_backups_enabled",
"cloudsql_instance_point_in_time_recovery_enabled",
"cloudstorage_bucket_object_versioning"
"cloudsql_instance_automated_backups",
"cloudstorage_bucket_versioning_enabled"
]
},
{
@@ -247,9 +238,8 @@
],
"Checks": [
"compute_instance_public_ip",
"compute_firewall_rdp_access_from_internet_restricted",
"compute_firewall_ssh_access_from_internet_restricted",
"gke_cluster_private_cluster_enabled"
"compute_firewall_rdp_access_from_the_internet_allowed",
"compute_firewall_ssh_access_from_the_internet_allowed"
]
},
{
@@ -264,9 +254,7 @@
}
],
"Checks": [
"compute_disk_encryption_enabled",
"compute_disk_snapshot_encryption_enabled",
"cloudstorage_bucket_encryption"
"compute_instance_encryption_with_csek_enabled"
]
},
{
@@ -285,11 +273,10 @@
"iam_no_service_roles_at_project_level",
"iam_account_access_approval_enabled",
"cloudstorage_bucket_public_access",
"cloudstorage_bucket_uniform_access",
"cloudstorage_bucket_uniform_bucket_level_access",
"cloudsql_instance_public_access",
"bigquery_dataset_public_access",
"compute_instance_public_ip",
"gke_cluster_private_cluster_enabled"
"compute_instance_public_ip"
]
},
{
@@ -320,11 +307,9 @@
}
],
"Checks": [
"cloudstorage_bucket_encryption",
"cloudsql_instance_encryption_enabled",
"compute_disk_encryption_enabled",
"compute_disk_snapshot_encryption_enabled",
"bigquery_dataset_cmek_encryption",
"cloudsql_instance_cmek_encryption_enabled",
"compute_instance_encryption_with_csek_enabled",
"bigquery_dataset_cmk_encryption",
"kms_key_rotation_enabled"
]
},
@@ -348,8 +333,7 @@
"logging_log_metric_filter_and_alert_for_vpc_network_route_changes_enabled",
"logging_log_metric_filter_and_alert_for_vpc_firewall_rule_changes_enabled",
"logging_log_metric_filter_and_alert_for_bucket_permission_changes_enabled",
"logging_log_metric_filter_and_alert_for_sql_instance_configuration_changes_enabled",
"gke_cluster_stackdriver_logging_enabled"
"logging_log_metric_filter_and_alert_for_sql_instance_configuration_changes_enabled"
]
},
{
@@ -364,9 +348,8 @@
}
],
"Checks": [
"cloudstorage_bucket_object_versioning",
"cloudsql_instance_automatic_backups_enabled",
"cloudsql_instance_point_in_time_recovery_enabled",
"cloudstorage_bucket_versioning_enabled",
"cloudsql_instance_automated_backups",
"kms_key_rotation_enabled"
]
},
@@ -398,11 +381,9 @@
}
],
"Checks": [
"cloudstorage_bucket_encryption",
"compute_firewall_rdp_access_from_internet_restricted",
"compute_firewall_ssh_access_from_internet_restricted",
"cloudsql_instance_ssl_required",
"gke_cluster_master_authorized_networks_enabled"
"compute_firewall_rdp_access_from_the_internet_allowed",
"compute_firewall_ssh_access_from_the_internet_allowed",
"cloudsql_instance_ssl_connections"
]
},
{
@@ -417,8 +398,8 @@
}
],
"Checks": [
"cloudstorage_bucket_object_versioning",
"cloudsql_instance_automatic_backups_enabled",
"cloudstorage_bucket_versioning_enabled",
"cloudsql_instance_automated_backups",
"logging_sink_created"
]
},
@@ -434,12 +415,11 @@
}
],
"Checks": [
"cloudstorage_bucket_encryption",
"cloudsql_instance_encryption_enabled",
"compute_disk_encryption_enabled",
"bigquery_dataset_cmek_encryption",
"cloudsql_instance_cmek_encryption_enabled",
"compute_instance_encryption_with_csek_enabled",
"bigquery_dataset_cmk_encryption",
"kms_key_rotation_enabled",
"cloudsql_instance_ssl_required"
"cloudsql_instance_ssl_connections"
]
}
]
@@ -247,8 +247,7 @@
"Checks": [
"iam_sa_user_managed_key_rotate_90_days",
"kms_key_rotation_enabled",
"apikeys_key_rotated_in_90_days",
"kms_key_rotation_enabled"
"apikeys_key_rotated_in_90_days"
]
},
{
-1
View File
@@ -889,7 +889,6 @@
"dns_dnssec_disabled",
"dns_rsasha1_in_use_to_key_sign_in_dnssec",
"dns_rsasha1_in_use_to_zone_sign_in_dnssec",
"bigquery_dataset_cmk_encryption",
"bigquery_table_cmk_encryption",
"compute_instance_encryption_with_csek_enabled",
"dataproc_encrypted_with_cmks_disabled"
@@ -63,7 +63,7 @@
"Id": "1.2.1",
"Description": "Ensure That There Are Only GCP-Managed Service Account Keys for Each Service Account",
"Checks": [
"iam_sa_no_user_managed_keysiam_sa_no_user_managed_keys"
"iam_sa_no_user_managed_keys"
],
"Attributes": [
{
+1 -2
View File
@@ -568,8 +568,7 @@
"cloudstorage_bucket_uniform_bucket_level_access",
"bigquery_dataset_cmk_encryption",
"bigquery_table_cmk_encryption",
"compute_instance_confidential_computing_enabled",
"pubsub_topic_encryption_with_cmk"
"compute_instance_confidential_computing_enabled"
]
},
{
@@ -1688,27 +1688,6 @@
}
]
},
{
"Id": "2.4.1",
"Description": "Sign all artifacts in all releases with user or organization keys.",
"Checks": [],
"Attributes": [
{
"Section": "2 Build Pipelines",
"Subsection": "2.4 Pipeline Integrity",
"Profile": "Level 2",
"AssessmentStatus": "Manual",
"Description": "Sign all artifacts in all releases with user or organization keys.",
"RationaleStatement": "Signing artifacts is used to validate both their integrity and security. Organizations signal that artifacts may be trusted and they themselves produced them by ensuring that every artifact is properly signed. The presence of this signature also makes potentially malicious activity far more difficult.",
"ImpactStatement": "",
"RemediationProcedure": "For every artifact in every release, verify that all are properly signed.",
"AuditProcedure": "Ensure every artifact in every release is signed.",
"AdditionalInformation": "",
"References": "",
"DefaultValue": ""
}
]
},
{
"Id": "2.4.2",
"Description": "External dependencies may be public packages needed in the pipeline, or perhaps the public image being used for the build worker. Lock these external dependencies in every build pipeline.",
@@ -1132,7 +1132,6 @@
"etcd_no_auto_tls",
"etcd_no_peer_auto_tls",
"etcd_peer_tls_config",
"etcd_tls_encryption",
"kubelet_tls_cert_and_key"
]
},
+2 -2
View File
@@ -9,7 +9,7 @@
"Id": "1.1.1",
"Description": "Administrative accounts are special privileged accounts that could have varying levels of access to data, users, and settings. Regular user accounts should never be utilized for administrative tasks and care should be taken, in the case of a hybrid environment, to keep Administrative accounts separated from on-prem accounts. Administrative accounts should not have applications assigned so that they have no access to potentially vulnerable services (EX. email, Teams, SharePoint, etc.) and only access to perform tasks as needed for administrative purposes.Ensure administrative accounts are not `On-premises sync enabled`.",
"Checks": [
"entra_admin_account_cloud_only"
"entra_admin_users_cloud_only"
],
"Attributes": [
{
@@ -1357,7 +1357,7 @@
"Id": "5.2.2.8",
"Description": "When a Conditional Access policy targets the Microsoft Admin Portals cloud app, the policy is enforced for tokens issued to application IDs of the following Microsoft administrative portals:- Azure portal- Exchange admin center- Microsoft 365 admin center- Microsoft 365 Defender portal- Microsoft Entra admin center- Microsoft Intune admin center- Microsoft Purview compliance portal- Power Platform admin center- SharePoint admin center- Microsoft Teams admin center`Microsoft Admin Portals` should be restricted to specific pre-determined administrative roles.",
"Checks": [
"entra_admin_portals_role_limited_access"
"entra_admin_portals_access_restriction"
],
"Attributes": [
{
@@ -51,13 +51,10 @@
"admincenter_users_between_two_and_four_global_admins",
"defender_antispam_outbound_policy_configured",
"entra_admin_consent_workflow_enabled",
"entra_admin_portals_access_restriction",
"entra_admin_users_cloud_only",
"entra_admin_users_mfa_enabled",
"entra_admin_users_phishing_resistant_mfa_enabled",
"entra_admin_users_sign_in_frequency_enabled",
"entra_policy_ensure_default_user_cannot_create_tenants",
"entra_policy_guest_invite_only_for_admin_roles"
"entra_policy_ensure_default_user_cannot_create_tenants"
]
},
{
@@ -119,7 +116,7 @@
"defender_safelinks_policy_enabled",
"defender_zap_for_teams_enabled",
"defenderxdr_endpoint_privileged_user_exposed_credentials",
"defender_identity_health_issues_no_open",
"defenderidentity_health_issues_no_open",
"entra_admin_users_phishing_resistant_mfa_enabled",
"entra_conditional_access_policy_block_elevated_insider_risk",
"entra_conditional_access_policy_block_o365_elevated_insider_risk",
@@ -186,7 +183,6 @@
"sharepoint_guest_sharing_restricted",
"sharepoint_modern_authentication_required",
"sharepoint_onedrive_sync_restricted_unmanaged_devices",
"teams_external_file_sharing_restricted",
"teams_external_file_sharing_restricted"
]
},
@@ -780,7 +776,7 @@
"defender_malware_policy_comprehensive_attachments_filter_applied",
"defender_malware_policy_notifications_internal_users_malware_enabled",
"defenderxdr_endpoint_privileged_user_exposed_credentials",
"defender_identity_health_issues_no_open"
"defenderidentity_health_issues_no_open"
]
},
{
+1 -1
View File
@@ -52,7 +52,7 @@ class _MutableTimestamp:
timestamp = _MutableTimestamp(datetime.today())
timestamp_utc = _MutableTimestamp(datetime.now(timezone.utc))
prowler_version = "5.41.0"
prowler_version = "5.42.0"
html_logo_url = "https://github.com/prowler-cloud/prowler/"
square_logo_img = "https://raw.githubusercontent.com/prowler-cloud/prowler/dc7d2d5aeb92fdf12e8604f42ef6472cd3e8e889/docs/img/prowler-logo-black.png"
aws_logo = "https://user-images.githubusercontent.com/38561120/235953920-3e3fba08-0795-41dc-b480-9bea57db9f2e.png"
+43 -14
View File
@@ -3,8 +3,10 @@ import hashlib
import os
import re
from collections.abc import Mapping
from concurrent.futures import ThreadPoolExecutor, as_completed
from dataclasses import dataclass
from datetime import datetime, timedelta
from threading import Lock
from typing import Dict, List, Optional
import requests
@@ -416,6 +418,7 @@ class Jira:
api_token: str = None,
domain: str = None,
):
self._token_lock = Lock()
self._redirect_uri = redirect_uri
self._client_id = client_id
self._client_secret = client_secret
@@ -1017,11 +1020,15 @@ class Jira:
if self._using_basic_auth:
return self._access_token
if self.auth_expiration and datetime.now() < datetime.fromisoformat(
self.auth_expiration
):
if self._access_token_is_valid():
return self._access_token
else:
# Atlassian rotates refresh tokens, so two concurrent refreshes with
# the same one would invalidate each other. Re-check under the lock
# in case another thread refreshed while we waited for it.
with self._token_lock:
if self._access_token_is_valid():
return self._access_token
return self.refresh_access_token()
except JiraRefreshTokenError as refresh_error:
raise refresh_error
@@ -1034,6 +1041,12 @@ class Jira:
file=os.path.basename(__file__),
)
def _access_token_is_valid(self) -> bool:
"""Return whether the current OAuth access token has not expired."""
return bool(self.auth_expiration) and datetime.now() < datetime.fromisoformat(
self.auth_expiration
)
def refresh_access_token(self) -> str:
"""Refresh the access token
@@ -1128,15 +1141,21 @@ class Jira:
projects = jira.get_projects()
issue_types = {}
for project_key in projects:
try:
issue_types[project_key] = jira.get_available_issue_types(
project_key
)
except Exception as e:
logger.warning(
f"Failed to get issue types for project {project_key}: {e}"
)
with ThreadPoolExecutor(max_workers=10) as executor:
future_to_project = {
executor.submit(
jira.get_available_issue_types, project_key
): project_key
for project_key in projects
}
for future in as_completed(future_to_project):
project_key = future_to_project[future]
try:
issue_types[project_key] = future.result()
except Exception as e:
logger.warning(
f"Failed to get issue types for project {project_key}: {e}"
)
return JiraConnection(
is_connected=True, projects=projects, issue_types=issue_types
@@ -1296,7 +1315,10 @@ class Jira:
if response.status_code == 200:
if len(response.json()["projects"]) == 0:
logger.error("No projects found")
# Expected per-project condition (e.g. the integration user lacks
# "create issue" rights on this specific project) — the caller in
# test_connection() already treats this as non-fatal, so this isn't
# an error worth alerting on.
raise JiraNoProjectsError(
message="No projects found in Jira",
file=os.path.basename(__file__),
@@ -1316,6 +1338,13 @@ class Jira:
raise refresh_error
except JiraRefreshTokenResponseError as response_error:
raise response_error
except JiraNoProjectsError as no_projects_error:
# Expected per-project condition; the caller decides whether to log it.
raise JiraGetAvailableIssueTypesError(
message="Failed to get available issue types",
file=os.path.basename(__file__),
original_exception=no_projects_error,
)
except Exception as e:
logger.error(f"Failed to get available issue types: {e}")
raise JiraGetAvailableIssueTypesError(
+80 -35
View File
@@ -126,6 +126,8 @@ class AwsProvider(Provider):
aws_access_key_id: str = None,
aws_secret_access_key: str = None,
aws_session_token: Optional[str] = None,
connect_timeout: Optional[int] = None,
read_timeout: Optional[int] = None,
):
"""
Initializes the AWS provider.
@@ -155,6 +157,8 @@ class AwsProvider(Provider):
- aws_access_key_id: The AWS access key ID.
- aws_secret_access_key: The AWS secret access key.
- aws_session_token: The AWS session token, optional.
- connect_timeout: Seconds to wait to establish a connection to an AWS endpoint.
- read_timeout: Seconds to wait for a response from an AWS endpoint.
Raises:
- ArgumentTypeError: If the input MFA ARN is invalid.
@@ -229,7 +233,9 @@ class AwsProvider(Provider):
# TODO: Use AwsSetUpSession ?????
# Configure the initial AWS Session using the local credentials: profile or environment variables
session_config = self.set_session_config(retries_max_attempts)
session_config = self.set_session_config(
retries_max_attempts, connect_timeout, read_timeout
)
aws_session = self.setup_session(
mfa=mfa,
profile=profile,
@@ -576,8 +582,15 @@ class AwsProvider(Provider):
) -> str:
excluded_regions = set(excluded_regions or ())
session_region = session.region_name
env_partition_regions = get_env_partition_regions(session_region)
if session_region and session_region not in excluded_regions:
return session_region
if not env_partition_regions or session_region in env_partition_regions:
return session_region
if env_partition_regions:
for region in env_partition_regions:
if region not in excluded_regions:
return region
return env_partition_regions[0]
for region in AwsProvider.get_bootstrap_region_candidates(session_region):
if region not in excluded_regions:
@@ -673,7 +686,7 @@ class AwsProvider(Provider):
session = Session(**session_arguments)
session._session.set_default_client_config(session_config)
sts_region = (
get_env_partition_bootstrap_region()
get_env_partition_bootstrap_region(session.region_name)
or session.region_name
or AWS_STS_GLOBAL_ENDPOINT_REGION
)
@@ -908,6 +921,9 @@ class AwsProvider(Provider):
logger.error(
f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
# Return an empty dict, as promised by the signature, so the service
# is simply not scanned instead of the callers failing later on a None
return {}
@staticmethod
def get_available_aws_service_regions(
@@ -923,9 +939,13 @@ class AwsProvider(Provider):
Returns:
- A set of strings representing the available regions for the given service and partition.
A service or a partition not present in the regions file yields an empty set, the same
outcome as a service explicitly recorded as unavailable in the partition.
"""
data = read_aws_regions_file()
json_regions = set(data["services"][service]["regions"][partition])
json_regions = set(
data["services"].get(service, {}).get("regions", {}).get(partition, [])
)
if audited_regions:
# Get common regions between input and json
regions = json_regions.intersection(audited_regions)
@@ -1132,16 +1152,14 @@ class AwsProvider(Provider):
Example:
global_region = get_global_region()a
"""
global_region = "us-east-1"
if self._identity.partition == "aws-cn":
global_region = "cn-north-1"
elif self._identity.partition == "aws-eusc":
global_region = "eusc-de-east-1"
elif self._identity.partition == "aws-us-gov":
global_region = "us-gov-east-1"
elif "aws-iso" in self._identity.partition:
global_region = "aws-iso-global"
return global_region
# The first region of the partition is the one of its global STS endpoint,
# which is always a real region, never a pseudo endpoint like "aws-iso-global"
partition_regions = get_botocore_partition_regions().get(
self._identity.partition
)
if partition_regions:
return partition_regions[0]
return "us-east-1"
@staticmethod
def input_role_mfa_token_and_code() -> AWSMFAInfo:
@@ -1158,26 +1176,35 @@ class AwsProvider(Provider):
return AWSMFAInfo(arn=mfa_ARN, totp=mfa_TOTP)
@staticmethod
def set_session_config(retries_max_attempts: int) -> Config:
def set_session_config(
retries_max_attempts: int,
connect_timeout: Optional[int] = None,
read_timeout: Optional[int] = None,
) -> Config:
"""
set_session_config returns a botocore Config object with the Prowler user agent and the default retrier configuration if nothing is passed as argument
set_session_config returns a botocore Config object with the Prowler user agent and the default retrier and timeout configuration if nothing is passed as argument
Args:
- retries_max_attempts: The maximum number of retries for the standard retrier config
- connect_timeout: Seconds to wait to establish a connection to an AWS endpoint
- read_timeout: Seconds to wait for a response from an AWS endpoint
Returns:
- Config: The botocore Config object
"""
default_session_config = get_default_session_config()
if retries_max_attempts:
default_session_config = default_session_config.merge(
Config(
retries={
"max_attempts": retries_max_attempts,
"mode": "standard",
},
)
)
overrides = {}
if retries_max_attempts is not None:
overrides["retries"] = {
"max_attempts": retries_max_attempts,
"mode": "standard",
}
if connect_timeout:
overrides["connect_timeout"] = connect_timeout
if read_timeout:
overrides["read_timeout"] = read_timeout
if overrides:
default_session_config = default_session_config.merge(Config(**overrides))
return default_session_config
@@ -1420,12 +1447,6 @@ class AwsProvider(Provider):
Connection(is_connected=True, Error=None))
"""
try:
if aws_region is None:
aws_region = (
get_env_partition_bootstrap_region()
or AWS_STS_GLOBAL_ENDPOINT_REGION
)
session = AwsProvider.setup_session(
mfa=mfa_enabled,
profile=profile,
@@ -1434,6 +1455,12 @@ class AwsProvider(Provider):
aws_session_token=aws_session_token,
)
if aws_region is None:
aws_region = (
get_env_partition_bootstrap_region(session.region_name)
or AWS_STS_GLOBAL_ENDPOINT_REGION
)
if role_arn:
session_duration = validate_session_duration(session_duration)
role_session_name = validate_role_session_name(role_session_name)
@@ -1759,11 +1786,18 @@ def get_botocore_partition_regions() -> dict:
return partition_regions
def get_env_partition_regions() -> Optional[list]:
def get_env_partition_regions(
session_region: Optional[str] = None,
) -> Optional[list]:
"""
Get the bootstrap region candidates for the partition set in the
PROWLER_AWS_PARTITION environment variable.
Args:
session_region (Optional[str]): The region of the AWS session. It leads
the candidates when it belongs to the partition and is ignored
otherwise.
Returns:
Optional[list]: The regions of the configured partition, preferred
bootstrap region first, or None when the environment variable is
@@ -1782,14 +1816,25 @@ def get_env_partition_regions() -> Optional[list]:
raise AWSInvalidPartitionError(
message=f"Invalid partition: {raw_partition} set in PROWLER_AWS_PARTITION. Valid partitions: {', '.join(sorted(partition_regions))}"
)
# A deployment reached only through its own region's endpoints has no route
# to the partition's global STS region, so the session region goes first
if session_region in regions:
regions = [session_region] + [r for r in regions if r != session_region]
return regions
def get_env_partition_bootstrap_region() -> Optional[str]:
def get_env_partition_bootstrap_region(
session_region: Optional[str] = None,
) -> Optional[str]:
"""
Get the STS bootstrap region for the partition set in the
PROWLER_AWS_PARTITION environment variable.
Args:
session_region (Optional[str]): The region of the AWS session, preferred
when it belongs to the partition.
Returns:
Optional[str]: The preferred bootstrap region of the configured
partition, or None when the environment variable is not set.
@@ -1797,7 +1842,7 @@ def get_env_partition_bootstrap_region() -> Optional[str]:
Raises:
AWSInvalidPartitionError: If the value is not a partition known to botocore.
"""
regions = get_env_partition_regions()
regions = get_env_partition_regions(session_region)
return regions[0] if regions else None
@@ -1833,7 +1878,7 @@ def get_aws_region_for_sts(
if region not in excluded_regions:
return region
env_partition_regions = get_env_partition_regions()
env_partition_regions = get_env_partition_regions(session_region)
if env_partition_regions:
# The configured partition constrains the whole fallback chain: prefer
# a non-excluded region, but never leave the partition
File diff suppressed because it is too large Load Diff
+26 -1
View File
@@ -2,14 +2,39 @@ import os
from botocore.config import Config
from prowler.providers.aws.exceptions.exceptions import AWSInvalidBoto3TimeoutError
AWS_STS_GLOBAL_ENDPOINT_REGION = "us-east-1"
AWS_REGION_US_EAST_1 = "us-east-1"
BOTO3_USER_AGENT_EXTRA = os.getenv("PROWLER_AWS_BOTO3_USER_AGENT_EXTRA", "APN_1826889")
BOTO3_RETRIES_MAX_ATTEMPTS = 3
# botocore defaults both to 60s
BOTO3_CONNECT_TIMEOUT = 10
BOTO3_READ_TIMEOUT = 60
ROLE_SESSION_NAME = "ProwlerAssessmentSession"
def get_boto3_timeout_from_env(name: str, default: int) -> int:
"""Positive integer seconds read from the environment, or default when unset."""
raw = os.getenv(name, "").strip()
if not raw:
return default
if not raw.isdecimal() or int(raw) == 0:
raise AWSInvalidBoto3TimeoutError(
file=os.path.basename(__file__),
message=f"{name} must be a positive integer number of seconds, got {raw!r}",
)
return int(raw)
def get_default_session_config() -> Config:
return Config(
user_agent_extra=BOTO3_USER_AGENT_EXTRA,
retries={"max_attempts": 3, "mode": "standard"},
retries={"max_attempts": BOTO3_RETRIES_MAX_ATTEMPTS, "mode": "standard"},
connect_timeout=get_boto3_timeout_from_env(
"PROWLER_AWS_BOTO3_CONNECT_TIMEOUT", BOTO3_CONNECT_TIMEOUT
),
read_timeout=get_boto3_timeout_from_env(
"PROWLER_AWS_BOTO3_READ_TIMEOUT", BOTO3_READ_TIMEOUT
),
)
@@ -78,6 +78,10 @@ class AWSBaseException(ProwlerException):
"message": "The provided AWS partition is invalid",
"remediation": "Check the provided AWS partition and ensure it is valid.",
},
(1918, "AWSInvalidBoto3TimeoutError"): {
"message": "The Boto3 timeout configured through the environment is invalid",
"remediation": "Set PROWLER_AWS_BOTO3_CONNECT_TIMEOUT and PROWLER_AWS_BOTO3_READ_TIMEOUT to a positive integer number of seconds.",
},
}
def __init__(self, code, file=None, original_exception=None, message=None):
@@ -231,3 +235,12 @@ class AWSInvalidPartitionError(AWSBaseException):
super().__init__(
1917, file=file, original_exception=original_exception, message=message
)
class AWSInvalidBoto3TimeoutError(AWSBaseException):
"""Boto3 timeout configured through the environment is not a positive integer."""
def __init__(self, file=None, original_exception=None, message=None):
super().__init__(
1918, file=file, original_exception=original_exception, message=message
)
@@ -156,7 +156,21 @@ def init_parser(self):
nargs="?",
default=None,
type=int,
help="Set the maximum attemps for the Boto3 standard retrier config (Default: 3)",
help="Set the maximum retries for the Boto3 standard retrier config, 0 disables retries (Default: 3)",
)
boto3_config_subparser.add_argument(
"--aws-connect-timeout",
nargs="?",
default=None,
type=validate_timeout,
help="Seconds to wait to establish a connection (TCP, proxy tunnel and TLS) to an AWS endpoint before retrying (Default: 10)",
)
boto3_config_subparser.add_argument(
"--aws-read-timeout",
nargs="?",
default=None,
type=validate_timeout,
help="Seconds to wait for a response from an AWS endpoint before retrying (Default: 60)",
)
# Scan Unused Services
@@ -190,6 +204,13 @@ def validate_session_duration(session_duration: int) -> int:
return duration
def validate_timeout(value: str) -> int:
"""validate_timeout validates that the input is a whole number of seconds greater than zero"""
if not value.isdecimal() or int(value) == 0:
raise ArgumentTypeError(f"{value} is not a positive integer")
return int(value)
def validate_role_session_name(session_name) -> str:
"""
Validates that the role session name is valid.
@@ -42,6 +42,8 @@ class AwsSetUpSession:
aws_session_token: Optional[str] = None,
retries_max_attempts: int = 3,
regions: set = set(),
connect_timeout: Optional[int] = None,
read_timeout: Optional[int] = None,
) -> None:
"""
The constructor for the AwsSetUpSession class.
@@ -58,6 +60,8 @@ class AwsSetUpSession:
- aws_session_token: The AWS session token, optional.
- retries_max_attempts: The maximum number of retries for the AWS client.
- regions: A set of regions to audit.
- connect_timeout: Seconds to wait to establish a connection to an AWS endpoint.
- read_timeout: Seconds to wait for a response from an AWS endpoint.
Returns:
@@ -73,7 +77,9 @@ class AwsSetUpSession:
aws_access_key_id=aws_access_key_id,
aws_secret_access_key=aws_secret_access_key,
)
session_config = AwsProvider.set_session_config(retries_max_attempts)
session_config = AwsProvider.set_session_config(
retries_max_attempts, connect_timeout, read_timeout
)
aws_session = AwsProvider.setup_session(
mfa=mfa,
profile=profile,
@@ -23,7 +23,7 @@ class codebuild_project_uses_allowed_github_organizations(Check):
project_role = next(
(
role
for role in iam_client.roles
for role in iam_client.roles or []
if role.arn == project.service_role_arn
),
None,
@@ -377,7 +377,7 @@ class iam_role_service_trust_restricts_source_to_account(Check):
status. The sibling token-wildcard check carries the same note, for the same reason.
"""
findings = []
for role in iam_client.roles:
for role in iam_client.roles or []:
# Service-linked roles are excluded: their trust relationship is managed by
# the service and cannot be edited, so a finding would not be actionable.
if "aws-service-role" in role.arn:
@@ -205,7 +205,9 @@ class rolesanywhere_profile_restricts_session_permissions(Check):
not administrative, and disabled profiles.
"""
findings = []
roles_by_arn = {role.arn: role for role in iam_client.roles}
# iam:ListRoles denied leaves roles as None: every referenced role is
# then unknown and the profile falls through to MANUAL.
roles_by_arn = {role.arn: role for role in (iam_client.roles or [])}
for profile in rolesanywhere_client.profiles.values():
report = Check_Report_AWS(metadata=self.metadata(), resource=profile)
role_statuses = {
+2
View File
@@ -382,6 +382,8 @@ class Provider(ABC):
)
provider_class(
retries_max_attempts=arguments.aws_retries_max_attempts,
connect_timeout=arguments.aws_connect_timeout,
read_timeout=arguments.aws_read_timeout,
role_arn=arguments.role,
session_duration=arguments.session_duration,
external_id=arguments.external_id,
+9 -4
View File
@@ -115,10 +115,15 @@ class ImageProvider(Provider):
self._session = None
self._identity = "prowler"
self._listing_only = False
self._trivy_cache_dir_obj = tempfile.TemporaryDirectory(
prefix="prowler-trivy-cache-"
)
self._trivy_cache_dir = self._trivy_cache_dir_obj.name
# A supplied cache dir is never deleted: it may hold a DB we cannot refetch
configured_cache_dir = os.environ.get("TRIVY_CACHE_DIR", "").strip()
if configured_cache_dir:
self._trivy_cache_dir = configured_cache_dir
else:
self._trivy_cache_dir_obj = tempfile.TemporaryDirectory(
prefix="prowler-trivy-cache-"
)
self._trivy_cache_dir = self._trivy_cache_dir_obj.name
# Registry authentication (follows IaC pattern: explicit params, env vars internal)
self.registry_username = registry_username or os.environ.get(
+1 -1
View File
@@ -143,7 +143,7 @@ maintainers = [{name = "Prowler Engineering", email = "engineering@prowler.com"}
name = "prowler"
readme = "README.md"
requires-python = ">=3.10,<3.14"
version = "5.41.0"
version = "5.42.0"
[project.scripts]
prowler = "prowler.__main__:prowler"
+21
View File
@@ -0,0 +1,21 @@
from unittest import mock
import pytest
_MOCK_CLASSES = (
mock.Mock,
mock.MagicMock,
mock.AsyncMock,
mock.NonCallableMock,
mock.NonCallableMagicMock,
)
_MOCK_CLASS_BASELINE = {cls: frozenset(vars(cls)) for cls in _MOCK_CLASSES}
@pytest.fixture(autouse=True)
def _reset_mock_class_attributes():
"""Drop attributes a test sets on the mock classes themselves (`c = mock.MagicMock; c.provider = ...`), so they cannot leak into other tests' instances."""
yield
for cls, baseline in _MOCK_CLASS_BASELINE.items():
for name in set(vars(cls)) - baseline:
delattr(cls, name)
@@ -0,0 +1,64 @@
import os
from functools import lru_cache
import pytest
from prowler.lib.check.compliance_models import load_compliance_framework_universal
from prowler.lib.check.utils import recover_checks_from_provider
COMPLIANCE_DIR = os.path.normpath(
os.path.join(os.path.dirname(__file__), "..", "..", "..", "prowler", "compliance")
)
def _compliance_jsons() -> list[str]:
paths = []
for root, _, files in os.walk(COMPLIANCE_DIR):
paths.extend(os.path.join(root, f) for f in files if f.endswith(".json"))
return sorted(paths)
@lru_cache
def _check_ids(provider: str) -> frozenset[str]:
return frozenset(name for name, _ in recover_checks_from_provider(provider))
@pytest.mark.parametrize("json_path", _compliance_jsons(), ids=os.path.basename)
class TestComplianceCatalogIntegrity:
def test_requirement_ids_are_unique(self, json_path):
framework = load_compliance_framework_universal(json_path)
assert framework is not None, f"Failed to load {json_path}"
ids = [requirement.id for requirement in framework.requirements]
duplicated = sorted({rid for rid in ids if ids.count(rid) > 1})
assert not duplicated, f"Duplicated requirement ids: {duplicated}"
def test_requirements_do_not_repeat_checks(self, json_path):
framework = load_compliance_framework_universal(json_path)
assert framework is not None, f"Failed to load {json_path}"
repeated = sorted(
{
(requirement.id, provider, check)
for requirement in framework.requirements
for provider, checks in requirement.checks.items()
for check in checks
if checks.count(check) > 1
}
)
assert not repeated, f"Checks listed twice in a requirement: {repeated}"
def test_referenced_checks_exist_for_provider(self, json_path):
framework = load_compliance_framework_universal(json_path)
assert framework is not None, f"Failed to load {json_path}"
unknown = sorted(
{
(provider, check)
for requirement in framework.requirements
for provider, checks in requirement.checks.items()
for check in checks
if check not in _check_ids(provider)
}
)
assert not unknown, f"Checks that do not exist for their provider: {unknown}"
+29
View File
@@ -1152,6 +1152,35 @@ class Test_Parser:
parsed = self.parser.parse(command)
assert parsed.aws_retries_max_attempts == int(max_retries)
def test_aws_parser_retries_max_attempts_zero(self):
command = [prowler_command, "--aws-retries-max-attempts", "0"]
parsed = self.parser.parse(command)
assert parsed.aws_retries_max_attempts == 0
def test_aws_parser_timeouts_default_to_none(self):
parsed = self.parser.parse([prowler_command])
assert parsed.aws_connect_timeout is None
assert parsed.aws_read_timeout is None
@pytest.mark.parametrize(
"argument, attribute",
[
("--aws-connect-timeout", "aws_connect_timeout"),
("--aws-read-timeout", "aws_read_timeout"),
],
)
def test_aws_parser_timeouts(self, argument, attribute):
timeout = "5"
command = [prowler_command, argument, timeout]
parsed = self.parser.parse(command)
assert getattr(parsed, attribute) == int(timeout)
@pytest.mark.parametrize("value", ["0", "-1", "abc"])
def test_aws_parser_connect_timeout_rejects_non_positive(self, value):
command = [prowler_command, "--aws-connect-timeout", value]
with pytest.raises(SystemExit):
self.parser.parse(command)
def test_aws_parser_scan_unused_services(self):
argument = "--scan-unused-services"
command = [prowler_command, argument]
+175
View File
@@ -1,7 +1,11 @@
import base64
import hashlib
from concurrent.futures import ThreadPoolExecutor
from dataclasses import FrozenInstanceError
from datetime import datetime, timedelta
from logging import ERROR, WARNING
from threading import Barrier
from time import sleep
from types import SimpleNamespace
from typing import List, Optional
from unittest.mock import MagicMock, PropertyMock, patch
@@ -453,6 +457,36 @@ class TestJiraIntegration:
assert access_token == "new_access_token"
mock_refresh_access_token.assert_called_once()
def test_get_access_token_concurrent_refresh_happens_once(self):
self.jira_integration.auth_expiration = (
datetime.now() - timedelta(seconds=1)
).isoformat()
refresh_calls = []
# All 5 pass the expiry check together, so without a lock every one of
# them would refresh.
barrier = Barrier(5, timeout=5)
def fake_refresh():
refresh_calls.append(1)
# Keep the token expired while the other threads check it.
sleep(0.2)
self.jira_integration._access_token = "refreshed_token"
self.jira_integration.auth_expiration = (
datetime.now() + timedelta(hours=1)
).isoformat()
return "refreshed_token"
def get_token(_):
barrier.wait()
return self.jira_integration.get_access_token()
with patch.object(Jira, "refresh_access_token", side_effect=fake_refresh):
with ThreadPoolExecutor(max_workers=5) as executor:
tokens = list(executor.map(get_token, range(5)))
assert tokens == ["refreshed_token"] * 5
assert len(refresh_calls) == 1
@freeze_time(TEST_DATETIME)
@patch("prowler.lib.outputs.jira.jira.requests.post")
@patch.object(Jira, "get_cloud_id", return_value="test_cloud_id")
@@ -749,6 +783,77 @@ class TestJiraIntegration:
domain=self.domain,
)
@patch.object(Jira, "get_auth", return_value=None)
@patch.object(
Jira,
"get_projects",
return_value={"PROJ1": "Project One", "PROJ2": "Project Two"},
)
def test_test_connection_partial_issue_types_failure(
self, mock_get_projects, mock_get_auth, caplog
):
# To disable vulture
mock_get_projects = mock_get_projects
mock_get_auth = mock_get_auth
caplog.set_level(WARNING)
def fake_issue_types(project_key):
if project_key == "PROJ2":
raise JiraGetAvailableIssueTypesError("no create permission")
return ["Task"]
with patch.object(
Jira, "get_available_issue_types", side_effect=fake_issue_types
):
connection = Jira.test_connection(
redirect_uri=self.redirect_uri,
client_id=self.client_id,
client_secret=self.client_secret,
)
assert connection.is_connected
assert connection.error is None
assert connection.issue_types == {"PROJ1": ["Task"]}
assert any(
record.levelno == WARNING
and "Failed to get issue types for project PROJ2" in record.message
for record in caplog.records
)
assert not any(record.levelno >= ERROR for record in caplog.records)
@patch.object(Jira, "get_auth", return_value=None)
@patch.object(
Jira,
"get_projects",
return_value={f"PROJ{i}": f"Project {i}" for i in range(5)},
)
def test_test_connection_fetches_issue_types_concurrently(
self, mock_get_projects, mock_get_auth
):
# To disable vulture
mock_get_projects = mock_get_projects
mock_get_auth = mock_get_auth
# Every call blocks until all 5 arrive; a sequential fetch would time out
# at the barrier and surface as a per-project failure instead of a result.
barrier = Barrier(5, timeout=5)
def fake_issue_types(project_key):
barrier.wait()
return [project_key]
with patch.object(
Jira, "get_available_issue_types", side_effect=fake_issue_types
):
connection = Jira.test_connection(
redirect_uri=self.redirect_uri,
client_id=self.client_id,
client_secret=self.client_secret,
)
assert connection.is_connected
assert connection.issue_types == {f"PROJ{i}": [f"PROJ{i}"] for i in range(5)}
@patch.object(Jira, "get_auth", return_value=None)
@patch.object(
Jira, "get_projects", side_effect=JiraNoProjectsError("No projects found")
@@ -998,6 +1103,76 @@ class TestJiraIntegration:
with pytest.raises(JiraGetAvailableIssueTypesError):
self.jira_integration.get_available_issue_types(project_key="TEST")
@patch.object(Jira, "get_access_token", return_value="valid_access_token")
@patch.object(
Jira, "cloud_id", new_callable=PropertyMock, return_value="test_cloud_id"
)
@patch("prowler.lib.outputs.jira.jira.requests.get")
def test_get_available_issue_types_no_projects_does_not_log(
self, mock_get, mock_cloud_id, mock_get_access_token, caplog
):
# To disable vulture
mock_cloud_id = mock_cloud_id
mock_get_access_token = mock_get_access_token
caplog.set_level(WARNING)
mock_response = MagicMock()
mock_response.status_code = 200
mock_response.json.return_value = {"projects": []}
mock_get.return_value = mock_response
with pytest.raises(JiraGetAvailableIssueTypesError):
self.jira_integration.get_available_issue_types(project_key="TEST")
assert not any(record.levelno >= WARNING for record in caplog.records)
@patch.object(Jira, "get_auth", return_value=None)
@patch.object(
Jira,
"get_projects",
return_value={"TEST": "Test Project"},
)
@patch.object(Jira, "get_access_token", return_value="valid_access_token")
@patch.object(
Jira, "cloud_id", new_callable=PropertyMock, return_value="test_cloud_id"
)
@patch("prowler.lib.outputs.jira.jira.requests.get")
def test_test_connection_empty_issue_types_logs_one_warning(
self,
mock_get,
mock_cloud_id,
mock_get_access_token,
mock_get_projects,
mock_get_auth,
caplog,
):
# To disable vulture
mock_cloud_id = mock_cloud_id
mock_get_access_token = mock_get_access_token
mock_get_projects = mock_get_projects
mock_get_auth = mock_get_auth
caplog.set_level(WARNING)
mock_response = MagicMock()
mock_response.status_code = 200
mock_response.json.return_value = {"projects": []}
mock_get.return_value = mock_response
connection = Jira.test_connection(
redirect_uri=self.redirect_uri,
client_id=self.client_id,
client_secret=self.client_secret,
)
warnings = [
record
for record in caplog.records
if record.levelno == WARNING and "project TEST" in record.message
]
assert connection.is_connected
assert len(warnings) == 1
assert not any(record.levelno >= ERROR for record in caplog.records)
@patch.object(Jira, "get_access_token", return_value="valid_access_token")
@patch.object(
Jira, "cloud_id", new_callable=PropertyMock, return_value="test_cloud_id"
+450 -4
View File
@@ -16,22 +16,32 @@ from moto import mock_aws
from pytest import raises
from tzlocal import get_localzone
from prowler.providers.aws.aws_provider import AwsProvider, get_aws_region_for_sts
from prowler.providers.aws.aws_provider import (
AwsProvider,
get_aws_region_for_sts,
get_env_partition_bootstrap_region,
get_env_partition_regions,
)
from prowler.providers.aws.config import (
AWS_STS_GLOBAL_ENDPOINT_REGION,
BOTO3_CONNECT_TIMEOUT,
BOTO3_READ_TIMEOUT,
BOTO3_USER_AGENT_EXTRA,
ROLE_SESSION_NAME,
get_boto3_timeout_from_env,
get_default_session_config,
)
from prowler.providers.aws.exceptions.exceptions import (
AWSArgumentTypeValidationError,
AWSIAMRoleARNInvalidResourceTypeError,
AWSInvalidBoto3TimeoutError,
AWSInvalidPartitionError,
AWSInvalidProviderIdError,
AWSNoCredentialsError,
)
from prowler.providers.aws.lib.arn.models import ARN
from prowler.providers.aws.lib.mutelist.mutelist import AWSMutelist
from prowler.providers.aws.lib.session.aws_set_up_session import AwsSetUpSession
from prowler.providers.aws.models import (
AWSAssumeRoleInfo,
AWSCallerIdentity,
@@ -49,6 +59,7 @@ from tests.providers.aws.utils import (
AWS_EUSC_PARTITION,
AWS_GOV_CLOUD_ACCOUNT_ARN,
AWS_GOV_CLOUD_PARTITION,
AWS_ISO_B_PARTITION,
AWS_ISO_PARTITION,
AWS_REGION_CN_NORTH_1,
AWS_REGION_CN_NORTHWEST_1,
@@ -56,7 +67,10 @@ from tests.providers.aws.utils import (
AWS_REGION_EU_WEST_1,
AWS_REGION_EUSC_DE_EAST_1,
AWS_REGION_GOV_CLOUD_US_EAST_1,
AWS_REGION_ISO_GLOBAL,
AWS_REGION_GOV_CLOUD_US_WEST_1,
AWS_REGION_ISO_B_EAST_1,
AWS_REGION_ISO_EAST_1,
AWS_REGION_ISO_WEST_1,
AWS_REGION_US_EAST_1,
AWS_REGION_US_EAST_2,
EXAMPLE_AMI_ID,
@@ -1181,6 +1195,13 @@ aws:
== AWS_REGION_EU_WEST_1
)
@mock_aws
def test_aws_get_global_region(self):
aws_provider = AwsProvider()
aws_provider._identity.partition = AWS_COMMERCIAL_PARTITION
assert aws_provider.get_global_region() == AWS_REGION_US_EAST_1
@mock_aws
def test_aws_gov_get_global_region(self):
aws_provider = AwsProvider()
@@ -1200,7 +1221,21 @@ aws:
aws_provider = AwsProvider()
aws_provider._identity.partition = AWS_ISO_PARTITION
assert aws_provider.get_global_region() == AWS_REGION_ISO_GLOBAL
assert aws_provider.get_global_region() == AWS_REGION_ISO_EAST_1
@mock_aws
def test_aws_iso_b_get_global_region(self):
aws_provider = AwsProvider()
aws_provider._identity.partition = AWS_ISO_B_PARTITION
assert aws_provider.get_global_region() == AWS_REGION_ISO_B_EAST_1
@mock_aws
def test_get_global_region_for_an_unknown_partition(self):
aws_provider = AwsProvider()
aws_provider._identity.partition = "aws-unknown"
assert aws_provider.get_global_region() == AWS_REGION_US_EAST_1
@mock_aws
def test_aws_eusc_get_global_region(self):
@@ -1288,6 +1323,88 @@ aws:
len(aws_provider.get_available_aws_service_regions("ec2", "aws")) == 17
)
@mock_aws
def test_get_available_aws_service_regions_commercial_and_gov_cloud(self):
aws_provider = AwsProvider()
assert AWS_REGION_US_EAST_1 in aws_provider.get_available_aws_service_regions(
"ec2", AWS_COMMERCIAL_PARTITION
)
assert (
AWS_REGION_GOV_CLOUD_US_EAST_1
in aws_provider.get_available_aws_service_regions(
"ec2", AWS_GOV_CLOUD_PARTITION
)
)
# A service recorded as unavailable in the partition yields an empty set
assert (
aws_provider.get_available_aws_service_regions(
"bedrock-agent", AWS_CHINA_PARTITION
)
== set()
)
@mock_aws
def test_get_available_aws_service_regions_iso_partitions(self):
aws_provider = AwsProvider()
assert aws_provider.get_available_aws_service_regions(
"ec2", AWS_ISO_PARTITION
) == {
AWS_REGION_ISO_EAST_1,
AWS_REGION_ISO_WEST_1,
}
assert aws_provider.get_available_aws_service_regions(
"guardduty", AWS_ISO_B_PARTITION
) == {AWS_REGION_ISO_B_EAST_1}
# Every service carries every ISO partition, empty when not available
assert (
aws_provider.get_available_aws_service_regions(
"bedrock", AWS_ISO_B_PARTITION
)
== set()
)
@mock_aws
def test_get_available_aws_service_regions_unknown_partition(self):
aws_provider = AwsProvider()
assert (
aws_provider.get_available_aws_service_regions("ec2", "aws-unknown")
== set()
)
@mock_aws
def test_get_available_aws_service_regions_unknown_service(self):
aws_provider = AwsProvider()
assert (
aws_provider.get_available_aws_service_regions(
"unknown-service", AWS_COMMERCIAL_PARTITION
)
== set()
)
@mock_aws
def test_generate_regional_clients_service_not_in_partition(self):
aws_provider = AwsProvider()
aws_provider._identity.partition = AWS_ISO_PARTITION
response = aws_provider.generate_regional_clients("bedrock")
assert response == {}
@mock_aws
def test_generate_regional_clients_returns_empty_dict_on_error(self):
aws_provider = AwsProvider()
with patch.object(
AwsProvider,
"get_available_aws_service_regions",
side_effect=Exception("boom"),
):
assert aws_provider.generate_regional_clients("ec2") == {}
@mock_aws
def test_get_tagged_resources(self):
ec2_client = client("ec2", region_name=AWS_REGION_EU_CENTRAL_1)
@@ -2054,7 +2171,8 @@ aws:
assert not recovered_regions
def test_get_regions_all_count(self):
assert len(AwsProvider.get_regions(partition=None)) == 39
# 34 aws + 2 aws-cn + 2 aws-us-gov + 1 aws-eusc + 7 ISO regions
assert len(AwsProvider.get_regions(partition=None)) == 46
def test_get_regions_cn_count(self):
assert len(AwsProvider.get_regions("aws-cn")) == 2
@@ -2062,6 +2180,12 @@ aws:
def test_get_regions_aws_count(self):
assert len(AwsProvider.get_regions(partition="aws")) == 34
def test_get_regions_iso_count(self):
assert AwsProvider.get_regions(AWS_ISO_PARTITION) == {
AWS_REGION_ISO_EAST_1,
AWS_REGION_ISO_WEST_1,
}
def test_get_all_regions(self):
with patch(
"prowler.providers.aws.aws_provider.read_aws_regions_file",
@@ -2447,6 +2571,245 @@ aws:
== AWS_REGION_GOV_CLOUD_US_EAST_1
)
def test_get_env_partition_regions_leads_with_session_region(self):
with mock.patch.dict(
os.environ,
{"PROWLER_AWS_PARTITION": AWS_GOV_CLOUD_PARTITION},
clear=False,
):
regions = get_env_partition_regions(AWS_REGION_GOV_CLOUD_US_WEST_1)
assert regions[0] == AWS_REGION_GOV_CLOUD_US_WEST_1
assert set(regions) == set(get_env_partition_regions())
def test_get_env_partition_regions_ignores_session_region_outside_partition(
self,
):
with mock.patch.dict(
os.environ,
{"PROWLER_AWS_PARTITION": AWS_GOV_CLOUD_PARTITION},
clear=False,
):
regions = get_env_partition_regions(AWS_REGION_EU_WEST_1)
assert regions[0] == AWS_REGION_GOV_CLOUD_US_EAST_1
assert AWS_REGION_EU_WEST_1 not in regions
def test_get_env_partition_bootstrap_region_prefers_session_region(self):
with mock.patch.dict(
os.environ,
{"PROWLER_AWS_PARTITION": AWS_GOV_CLOUD_PARTITION},
clear=False,
):
assert (
get_env_partition_bootstrap_region(AWS_REGION_GOV_CLOUD_US_WEST_1)
== AWS_REGION_GOV_CLOUD_US_WEST_1
)
def test_get_env_partition_bootstrap_region_without_session_region(self):
with mock.patch.dict(
os.environ,
{"PROWLER_AWS_PARTITION": AWS_GOV_CLOUD_PARTITION},
clear=False,
):
assert (
get_env_partition_bootstrap_region() == AWS_REGION_GOV_CLOUD_US_EAST_1
)
def test_get_env_partition_bootstrap_region_without_partition(self):
with mock.patch.dict(os.environ, {"PROWLER_AWS_PARTITION": ""}, clear=False):
assert (
get_env_partition_bootstrap_region(AWS_REGION_GOV_CLOUD_US_WEST_1)
is None
)
def test_get_aws_region_for_sts_env_partition_prefers_session_region(self):
with mock.patch.dict(
os.environ,
{"PROWLER_AWS_PARTITION": AWS_GOV_CLOUD_PARTITION},
clear=False,
):
assert (
get_aws_region_for_sts(AWS_REGION_GOV_CLOUD_US_WEST_1, None)
== AWS_REGION_GOV_CLOUD_US_WEST_1
)
def test_get_profile_region_env_partition_keeps_session_region_inside_partition(
self,
):
with mock.patch.dict(
os.environ,
{"PROWLER_AWS_PARTITION": AWS_GOV_CLOUD_PARTITION},
clear=False,
):
aws_session = session.Session(region_name=AWS_REGION_GOV_CLOUD_US_WEST_1)
assert (
AwsProvider.get_profile_region(aws_session)
== AWS_REGION_GOV_CLOUD_US_WEST_1
)
def test_get_profile_region_env_partition_ignores_session_region_outside_partition(
self,
):
with mock.patch.dict(
os.environ,
{"PROWLER_AWS_PARTITION": AWS_GOV_CLOUD_PARTITION},
clear=False,
):
aws_session = session.Session(region_name=AWS_REGION_US_EAST_1)
assert (
AwsProvider.get_profile_region(aws_session)
== AWS_REGION_GOV_CLOUD_US_EAST_1
)
def test_get_profile_region_env_partition_excluded_session_region_stays_in_partition(
self,
):
with mock.patch.dict(
os.environ,
{"PROWLER_AWS_PARTITION": AWS_GOV_CLOUD_PARTITION},
clear=False,
):
aws_session = session.Session(region_name=AWS_REGION_GOV_CLOUD_US_WEST_1)
assert (
AwsProvider.get_profile_region(
aws_session, {AWS_REGION_GOV_CLOUD_US_WEST_1}
)
== AWS_REGION_GOV_CLOUD_US_EAST_1
)
def test_get_profile_region_env_partition_all_regions_excluded_stays_in_partition(
self,
):
with mock.patch.dict(
os.environ,
{"PROWLER_AWS_PARTITION": AWS_GOV_CLOUD_PARTITION},
clear=False,
):
aws_session = session.Session(region_name=AWS_REGION_GOV_CLOUD_US_WEST_1)
gov_cloud_regions = set(get_env_partition_regions())
assert (
AwsProvider.get_profile_region(aws_session, gov_cloud_regions)
== AWS_REGION_GOV_CLOUD_US_WEST_1
)
@mock_aws
def test_test_connection_env_partition_prefers_session_region(self):
with (
mock.patch.dict(
os.environ,
{
"PROWLER_AWS_PARTITION": AWS_GOV_CLOUD_PARTITION,
"AWS_DEFAULT_REGION": AWS_REGION_GOV_CLOUD_US_WEST_1,
},
clear=False,
),
mock.patch.object(
AwsProvider,
"validate_credentials",
return_value=AWSCallerIdentity(
user_id="test-user-id",
account=AWS_ACCOUNT_NUMBER,
arn=ARN(AWS_GOV_CLOUD_ACCOUNT_ARN),
region=AWS_REGION_GOV_CLOUD_US_WEST_1,
),
) as mock_validate_credentials,
):
connection = AwsProvider.test_connection(
aws_access_key_id="test-access-key",
aws_secret_access_key="test-secret-key",
raise_on_exception=False,
)
assert connection.is_connected
assert (
mock_validate_credentials.call_args.args[1]
== AWS_REGION_GOV_CLOUD_US_WEST_1
)
@mock_aws
def test_test_connection_role_env_partition_prefers_session_region(self):
with (
mock.patch.dict(
os.environ,
{
"PROWLER_AWS_PARTITION": AWS_GOV_CLOUD_PARTITION,
"AWS_DEFAULT_REGION": AWS_REGION_GOV_CLOUD_US_WEST_1,
},
clear=False,
),
mock.patch.object(
AwsProvider,
"assume_role",
return_value=AWSCredentials(
aws_access_key_id="assumed-access-key",
aws_secret_access_key="assumed-secret-key",
aws_session_token="assumed-session-token",
expiration=datetime.now(),
),
) as mock_assume_role,
mock.patch.object(
AwsProvider,
"validate_credentials",
return_value=AWSCallerIdentity(
user_id="test-user-id",
account=AWS_ACCOUNT_NUMBER,
arn=ARN(AWS_GOV_CLOUD_ACCOUNT_ARN),
region=AWS_REGION_GOV_CLOUD_US_WEST_1,
),
),
):
connection = AwsProvider.test_connection(
role_arn=f"arn:{AWS_GOV_CLOUD_PARTITION}:iam::{AWS_ACCOUNT_NUMBER}:role/test-role",
aws_access_key_id="test-access-key",
aws_secret_access_key="test-secret-key",
raise_on_exception=False,
)
assert connection.is_connected
assumed_role_info = mock_assume_role.call_args.args[1]
assert assumed_role_info.sts_region == AWS_REGION_GOV_CLOUD_US_WEST_1
@mock_aws
def test_setup_session_mfa_env_partition_prefers_session_region(self):
with (
mock.patch.dict(
os.environ,
{
"PROWLER_AWS_PARTITION": AWS_GOV_CLOUD_PARTITION,
"AWS_DEFAULT_REGION": AWS_REGION_GOV_CLOUD_US_WEST_1,
},
clear=False,
),
mock.patch.object(
AwsProvider,
"input_role_mfa_token_and_code",
return_value=AWSMFAInfo(
arn=f"arn:{AWS_GOV_CLOUD_PARTITION}:iam::{AWS_ACCOUNT_NUMBER}:mfa/test",
totp="123456",
),
),
mock.patch.object(
AwsProvider,
"create_sts_session",
side_effect=AwsProvider.create_sts_session,
) as mock_create_sts_session,
):
AwsProvider.setup_session(
mfa=True,
aws_access_key_id="test-access-key",
aws_secret_access_key="test-secret-key",
)
assert (
mock_create_sts_session.call_args.args[1]
== AWS_REGION_GOV_CLOUD_US_WEST_1
)
@mock_aws
def test_test_connection_env_partition_mismatch(self):
with (
@@ -2490,6 +2853,8 @@ aws:
assert session_config.user_agent_extra == BOTO3_USER_AGENT_EXTRA
assert session_config.retries == {"max_attempts": 3, "mode": "standard"}
assert session_config.connect_timeout == BOTO3_CONNECT_TIMEOUT
assert session_config.read_timeout == BOTO3_READ_TIMEOUT
@mock_aws
def test_set_session_config_10_max_attempts(self):
@@ -2498,12 +2863,93 @@ aws:
assert session_config.user_agent_extra == BOTO3_USER_AGENT_EXTRA
assert session_config.retries == {"max_attempts": 10, "mode": "standard"}
assert session_config.connect_timeout == BOTO3_CONNECT_TIMEOUT
assert session_config.read_timeout == BOTO3_READ_TIMEOUT
def test_set_session_config_0_max_attempts_disables_retries(self):
session_config = AwsProvider.set_session_config(0)
assert session_config.retries == {"max_attempts": 0, "mode": "standard"}
@mock_aws
def test_aws_provider_0_max_attempts_reaches_clients(self):
aws_provider = AwsProvider(retries_max_attempts=0)
client = aws_provider.session.current_session.client(
"ec2", region_name=AWS_REGION_US_EAST_1
)
# botocore rewrites max_attempts into total_max_attempts (retries + 1)
assert client.meta.config.retries["total_max_attempts"] == 1
def test_set_session_config_timeouts(self):
session_config = AwsProvider.set_session_config(
None, connect_timeout=2, read_timeout=15
)
assert session_config.retries == {"max_attempts": 3, "mode": "standard"}
assert session_config.connect_timeout == 2
assert session_config.read_timeout == 15
@mock_aws
def test_aws_provider_timeouts_reach_session_config(self):
aws_provider = AwsProvider(connect_timeout=2, read_timeout=15)
assert aws_provider.session.session_config.connect_timeout == 2
assert aws_provider.session.session_config.read_timeout == 15
@mock_aws
def test_aws_set_up_session_forwards_timeouts(self):
aws_session = AwsSetUpSession(
aws_access_key_id="testing",
aws_secret_access_key="testing",
connect_timeout=2,
read_timeout=15,
)
assert aws_session._session.session_config.connect_timeout == 2
assert aws_session._session.session_config.read_timeout == 15
def test_get_default_session_config(self):
config = get_default_session_config()
assert config.user_agent_extra == BOTO3_USER_AGENT_EXTRA
assert config.retries == {"max_attempts": 3, "mode": "standard"}
assert config.connect_timeout == BOTO3_CONNECT_TIMEOUT
assert config.read_timeout == BOTO3_READ_TIMEOUT
def test_get_default_session_config_timeouts_from_env(self):
with mock.patch.dict(
os.environ,
{
"PROWLER_AWS_BOTO3_CONNECT_TIMEOUT": "3",
"PROWLER_AWS_BOTO3_READ_TIMEOUT": "20",
},
):
config = get_default_session_config()
assert config.connect_timeout == 3
assert config.read_timeout == 20
def test_set_session_config_argument_overrides_env_timeouts(self):
with mock.patch.dict(os.environ, {"PROWLER_AWS_BOTO3_CONNECT_TIMEOUT": "3"}):
config = AwsProvider.set_session_config(None, connect_timeout=7)
assert config.connect_timeout == 7
@pytest.mark.parametrize("raw", ["0", "-5", "ten", "1.5"])
def test_get_boto3_timeout_from_env_rejects_non_positive_integers(self, raw):
with mock.patch.dict(os.environ, {"PROWLER_AWS_BOTO3_CONNECT_TIMEOUT": raw}):
with raises(
AWSInvalidBoto3TimeoutError, match="PROWLER_AWS_BOTO3_CONNECT_TIMEOUT"
):
get_boto3_timeout_from_env("PROWLER_AWS_BOTO3_CONNECT_TIMEOUT", 10)
def test_get_boto3_timeout_from_env_blank_falls_back_to_default(self):
with mock.patch.dict(os.environ, {"PROWLER_AWS_BOTO3_CONNECT_TIMEOUT": " "}):
assert (
get_boto3_timeout_from_env("PROWLER_AWS_BOTO3_CONNECT_TIMEOUT", 10)
== 10
)
@mock_aws
@patch(
@@ -1,4 +1,4 @@
from unittest.mock import patch
from unittest.mock import MagicMock, patch
from boto3 import client
from moto import mock_aws
@@ -182,6 +182,59 @@ class Test_codebuild_project_uses_allowed_github_organizations:
)
assert result[0].region == AWS_REGION_EU_WEST_1
@mock_aws
def test_project_github_with_unlisted_roles(self):
# iam:ListRoles denied leaves iam_client.roles as None.
aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
codebuild_client = client("codebuild", region_name=AWS_REGION_EU_WEST_1)
codebuild_client.create_project(
name="test-project-github-unlisted-roles",
source={
"type": "GITHUB",
"location": "https://github.com/allowed-org/repo",
},
artifacts={"type": "NO_ARTIFACTS"},
environment={
"type": "LINUX_CONTAINER",
"image": "aws/codebuild/standard:4.0",
"computeType": "BUILD_GENERAL1_SMALL",
"environmentVariables": [],
},
serviceRole=f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:role/codebuild-test-role",
)
from prowler.providers.aws.services.codebuild.codebuild_service import Codebuild
iam_client = MagicMock()
iam_client.roles = None
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=aws_provider,
),
patch(
"prowler.providers.aws.services.codebuild.codebuild_project_uses_allowed_github_organizations.codebuild_project_uses_allowed_github_organizations.codebuild_client",
new=Codebuild(aws_provider),
),
patch(
"prowler.providers.aws.services.codebuild.codebuild_project_uses_allowed_github_organizations.codebuild_project_uses_allowed_github_organizations.iam_client",
new=iam_client,
),
patch(
"prowler.providers.aws.services.codebuild.codebuild_project_uses_allowed_github_organizations.codebuild_project_uses_allowed_github_organizations.codebuild_client.audit_config",
{"codebuild_github_allowed_organizations": ["allowed-org"]},
),
):
from prowler.providers.aws.services.codebuild.codebuild_project_uses_allowed_github_organizations.codebuild_project_uses_allowed_github_organizations import (
codebuild_project_uses_allowed_github_organizations,
)
assert (
len(codebuild_project_uses_allowed_github_organizations().execute())
== 0
)
@mock_aws
def test_project_github_no_codebuild_trusted_principal(self):
aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
@@ -48,7 +48,7 @@ def _run(policies: list, scan_unused_services: bool = True):
iam_client = mock.MagicMock()
iam_client.policies = {policy.arn: policy for policy in policies}
iam_client.region = AWS_REGION_US_EAST_1
iam_client.provider.scan_unused_services = scan_unused_services
iam_client.provider = mock.MagicMock(scan_unused_services=scan_unused_services)
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
@@ -105,7 +105,8 @@ def _run(policies: list, scan_unused_services: bool = True):
iam_client = mock.MagicMock()
iam_client.policies = {policy.arn: policy for policy in policies}
iam_client.region = AWS_REGION_US_EAST_1
iam_client.provider.scan_unused_services = scan_unused_services
# Own mock: other test files set MagicMock.provider at class level to a real AwsProvider.
iam_client.provider = mock.MagicMock(scan_unused_services=scan_unused_services)
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
@@ -93,6 +93,10 @@ class Test_iam_role_service_trust_restricts_source_to_account:
"""An account with no roles produces no reports at all."""
assert len(_run([])) == 0
def test_unlisted_roles_produce_no_reports(self):
# iam:ListRoles denied leaves iam_client.roles as None.
assert len(_run(None)) == 0
def test_service_linked_role_skipped(self):
"""A service-linked role is excluded even when its trust policy would FAIL.
@@ -15,7 +15,7 @@ FINDING_ARN = (
class Test_inspector2_active_findings_exist:
def test_enabled_no_finding(self):
# Mock the inspector2 client
inspector2_client = mock.MagicMock
inspector2_client = mock.MagicMock()
inspector2_client.provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
inspector2_client.audited_account = AWS_ACCOUNT_NUMBER
@@ -69,7 +69,7 @@ class Test_inspector2_active_findings_exist:
def test_enabled_with_no_active_finding(self):
# Mock the inspector2 client
inspector2_client = mock.MagicMock
inspector2_client = mock.MagicMock()
inspector2_client.provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
inspector2_client.audited_account = AWS_ACCOUNT_NUMBER
@@ -123,7 +123,7 @@ class Test_inspector2_active_findings_exist:
def test_enabled_with_active_finding(self):
# Mock the inspector2 client
inspector2_client = mock.MagicMock
inspector2_client = mock.MagicMock()
inspector2_client.provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
inspector2_client.audited_account = AWS_ACCOUNT_NUMBER
@@ -176,7 +176,7 @@ class Test_inspector2_active_findings_exist:
def test_enabled_with_none_finding(self):
# Mock the inspector2 client
inspector2_client = mock.MagicMock
inspector2_client = mock.MagicMock()
inspector2_client.provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
inspector2_client.audited_account = AWS_ACCOUNT_NUMBER
@@ -219,14 +219,14 @@ class Test_inspector2_active_findings_exist:
def test_inspector2_disabled_ignoring(self):
# Mock the inspector2 client
inspector2_client = mock.MagicMock
awslambda_client = mock.MagicMock
inspector2_client = mock.MagicMock()
awslambda_client = mock.MagicMock()
awslambda_client.functions = {}
ecr_client = mock.MagicMock
ecr_client = mock.MagicMock()
ecr_client.registries = {}
ecr_client.registries[AWS_REGION_EU_WEST_1] = mock.MagicMock
ecr_client.registries[AWS_REGION_EU_WEST_1] = mock.MagicMock()
ecr_client.registries[AWS_REGION_EU_WEST_1].repositories = []
ec2_client = mock.MagicMock
ec2_client = mock.MagicMock()
ec2_client.instances = []
ec2_client.provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
ecr_client.provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
@@ -75,10 +75,10 @@ class Test_inspector2_is_enabled:
def test_inspector2_disabled(self):
# Mock the inspector2 client
inspector2_client = mock.MagicMock
awslambda_client = mock.MagicMock
ecr_client = mock.MagicMock
ec2_client = mock.MagicMock
inspector2_client = mock.MagicMock()
awslambda_client = mock.MagicMock()
ecr_client = mock.MagicMock()
ec2_client = mock.MagicMock()
ec2_client.provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
ecr_client.provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
awslambda_client.provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
@@ -133,7 +133,7 @@ class Test_inspector2_is_enabled:
def test_all_enabled(self):
# Mock the inspector2 client
inspector2_client = mock.MagicMock
inspector2_client = mock.MagicMock()
inspector2_client.provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
inspector2_client.audited_account = AWS_ACCOUNT_NUMBER
inspector2_client.audited_account_arn = (
@@ -235,7 +235,7 @@ class Test_inspector2_is_enabled:
assert result[0].region == AWS_REGION_EU_WEST_1
def test_ec2_disabled(self):
inspector2_client = mock.MagicMock
inspector2_client = mock.MagicMock()
inspector2_client.provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
inspector2_client.audited_account = AWS_ACCOUNT_NUMBER
inspector2_client.audited_account_arn = (
@@ -286,7 +286,7 @@ class Test_inspector2_is_enabled:
assert result[0].region == AWS_REGION_EU_WEST_1
def test_ecr_disabled(self):
inspector2_client = mock.MagicMock
inspector2_client = mock.MagicMock()
inspector2_client.provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
inspector2_client.audited_account = AWS_ACCOUNT_NUMBER
inspector2_client.audited_account_arn = (
@@ -337,7 +337,7 @@ class Test_inspector2_is_enabled:
assert result[0].region == AWS_REGION_EU_WEST_1
def test_lambda_disabled(self):
inspector2_client = mock.MagicMock
inspector2_client = mock.MagicMock()
inspector2_client.provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
inspector2_client.audited_account = AWS_ACCOUNT_NUMBER
inspector2_client.audited_account_arn = (
@@ -388,7 +388,7 @@ class Test_inspector2_is_enabled:
assert result[0].region == AWS_REGION_EU_WEST_1
def test_lambda_code_disabled(self):
inspector2_client = mock.MagicMock
inspector2_client = mock.MagicMock()
inspector2_client.provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
inspector2_client.audited_account = AWS_ACCOUNT_NUMBER
inspector2_client.audited_account_arn = (
@@ -439,7 +439,7 @@ class Test_inspector2_is_enabled:
assert result[0].region == AWS_REGION_EU_WEST_1
def test_ec2_ecr_disabled(self):
inspector2_client = mock.MagicMock
inspector2_client = mock.MagicMock()
inspector2_client.provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
inspector2_client.audited_account = AWS_ACCOUNT_NUMBER
inspector2_client.audited_account_arn = (
@@ -490,7 +490,7 @@ class Test_inspector2_is_enabled:
assert result[0].region == AWS_REGION_EU_WEST_1
def test_ec2_lambda_disabled(self):
inspector2_client = mock.MagicMock
inspector2_client = mock.MagicMock()
inspector2_client.provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
inspector2_client.audited_account = AWS_ACCOUNT_NUMBER
inspector2_client.audited_account_arn = (
@@ -541,7 +541,7 @@ class Test_inspector2_is_enabled:
assert result[0].region == AWS_REGION_EU_WEST_1
def test_ec2_lambda_code_disabled(self):
inspector2_client = mock.MagicMock
inspector2_client = mock.MagicMock()
inspector2_client.provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
inspector2_client.audited_account = AWS_ACCOUNT_NUMBER
inspector2_client.audited_account_arn = (
@@ -592,7 +592,7 @@ class Test_inspector2_is_enabled:
assert result[0].region == AWS_REGION_EU_WEST_1
def test_ecr_lambda_disabled(self):
inspector2_client = mock.MagicMock
inspector2_client = mock.MagicMock()
inspector2_client.provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
inspector2_client.audited_account = AWS_ACCOUNT_NUMBER
inspector2_client.audited_account_arn = (
@@ -643,7 +643,7 @@ class Test_inspector2_is_enabled:
assert result[0].region == AWS_REGION_EU_WEST_1
def test_ecr_lambda_code_disabled(self):
inspector2_client = mock.MagicMock
inspector2_client = mock.MagicMock()
inspector2_client.provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
inspector2_client.audited_account = AWS_ACCOUNT_NUMBER
inspector2_client.audited_account_arn = (
@@ -694,7 +694,7 @@ class Test_inspector2_is_enabled:
assert result[0].region == AWS_REGION_EU_WEST_1
def test_lambda_lambda_code_disabled(self):
inspector2_client = mock.MagicMock
inspector2_client = mock.MagicMock()
inspector2_client.provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
inspector2_client.audited_account = AWS_ACCOUNT_NUMBER
inspector2_client.audited_account_arn = (
@@ -745,7 +745,7 @@ class Test_inspector2_is_enabled:
assert result[0].region == AWS_REGION_EU_WEST_1
def test_ec2_ecr_lambda_disabled(self):
inspector2_client = mock.MagicMock
inspector2_client = mock.MagicMock()
inspector2_client.provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
inspector2_client.audited_account = AWS_ACCOUNT_NUMBER
inspector2_client.audited_account_arn = (
@@ -796,7 +796,7 @@ class Test_inspector2_is_enabled:
assert result[0].region == AWS_REGION_EU_WEST_1
def test_ec2_ecr_lambda_code_disabled(self):
inspector2_client = mock.MagicMock
inspector2_client = mock.MagicMock()
inspector2_client.provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
inspector2_client.audited_account = AWS_ACCOUNT_NUMBER
inspector2_client.audited_account_arn = (
@@ -847,7 +847,7 @@ class Test_inspector2_is_enabled:
assert result[0].region == AWS_REGION_EU_WEST_1
def test_ec2_lambda_lambda_code_disabled(self):
inspector2_client = mock.MagicMock
inspector2_client = mock.MagicMock()
inspector2_client.provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
inspector2_client.audited_account = AWS_ACCOUNT_NUMBER
inspector2_client.audited_account_arn = (
@@ -898,7 +898,7 @@ class Test_inspector2_is_enabled:
assert result[0].region == AWS_REGION_EU_WEST_1
def test_ecr_lambda_lambda_code_disabled(self):
inspector2_client = mock.MagicMock
inspector2_client = mock.MagicMock()
inspector2_client.provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
inspector2_client.audited_account = AWS_ACCOUNT_NUMBER
inspector2_client.audited_account_arn = (
@@ -13,7 +13,7 @@ from tests.providers.aws.utils import (
class Test_macie_automated_sensitive_data_discovery_enabled:
@mock_aws
def test_macie_disabled(self):
macie_client = mock.MagicMock
macie_client = mock.MagicMock()
macie_client.provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
macie_client.audited_account = AWS_ACCOUNT_NUMBER
macie_client.audited_account_arn = f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root"
@@ -56,7 +56,7 @@ class Test_macie_automated_sensitive_data_discovery_enabled:
@mock_aws
def test_macie_enabled_automated_discovery_disabled(self):
macie_client = mock.MagicMock
macie_client = mock.MagicMock()
macie_client.provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
macie_client.audited_account = AWS_ACCOUNT_NUMBER
macie_client.audited_account_arn = f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root"
@@ -109,7 +109,7 @@ class Test_macie_automated_sensitive_data_discovery_enabled:
@mock_aws
def test_macie_enabled_automated_discovery_enabled(self):
macie_client = mock.MagicMock
macie_client = mock.MagicMock()
macie_client.provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
macie_client.audited_account = AWS_ACCOUNT_NUMBER
macie_client.audited_account_arn = f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root"
@@ -14,12 +14,12 @@ from tests.providers.aws.utils import (
class Test_macie_is_enabled:
@mock_aws
def test_macie_disabled(self):
s3_client = mock.MagicMock
s3_client = mock.MagicMock()
s3_client.provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
s3_client.buckets = {}
s3_client.regions_with_buckets = []
macie_client = mock.MagicMock
macie_client = mock.MagicMock()
macie_client.provider = set_mocked_aws_provider(
[AWS_REGION_EU_WEST_1], create_default_organization=False
)
@@ -74,12 +74,12 @@ class Test_macie_is_enabled:
@mock_aws
def test_macie_enabled(self):
s3_client = mock.MagicMock
s3_client = mock.MagicMock()
s3_client.provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
s3_client.buckets = {}
s3_client.regions_with_buckets = []
macie_client = mock.MagicMock
macie_client = mock.MagicMock()
macie_client.provider = set_mocked_aws_provider(
[AWS_REGION_EU_WEST_1], create_default_organization=False
)
@@ -134,12 +134,12 @@ class Test_macie_is_enabled:
@mock_aws
def test_macie_suspended_ignored(self):
s3_client = mock.MagicMock
s3_client = mock.MagicMock()
s3_client.provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
s3_client.buckets = {}
s3_client.regions_with_buckets = []
macie_client = mock.MagicMock
macie_client = mock.MagicMock()
macie_client.provider = set_mocked_aws_provider(
[AWS_REGION_EU_WEST_1], create_default_organization=False
)
@@ -189,7 +189,7 @@ class Test_macie_is_enabled:
@mock_aws
def test_macie_suspended_ignored_with_buckets(self):
s3_client = mock.MagicMock
s3_client = mock.MagicMock()
s3_client.regions_with_buckets = [AWS_REGION_EU_WEST_1]
s3_client.provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
s3_client.buckets = [
@@ -200,7 +200,7 @@ class Test_macie_is_enabled:
)
]
macie_client = mock.MagicMock
macie_client = mock.MagicMock()
macie_client.provider = set_mocked_aws_provider(
[AWS_REGION_EU_WEST_1], create_default_organization=False
)
@@ -258,10 +258,10 @@ class Test_macie_is_enabled:
@mock_aws
def test_macie_suspended(self):
s3_client = mock.MagicMock
s3_client = mock.MagicMock()
s3_client.provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
macie_client = mock.MagicMock
macie_client = mock.MagicMock()
macie_client.provider = set_mocked_aws_provider(
[AWS_REGION_EU_WEST_1], create_default_organization=False
)
@@ -14,7 +14,7 @@ POLICY_ARN = "arn:aws:network-firewall:us-east-1:123456789012:firewall-policy/my
class Test_networkfirewall_deletion_protection:
def test_no_networkfirewall(self):
networkfirewall_client = mock.MagicMock
networkfirewall_client = mock.MagicMock()
networkfirewall_client.provider = set_mocked_aws_provider(
[AWS_REGION_US_EAST_1]
)
@@ -42,7 +42,7 @@ class Test_networkfirewall_deletion_protection:
assert len(result) == 0
def test_networkfirewall_deletion_protection_disabled(self):
networkfirewall_client = mock.MagicMock
networkfirewall_client = mock.MagicMock()
networkfirewall_client.provider = set_mocked_aws_provider(
[AWS_REGION_US_EAST_1]
)
@@ -89,7 +89,7 @@ class Test_networkfirewall_deletion_protection:
assert result[0].resource_arn == FIREWALL_ARN
def test_networkfirewall_deletion_protection_enabled(self):
networkfirewall_client = mock.MagicMock
networkfirewall_client = mock.MagicMock()
networkfirewall_client.provider = set_mocked_aws_provider(
[AWS_REGION_US_EAST_1]
)
@@ -15,13 +15,13 @@ POLICY_ARN = "arn:aws:network-firewall:us-east-1:123456789012:firewall-policy/my
class Test_networkfirewall_in_all_vpc:
def test_no_vpcs(self):
networkfirewall_client = mock.MagicMock
networkfirewall_client = mock.MagicMock()
networkfirewall_client.provider = set_mocked_aws_provider(
[AWS_REGION_US_EAST_1]
)
networkfirewall_client.region = AWS_REGION_US_EAST_1
networkfirewall_client.network_firewalls = {}
vpc_client = mock.MagicMock
vpc_client = mock.MagicMock()
vpc_client.provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
vpc_client.region = AWS_REGION_US_EAST_1
vpc_client.vpcs = {}
@@ -51,7 +51,7 @@ class Test_networkfirewall_in_all_vpc:
assert len(result) == 0
def test_vpcs_with_firewall_all(self):
networkfirewall_client = mock.MagicMock
networkfirewall_client = mock.MagicMock()
networkfirewall_client.provider = set_mocked_aws_provider(
[AWS_REGION_US_EAST_1]
)
@@ -68,7 +68,7 @@ class Test_networkfirewall_in_all_vpc:
deletion_protection=True,
)
}
vpc_client = mock.MagicMock
vpc_client = mock.MagicMock()
vpc_client.provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
vpc_client.region = AWS_REGION_US_EAST_1
vpc_client.vpcs = {
@@ -134,13 +134,13 @@ class Test_networkfirewall_in_all_vpc:
assert result[0].resource_arn == "arn_test"
def test_vpcs_without_firewall(self):
networkfirewall_client = mock.MagicMock
networkfirewall_client = mock.MagicMock()
networkfirewall_client.provider = set_mocked_aws_provider(
[AWS_REGION_US_EAST_1]
)
networkfirewall_client.region = AWS_REGION_US_EAST_1
networkfirewall_client.network_firewalls = {}
vpc_client = mock.MagicMock
vpc_client = mock.MagicMock()
vpc_client.provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
vpc_client.region = AWS_REGION_US_EAST_1
vpc_client.vpcs = {
@@ -206,14 +206,14 @@ class Test_networkfirewall_in_all_vpc:
assert result[0].resource_arn == "arn_test"
def test_vpcs_with_name_without_firewall(self):
networkfirewall_client = mock.MagicMock
networkfirewall_client = mock.MagicMock()
networkfirewall_client.provider = set_mocked_aws_provider(
[AWS_REGION_US_EAST_1]
)
networkfirewall_client.region = AWS_REGION_US_EAST_1
networkfirewall_client.network_firewalls = {}
vpc_client = mock.MagicMock
vpc_client = mock.MagicMock()
vpc_client.provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
vpc_client.region = AWS_REGION_US_EAST_1
vpc_client.vpcs = {
@@ -279,7 +279,7 @@ class Test_networkfirewall_in_all_vpc:
assert result[0].resource_arn == "arn_test"
def test_vpcs_with_and_without_firewall(self):
networkfirewall_client = mock.MagicMock
networkfirewall_client = mock.MagicMock()
networkfirewall_client.provider = set_mocked_aws_provider(
[AWS_REGION_US_EAST_1]
)
@@ -296,7 +296,7 @@ class Test_networkfirewall_in_all_vpc:
deletion_protection=True,
)
}
vpc_client = mock.MagicMock
vpc_client = mock.MagicMock()
vpc_client.provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
vpc_client.region = AWS_REGION_US_EAST_1
vpc_client.vpcs = {
@@ -400,13 +400,13 @@ class Test_networkfirewall_in_all_vpc:
assert r.resource_arn == "arn_test"
def test_vpcs_without_firewall_ignoring(self):
networkfirewall_client = mock.MagicMock
networkfirewall_client = mock.MagicMock()
networkfirewall_client.provider = set_mocked_aws_provider(
[AWS_REGION_US_EAST_1]
)
networkfirewall_client.region = AWS_REGION_US_EAST_1
networkfirewall_client.network_firewalls = {}
vpc_client = mock.MagicMock
vpc_client = mock.MagicMock()
vpc_client.provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
vpc_client.region = AWS_REGION_US_EAST_1
vpc_client.vpcs = {
@@ -464,13 +464,13 @@ class Test_networkfirewall_in_all_vpc:
assert len(result) == 0
def test_vpcs_without_firewall_ignoring_vpc_in_use(self):
networkfirewall_client = mock.MagicMock
networkfirewall_client = mock.MagicMock()
networkfirewall_client.provider = set_mocked_aws_provider(
[AWS_REGION_US_EAST_1]
)
networkfirewall_client.region = AWS_REGION_US_EAST_1
networkfirewall_client.network_firewalls = {}
vpc_client = mock.MagicMock
vpc_client = mock.MagicMock()
vpc_client.provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
vpc_client.region = AWS_REGION_US_EAST_1
vpc_client.vpcs = {
@@ -17,7 +17,7 @@ POLICY_ARN = "arn:aws:network-firewall:us-east-1:123456789012:firewall-policy/my
class Test_networkfirewall_logging_enabled:
def test_no_networkfirewall(self):
networkfirewall_client = mock.MagicMock
networkfirewall_client = mock.MagicMock()
networkfirewall_client.provider = set_mocked_aws_provider(
[AWS_REGION_US_EAST_1]
)
@@ -45,7 +45,7 @@ class Test_networkfirewall_logging_enabled:
assert len(result) == 0
def test_networkfirewall_logging_disabled(self):
networkfirewall_client = mock.MagicMock
networkfirewall_client = mock.MagicMock()
networkfirewall_client.provider = set_mocked_aws_provider(
[AWS_REGION_US_EAST_1]
)
@@ -93,7 +93,7 @@ class Test_networkfirewall_logging_enabled:
assert result[0].resource_arn == FIREWALL_ARN
def test_networkfirewall_logging_enabled(self):
networkfirewall_client = mock.MagicMock
networkfirewall_client = mock.MagicMock()
networkfirewall_client.provider = set_mocked_aws_provider(
[AWS_REGION_US_EAST_1]
)
@@ -16,7 +16,7 @@ POLICY_ARN = "arn:aws:network-firewall:us-east-1:123456789012:firewall-policy/my
class Test_networkfirewall_multi_az:
def test_no_networkfirewall(self):
networkfirewall_client = mock.MagicMock
networkfirewall_client = mock.MagicMock()
networkfirewall_client.provider = set_mocked_aws_provider(
[AWS_REGION_US_EAST_1]
)
@@ -44,7 +44,7 @@ class Test_networkfirewall_multi_az:
assert len(result) == 0
def test_networkfirewall_multi_az_disabled(self):
networkfirewall_client = mock.MagicMock
networkfirewall_client = mock.MagicMock()
networkfirewall_client.provider = set_mocked_aws_provider(
[AWS_REGION_US_EAST_1]
)
@@ -97,7 +97,7 @@ class Test_networkfirewall_multi_az:
assert result[0].resource_arn == FIREWALL_ARN
def test_networkfirewall_multi_az_enabled(self):
networkfirewall_client = mock.MagicMock
networkfirewall_client = mock.MagicMock()
networkfirewall_client.provider = set_mocked_aws_provider(
[AWS_REGION_US_EAST_1]
)
@@ -14,7 +14,7 @@ POLICY_ARN = "arn:aws:network-firewall:us-east-1:123456789012:firewall-policy/my
class Test_networkfirewall_policy_default_action_fragmented_packets:
def test_no_networkfirewall(self):
networkfirewall_client = mock.MagicMock
networkfirewall_client = mock.MagicMock()
networkfirewall_client.provider = set_mocked_aws_provider(
[AWS_REGION_US_EAST_1]
)
@@ -42,7 +42,7 @@ class Test_networkfirewall_policy_default_action_fragmented_packets:
assert len(result) == 0
def test_networkfirewall_default_stateless_action_drop(self):
networkfirewall_client = mock.MagicMock
networkfirewall_client = mock.MagicMock()
networkfirewall_client.provider = set_mocked_aws_provider(
[AWS_REGION_US_EAST_1]
)
@@ -90,7 +90,7 @@ class Test_networkfirewall_policy_default_action_fragmented_packets:
assert result[0].resource_arn == FIREWALL_ARN
def test_networkfirewall_default_stateless_action_forward(self):
networkfirewall_client = mock.MagicMock
networkfirewall_client = mock.MagicMock()
networkfirewall_client.provider = set_mocked_aws_provider(
[AWS_REGION_US_EAST_1]
)
@@ -139,7 +139,7 @@ class Test_networkfirewall_policy_default_action_fragmented_packets:
assert result[0].resource_arn == FIREWALL_ARN
def test_networkfirewall_default_stateless_action_pass(self):
networkfirewall_client = mock.MagicMock
networkfirewall_client = mock.MagicMock()
networkfirewall_client.provider = set_mocked_aws_provider(
[AWS_REGION_US_EAST_1]
)
@@ -14,7 +14,7 @@ POLICY_ARN = "arn:aws:network-firewall:us-east-1:123456789012:firewall-policy/my
class Test_networkfirewall_policy_default_action_full_packets:
def test_no_networkfirewall(self):
networkfirewall_client = mock.MagicMock
networkfirewall_client = mock.MagicMock()
networkfirewall_client.provider = set_mocked_aws_provider(
[AWS_REGION_US_EAST_1]
)
@@ -42,7 +42,7 @@ class Test_networkfirewall_policy_default_action_full_packets:
assert len(result) == 0
def test_networkfirewall_policy_default_action_drop(self):
networkfirewall_client = mock.MagicMock
networkfirewall_client = mock.MagicMock()
networkfirewall_client.provider = set_mocked_aws_provider(
[AWS_REGION_US_EAST_1]
)
@@ -90,7 +90,7 @@ class Test_networkfirewall_policy_default_action_full_packets:
assert result[0].resource_arn == FIREWALL_ARN
def test_networkfirewall_policy_default_action_forward(self):
networkfirewall_client = mock.MagicMock
networkfirewall_client = mock.MagicMock()
networkfirewall_client.provider = set_mocked_aws_provider(
[AWS_REGION_US_EAST_1]
)
@@ -139,7 +139,7 @@ class Test_networkfirewall_policy_default_action_full_packets:
assert result[0].resource_arn == FIREWALL_ARN
def test_networkfirewall_policy_default_action_pass(self):
networkfirewall_client = mock.MagicMock
networkfirewall_client = mock.MagicMock()
networkfirewall_client.provider = set_mocked_aws_provider(
[AWS_REGION_US_EAST_1]
)
@@ -14,7 +14,7 @@ POLICY_ARN = "arn:aws:network-firewall:us-east-1:123456789012:firewall-policy/my
class Test_networkfirewall_policy_rule_group_associated:
def test_no_networkfirewall(self):
networkfirewall_client = mock.MagicMock
networkfirewall_client = mock.MagicMock()
networkfirewall_client.provider = set_mocked_aws_provider(
[AWS_REGION_US_EAST_1]
)
@@ -42,7 +42,7 @@ class Test_networkfirewall_policy_rule_group_associated:
assert len(result) == 0
def test_networkfirewall_policy_stateless_rule_group_associated(self):
networkfirewall_client = mock.MagicMock
networkfirewall_client = mock.MagicMock()
networkfirewall_client.provider = set_mocked_aws_provider(
[AWS_REGION_US_EAST_1]
)
@@ -92,7 +92,7 @@ class Test_networkfirewall_policy_rule_group_associated:
assert result[0].resource_arn == FIREWALL_ARN
def test_networkfirewall_policy_stateful_rule_group_associated(self):
networkfirewall_client = mock.MagicMock
networkfirewall_client = mock.MagicMock()
networkfirewall_client.provider = set_mocked_aws_provider(
[AWS_REGION_US_EAST_1]
)
@@ -142,7 +142,7 @@ class Test_networkfirewall_policy_rule_group_associated:
assert result[0].resource_arn == FIREWALL_ARN
def test_networkfirewall_policy_both_rule_groups_associated(self):
networkfirewall_client = mock.MagicMock
networkfirewall_client = mock.MagicMock()
networkfirewall_client.provider = set_mocked_aws_provider(
[AWS_REGION_US_EAST_1]
)
@@ -196,7 +196,7 @@ class Test_networkfirewall_policy_rule_group_associated:
assert result[0].resource_arn == FIREWALL_ARN
def test_networkfirewall_policy_no_rule_groups_associated(self):
networkfirewall_client = mock.MagicMock
networkfirewall_client = mock.MagicMock()
networkfirewall_client.provider = set_mocked_aws_provider(
[AWS_REGION_US_EAST_1]
)
@@ -472,6 +472,19 @@ class Test_rolesanywhere_profile_restricts_session_permissions:
assert result[0].status == "MANUAL"
assert "could not be evaluated" in result[0].status_extended
def test_unscoped_profile_with_unlisted_roles_is_manual(self):
# iam:ListRoles denied leaves iam_client.roles as None.
patches = _patched(
_build_client({PROFILE_ARN: _profile(role_arns=[ADMIN_ROLE_ARN])})
)
patches[-1].new.roles = None
with _enter(patches):
result = _run()
assert len(result) == 1
assert result[0].status == "MANUAL"
assert ADMIN_ROLE_ARN in result[0].status_extended
assert "could not be evaluated" in result[0].status_extended
def test_unscoped_profile_without_roles_passes(self):
with _enter(_patched(_build_client({PROFILE_ARN: _profile(role_arns=[])}))):
result = _run()
@@ -103,12 +103,6 @@ class TestSecretsManagerHasRestrictiveResourcePolicy:
with mock_aws():
aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
from prowler.providers.aws.services.secretsmanager.secretsmanager_has_restrictive_resource_policy.secretsmanager_has_restrictive_resource_policy import (
secretsmanager_client,
)
secretsmanager_client.secrets.clear()
with (
mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
+5 -1
View File
@@ -21,6 +21,7 @@ AWS_GOV_CLOUD_PARTITION = "aws-us-gov"
AWS_CHINA_PARTITION = "aws-cn"
AWS_EUSC_PARTITION = "aws-eusc"
AWS_ISO_PARTITION = "aws-iso"
AWS_ISO_B_PARTITION = "aws-iso-b"
# Root AWS Account
AWS_ACCOUNT_NUMBER = "123456789012"
@@ -51,9 +52,12 @@ AWS_REGION_CN_NORTH_1 = "cn-north-1"
# Gov Cloud Regions
AWS_REGION_GOV_CLOUD_US_EAST_1 = "us-gov-east-1"
AWS_REGION_GOV_CLOUD_US_WEST_1 = "us-gov-west-1"
# Iso Regions
AWS_REGION_ISO_GLOBAL = "aws-iso-global"
AWS_REGION_ISO_EAST_1 = "us-iso-east-1"
AWS_REGION_ISO_WEST_1 = "us-iso-west-1"
AWS_REGION_ISO_B_EAST_1 = "us-isob-east-1"
# European Sovereign Cloud Regions
AWS_REGION_EUSC_DE_EAST_1 = "eusc-de-east-1"

Some files were not shown because too many files have changed in this diff Show More