Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f7669649f0 | ||
|
|
510fc1108c | ||
|
|
19a2875e28 | ||
|
|
a2526d946b | ||
|
|
19269ff2a8 | ||
|
|
03d4c23551 | ||
|
|
18dc77f5ae | ||
|
|
39f20b883b | ||
|
|
94fbf76f5d | ||
|
|
c6156b20d3 | ||
|
|
286c1e4840 | ||
|
|
18453e592e | ||
|
|
86e4408f29 | ||
|
|
ae43d21efb | ||
|
|
7c84822fa3 | ||
|
|
51c5fa7168 | ||
|
|
e9121f5f1a | ||
|
|
821fe43efd | ||
|
|
9ffbb4b758 | ||
|
|
9c5285adc3 | ||
|
|
f295d290dd | ||
|
|
e5df95c259 | ||
|
|
b6a8af3c54 | ||
|
|
fb7064401b | ||
|
|
8d60f9703a | ||
|
|
ceb601028e |
@@ -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.41.1
|
||||
|
||||
# Social login credentials
|
||||
SOCIAL_GOOGLE_OAUTH_CALLBACK_URL="${AUTH_URL}/api/auth/callback/google"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -139,7 +139,7 @@ Every AWS provider scan will enqueue an Attack Paths ingestion job automatically
|
||||
| MongoDB Atlas | 10 | 3 | 1 | 8 | Official | UI, API, CLI |
|
||||
| LLM | [See `promptfoo` docs.](https://www.promptfoo.dev/docs/red-team/plugins/) | N/A | N/A | N/A | Official | CLI |
|
||||
| Image | N/A | N/A | N/A | N/A | Official | UI, API, CLI |
|
||||
| Google Workspace | 65 | 11 | 3 | 6 | Official | UI, API, CLI |
|
||||
| Google Workspace | 65 | 11 | 4 | 6 | Official | UI, API, CLI |
|
||||
| OpenStack | 34 | 5 | 1 | 9 | Official | UI, API, CLI |
|
||||
| Vercel | 26 | 6 | 1 | 8 | Official | UI, API, CLI |
|
||||
| Okta | 29 | 8 | 2 | 2 | Official | UI, API, CLI |
|
||||
|
||||
@@ -4,6 +4,18 @@ All notable changes to the **Prowler API** are documented in this file.
|
||||
|
||||
<!-- changelog: release notes start -->
|
||||
|
||||
## [1.42.0] (Prowler v5.41.0)
|
||||
|
||||
### 🚀 Added
|
||||
|
||||
- Jira issues created from Prowler Cloud now carry the `prowler`, `prowler-<provider>`, `prowler-<severity>`, `prowler-<check-id>`, and `prowler-finding-<finding-uid>` labels, a link back to the finding when `DJANGO_UI_BASE_URL` is configured, and the tenant name [(#12540)](https://github.com/prowler-cloud/prowler/pull/12540)
|
||||
|
||||
### 🐞 Fixed
|
||||
|
||||
- `POST /api/v1/mute-rules` now updates only each affected provider's latest completed scan and future scans, preventing historical reaggregation from flooding Celery queues [(#12681)](https://github.com/prowler-cloud/prowler/pull/12681)
|
||||
|
||||
---
|
||||
|
||||
## [1.41.0] (Prowler v5.40.0)
|
||||
|
||||
### 🐞 Fixed
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
Jira issues created from Prowler Cloud now carry the `prowler`, `prowler-<provider>`, `prowler-<severity>`, `prowler-<check-id>`, and `prowler-finding-<finding-uid>` labels, a link back to the finding when `DJANGO_UI_BASE_URL` is configured, and the tenant name
|
||||
@@ -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.41",
|
||||
"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.42.1"
|
||||
|
||||
# Shared ruff baseline (kept in sync with mcp_server/pyproject.toml).
|
||||
# target-version tracks this project's lowest supported Python.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: Prowler API
|
||||
version: 1.42.0
|
||||
version: 1.42.1
|
||||
description: |-
|
||||
Prowler API specification.
|
||||
|
||||
|
||||
@@ -18333,19 +18333,14 @@ class TestMuteRuleViewSet:
|
||||
assert len(data) == 2
|
||||
assert data[0]["id"] == str(mute_rules_fixture[first_index].id)
|
||||
|
||||
@patch("api.v1.views.chain")
|
||||
@patch("api.v1.views.reaggregate_all_finding_group_summaries_task.si")
|
||||
@patch("api.v1.views.mute_historical_findings_task.si")
|
||||
@patch("api.v1.views.mute_findings_in_latest_scans_task.apply_async")
|
||||
@patch("api.v1.views.transaction.on_commit", side_effect=lambda fn: fn())
|
||||
def test_mute_rules_create_valid(
|
||||
self,
|
||||
_mock_on_commit,
|
||||
mock_mute_signature,
|
||||
mock_reaggregate_signature,
|
||||
mock_chain,
|
||||
mock_mute_task,
|
||||
authenticated_client,
|
||||
findings_fixture,
|
||||
create_test_user,
|
||||
):
|
||||
"""Test creating a valid mute rule."""
|
||||
finding_ids = [str(findings_fixture[0].id)]
|
||||
@@ -18372,24 +18367,20 @@ class TestMuteRuleViewSet:
|
||||
assert response_data["attributes"]["name"] == "New Mute Rule"
|
||||
assert response_data["attributes"]["reason"] == "Security exception approved"
|
||||
|
||||
# Verify the finding was immediately muted
|
||||
from api.models import Finding
|
||||
|
||||
finding = Finding.objects.get(id=findings_fixture[0].id)
|
||||
assert finding.muted is True
|
||||
assert finding.muted_at is not None
|
||||
assert finding.muted_reason == "Security exception approved"
|
||||
assert finding.muted is False
|
||||
assert finding.muted_at is None
|
||||
assert finding.muted_reason is None
|
||||
|
||||
# Verify background task chain was called: mute → reaggregate all
|
||||
mock_mute_signature.assert_called_once()
|
||||
mock_reaggregate_signature.assert_called_once()
|
||||
mock_chain.assert_called_once_with(
|
||||
mock_mute_signature.return_value,
|
||||
mock_reaggregate_signature.return_value,
|
||||
mock_mute_task.assert_called_once_with(
|
||||
kwargs={
|
||||
"tenant_id": str(finding.tenant_id),
|
||||
"mute_rule_id": response_data["id"],
|
||||
"provider_ids": [str(finding.scan.provider_id)],
|
||||
}
|
||||
)
|
||||
mock_chain.return_value.apply_async.assert_called_once()
|
||||
|
||||
@patch("tasks.tasks.mute_historical_findings_task.apply_async")
|
||||
@patch("api.v1.views.mute_findings_in_latest_scans_task.apply_async")
|
||||
def test_mute_rules_create_converts_finding_ids_to_uids(
|
||||
self,
|
||||
mock_task,
|
||||
@@ -18425,7 +18416,7 @@ class TestMuteRuleViewSet:
|
||||
]
|
||||
assert set(mute_rule.finding_uids) == set(expected_uids)
|
||||
|
||||
@patch("tasks.tasks.mute_historical_findings_task.apply_async")
|
||||
@patch("api.v1.views.mute_findings_in_latest_scans_task.apply_async")
|
||||
def test_mute_rules_deduplicates_uids(
|
||||
self,
|
||||
mock_task,
|
||||
@@ -18492,10 +18483,10 @@ class TestMuteRuleViewSet:
|
||||
|
||||
finding1.refresh_from_db()
|
||||
finding2.refresh_from_db()
|
||||
assert finding1.muted is True
|
||||
assert finding2.muted is True
|
||||
assert finding1.muted is False
|
||||
assert finding2.muted is False
|
||||
|
||||
@patch("tasks.tasks.mute_historical_findings_task.apply_async")
|
||||
@patch("api.v1.views.mute_findings_in_latest_scans_task.apply_async")
|
||||
def test_mute_rules_create_overlap_detection_active(
|
||||
self,
|
||||
mock_task,
|
||||
@@ -18528,7 +18519,7 @@ class TestMuteRuleViewSet:
|
||||
"already muted" in error_detail.lower() or "overlap" in error_detail.lower()
|
||||
)
|
||||
|
||||
@patch("tasks.tasks.mute_historical_findings_task.apply_async")
|
||||
@patch("api.v1.views.mute_findings_in_latest_scans_task.apply_async")
|
||||
def test_mute_rules_create_no_overlap_with_inactive(
|
||||
self,
|
||||
mock_task,
|
||||
@@ -18584,7 +18575,7 @@ class TestMuteRuleViewSet:
|
||||
== "/data/attributes/finding_ids"
|
||||
)
|
||||
|
||||
@patch("tasks.tasks.mute_historical_findings_task.apply_async")
|
||||
@patch("api.v1.views.mute_findings_in_latest_scans_task.apply_async")
|
||||
def test_mute_rules_create_invalid_finding_ids(
|
||||
self, mock_task, authenticated_client
|
||||
):
|
||||
|
||||
@@ -244,7 +244,6 @@ from api.v1.serializers import (
|
||||
UserUpdateSerializer,
|
||||
)
|
||||
from botocore.exceptions import ClientError, NoCredentialsError, ParamValidationError
|
||||
from celery import chain
|
||||
from celery.result import AsyncResult
|
||||
from config.custom_logging import BackendLogger
|
||||
from config.env import env
|
||||
@@ -342,8 +341,7 @@ from tasks.tasks import (
|
||||
enqueue_scan_execution_on_commit,
|
||||
get_active_provider_scan,
|
||||
jira_integration_task,
|
||||
mute_historical_findings_task,
|
||||
reaggregate_all_finding_group_summaries_task,
|
||||
mute_findings_in_latest_scans_task,
|
||||
refresh_lighthouse_provider_models_task,
|
||||
)
|
||||
|
||||
@@ -7551,35 +7549,28 @@ class MuteRuleViewSet(BaseRLSViewSet):
|
||||
serializer = self.get_serializer(data=request.data)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
|
||||
# Create the mute rule
|
||||
tenant_id = str(request.tenant_id)
|
||||
finding_ids = serializer.validated_data["finding_ids"]
|
||||
provider_ids = list(
|
||||
dict.fromkeys(
|
||||
Finding.all_objects.filter(
|
||||
id__in=finding_ids, tenant_id=tenant_id
|
||||
).values_list("scan__provider_id", flat=True)
|
||||
)
|
||||
)
|
||||
|
||||
mute_rule = serializer.save()
|
||||
|
||||
tenant_id = str(request.tenant_id)
|
||||
finding_ids = request.data.get("finding_ids", [])
|
||||
|
||||
# Immediately mute the selected findings
|
||||
Finding.all_objects.filter(
|
||||
id__in=finding_ids, tenant_id=tenant_id, muted=False
|
||||
).update(
|
||||
muted=True,
|
||||
muted_at=mute_rule.inserted_at,
|
||||
muted_reason=mute_rule.reason,
|
||||
)
|
||||
|
||||
# Launch background task for historical muting + reaggregation
|
||||
transaction.on_commit(
|
||||
lambda: chain(
|
||||
mute_historical_findings_task.si(
|
||||
tenant_id=tenant_id,
|
||||
mute_rule_id=str(mute_rule.id),
|
||||
),
|
||||
reaggregate_all_finding_group_summaries_task.si(
|
||||
tenant_id=tenant_id,
|
||||
),
|
||||
).apply_async()
|
||||
lambda: mute_findings_in_latest_scans_task.apply_async(
|
||||
kwargs={
|
||||
"tenant_id": tenant_id,
|
||||
"mute_rule_id": str(mute_rule.id),
|
||||
"provider_ids": [str(provider_id) for provider_id in provider_ids],
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
# Return the created mute rule
|
||||
serializer = self.get_serializer(mute_rule)
|
||||
return Response(
|
||||
data=serializer.data,
|
||||
|
||||
@@ -1,63 +1,104 @@
|
||||
from collections.abc import Iterable
|
||||
|
||||
from api.db_utils import rls_transaction
|
||||
from api.models import Finding, MuteRule
|
||||
from api.models import Finding, MuteRule, Scan, StateChoices
|
||||
from celery.utils.log import get_task_logger
|
||||
from config.django.base import DJANGO_FINDINGS_BATCH_SIZE
|
||||
from tasks.utils import batched
|
||||
|
||||
logger = get_task_logger(__name__)
|
||||
|
||||
|
||||
def mute_historical_findings(tenant_id: str, mute_rule_id: str):
|
||||
"""
|
||||
Mute historical findings that match the given mute rule.
|
||||
def _mute_findings_for_rule(
|
||||
*,
|
||||
tenant_id: str,
|
||||
scan_id: str,
|
||||
finding_uids: Iterable[str],
|
||||
muted_at,
|
||||
muted_reason: str,
|
||||
) -> int:
|
||||
finding_uids = list(finding_uids)
|
||||
if not finding_uids:
|
||||
return 0
|
||||
|
||||
This function processes findings in batches, updating their muted status
|
||||
and adding the mute reason.
|
||||
return Finding.all_objects.filter(
|
||||
tenant_id=tenant_id,
|
||||
scan_id=scan_id,
|
||||
uid__in=finding_uids,
|
||||
muted=False,
|
||||
).update(
|
||||
muted=True,
|
||||
muted_at=muted_at,
|
||||
muted_reason=muted_reason,
|
||||
)
|
||||
|
||||
Args:
|
||||
tenant_id (str): The tenant ID for RLS context
|
||||
mute_rule_id (str): The ID of the mute rule to apply
|
||||
|
||||
Returns:
|
||||
dict: Summary of the muting operation with findings_muted count
|
||||
"""
|
||||
findings_muted_count = 0
|
||||
def mute_findings_in_latest_scans(
|
||||
tenant_id: str, mute_rule_id: str, provider_ids: list[str]
|
||||
) -> dict:
|
||||
"""Apply a mute rule to the latest completed scan of each provider."""
|
||||
provider_ids = list(dict.fromkeys(provider_ids))
|
||||
|
||||
# Get the list of UIDs to mute and the reason
|
||||
with rls_transaction(tenant_id):
|
||||
mute_rule = MuteRule.objects.get(id=mute_rule_id, tenant_id=tenant_id)
|
||||
finding_uids = mute_rule.finding_uids
|
||||
mute_reason = mute_rule.reason
|
||||
muted_at = mute_rule.inserted_at
|
||||
|
||||
# Query findings that match the UIDs and are not already muted
|
||||
with rls_transaction(tenant_id):
|
||||
findings_to_mute = Finding.objects.filter(
|
||||
tenant_id=tenant_id, uid__in=finding_uids, muted=False
|
||||
)
|
||||
total_findings = findings_to_mute.count()
|
||||
|
||||
logger.info(
|
||||
f"Processing {total_findings} findings for mute rule {mute_rule_id}"
|
||||
latest_scans = list(
|
||||
Scan.objects.filter(
|
||||
tenant_id=tenant_id,
|
||||
provider_id__in=provider_ids,
|
||||
state=StateChoices.COMPLETED,
|
||||
completed_at__isnull=False,
|
||||
)
|
||||
.order_by("provider_id", "-completed_at", "-inserted_at", "-id")
|
||||
.distinct("provider_id")
|
||||
.values_list("id", flat=True)
|
||||
)
|
||||
|
||||
if total_findings > 0:
|
||||
for batch, is_last in batched(
|
||||
findings_to_mute.iterator(), DJANGO_FINDINGS_BATCH_SIZE
|
||||
):
|
||||
batch_ids = [f.id for f in batch]
|
||||
updated_count = Finding.all_objects.filter(
|
||||
id__in=batch_ids, tenant_id=tenant_id
|
||||
).update(
|
||||
muted=True,
|
||||
muted_at=muted_at,
|
||||
muted_reason=mute_reason,
|
||||
)
|
||||
findings_muted_count += updated_count
|
||||
|
||||
logger.info(f"Muted {findings_muted_count} findings for rule {mute_rule_id}")
|
||||
changed_scan_ids = []
|
||||
findings_muted = 0
|
||||
for scan_id in latest_scans:
|
||||
updated = _mute_findings_for_rule(
|
||||
tenant_id=tenant_id,
|
||||
scan_id=str(scan_id),
|
||||
finding_uids=mute_rule.finding_uids,
|
||||
muted_at=mute_rule.inserted_at,
|
||||
muted_reason=mute_rule.reason,
|
||||
)
|
||||
if updated:
|
||||
findings_muted += updated
|
||||
changed_scan_ids.append(str(scan_id))
|
||||
|
||||
logger.info(
|
||||
"Muted %d findings in %d latest scans for rule %s",
|
||||
findings_muted,
|
||||
len(changed_scan_ids),
|
||||
mute_rule_id,
|
||||
)
|
||||
return {
|
||||
"findings_muted": findings_muted_count,
|
||||
"findings_muted": findings_muted,
|
||||
"rule_id": mute_rule_id,
|
||||
"scan_ids": changed_scan_ids,
|
||||
}
|
||||
|
||||
|
||||
def reconcile_scan_mute_rules(tenant_id: str, scan_id: str) -> dict:
|
||||
"""Apply the current enabled mute rules to one completed scan."""
|
||||
findings_muted = 0
|
||||
|
||||
with rls_transaction(tenant_id):
|
||||
mute_rules = MuteRule.objects.filter(tenant_id=tenant_id, enabled=True).values(
|
||||
"finding_uids", "reason", "inserted_at"
|
||||
)
|
||||
|
||||
for mute_rule in mute_rules:
|
||||
findings_muted += _mute_findings_for_rule(
|
||||
tenant_id=tenant_id,
|
||||
scan_id=scan_id,
|
||||
finding_uids=mute_rule["finding_uids"],
|
||||
muted_at=mute_rule["inserted_at"],
|
||||
muted_reason=mute_rule["reason"],
|
||||
)
|
||||
|
||||
logger.info(
|
||||
"Reconciled mute rules for scan %s; muted %d findings",
|
||||
scan_id,
|
||||
findings_muted,
|
||||
)
|
||||
return {"findings_muted": findings_muted, "scan_id": str(scan_id)}
|
||||
|
||||
@@ -73,7 +73,10 @@ from tasks.jobs.lighthouse_providers import (
|
||||
check_lighthouse_provider_connection,
|
||||
refresh_lighthouse_provider_models,
|
||||
)
|
||||
from tasks.jobs.muting import mute_historical_findings
|
||||
from tasks.jobs.muting import (
|
||||
mute_findings_in_latest_scans,
|
||||
reconcile_scan_mute_rules,
|
||||
)
|
||||
from tasks.jobs.orphan_recovery import reconcile_orphans
|
||||
from tasks.jobs.report import (
|
||||
STALE_TMP_OUTPUT_MAX_AGE_HOURS,
|
||||
@@ -526,6 +529,7 @@ def perform_scan_task(
|
||||
provider_id=provider_id,
|
||||
checks_to_execute=checks_to_execute,
|
||||
)
|
||||
reconcile_scan_mute_rules(tenant_id, scan_id)
|
||||
_perform_scan_complete_tasks(tenant_id, scan_id, provider_id)
|
||||
return result
|
||||
finally:
|
||||
@@ -635,6 +639,7 @@ def perform_scheduled_scan_task(self, tenant_id: str, provider_id: str):
|
||||
scan_id=str(scan_instance.id),
|
||||
provider_id=provider_id,
|
||||
)
|
||||
reconcile_scan_mute_rules(tenant_id, str(scan_instance.id))
|
||||
_perform_scan_complete_tasks(tenant_id, str(scan_instance.id), provider_id)
|
||||
return result
|
||||
finally:
|
||||
@@ -1188,85 +1193,48 @@ def aggregate_finding_group_summaries_task(tenant_id: str, scan_id: str):
|
||||
return aggregate_finding_group_summaries(tenant_id=tenant_id, scan_id=scan_id)
|
||||
|
||||
|
||||
@shared_task(
|
||||
base=RLSTask, name="reaggregate-all-finding-group-summaries", queue="overview"
|
||||
)
|
||||
@set_tenant(keep_tenant=True)
|
||||
def reaggregate_all_finding_group_summaries_task(tenant_id: str):
|
||||
"""Reaggregate every pre-aggregated summary table for this tenant.
|
||||
def _dispatch_scan_summary_reaggregation(tenant_id: str, scan_ids: list[str]) -> None:
|
||||
if not scan_ids:
|
||||
return
|
||||
|
||||
Mirrors the unbounded scope of `mute_historical_findings_task`: that task
|
||||
rewrites every Finding row whose UID matches a mute rule, with no time
|
||||
limit. To keep the pre-aggregated tables consistent with that update,
|
||||
this task re-runs the same per-scan aggregation pipeline that scan
|
||||
completion runs on the latest completed scan of every (provider, day)
|
||||
pair, rebuilding the tables that power the read endpoints:
|
||||
|
||||
- `ScanSummary` and `DailySeveritySummary` -> `/overviews/findings`,
|
||||
`/overviews/findings-severity`, `/overviews/services`.
|
||||
- `FindingGroupDailySummary` -> `/finding-groups` and
|
||||
`/finding-groups/latest`.
|
||||
- `ScanGroupSummary` -> `/overviews/resource-groups` (resource
|
||||
inventory).
|
||||
- `ScanCategorySummary` -> `/overviews/categories`.
|
||||
- `AttackSurfaceOverview` -> `/overviews/attack-surfaces`.
|
||||
|
||||
Per-scan pipelines are dispatched in parallel via a Celery group so
|
||||
wallclock scales with the worker pool.
|
||||
"""
|
||||
completed_scans = list(
|
||||
Scan.objects.filter(
|
||||
tenant_id=tenant_id,
|
||||
state=StateChoices.COMPLETED,
|
||||
completed_at__isnull=False,
|
||||
)
|
||||
.order_by("-completed_at")
|
||||
.values("id", "completed_at", "provider_id")
|
||||
logger.info(
|
||||
"Reaggregating overview/finding summaries for %d latest scans",
|
||||
len(scan_ids),
|
||||
)
|
||||
|
||||
# Keep the latest scan per (provider, day) pair so the daily summary row
|
||||
# the aggregator writes is the most recent snapshot of that day for that
|
||||
# provider. Iterating from most recent to oldest means the first scan we
|
||||
# see for a given key wins.
|
||||
latest_scans: dict[tuple, str] = {}
|
||||
for scan in completed_scans:
|
||||
key = (scan["provider_id"], scan["completed_at"].date())
|
||||
if key not in latest_scans:
|
||||
latest_scans[key] = str(scan["id"])
|
||||
|
||||
scan_ids = list(latest_scans.values())
|
||||
if scan_ids:
|
||||
logger.info(
|
||||
"Reaggregating overview/finding summaries for %d scans (provider x day)",
|
||||
len(scan_ids),
|
||||
)
|
||||
# DailySeveritySummary reads from ScanSummary, so ScanSummary must be
|
||||
# recomputed first; the other aggregators read Finding directly and
|
||||
# can run in parallel with the severity step.
|
||||
group(
|
||||
chain(
|
||||
perform_scan_summary_task.si(tenant_id=tenant_id, scan_id=scan_id),
|
||||
group(
|
||||
aggregate_daily_severity_task.si(
|
||||
tenant_id=tenant_id, scan_id=scan_id
|
||||
),
|
||||
aggregate_finding_group_summaries_task.si(
|
||||
tenant_id=tenant_id, scan_id=scan_id
|
||||
),
|
||||
aggregate_scan_resource_group_summaries_task.si(
|
||||
tenant_id=tenant_id, scan_id=scan_id
|
||||
),
|
||||
aggregate_scan_category_summaries_task.si(
|
||||
tenant_id=tenant_id, scan_id=scan_id
|
||||
),
|
||||
aggregate_attack_surface_task.si(
|
||||
tenant_id=tenant_id, scan_id=scan_id
|
||||
),
|
||||
group(
|
||||
chain(
|
||||
perform_scan_summary_task.si(tenant_id=tenant_id, scan_id=scan_id),
|
||||
group(
|
||||
aggregate_daily_severity_task.si(tenant_id=tenant_id, scan_id=scan_id),
|
||||
aggregate_finding_group_summaries_task.si(
|
||||
tenant_id=tenant_id, scan_id=scan_id
|
||||
),
|
||||
)
|
||||
for scan_id in scan_ids
|
||||
).apply_async()
|
||||
return {"scans_reaggregated": len(scan_ids)}
|
||||
aggregate_scan_resource_group_summaries_task.si(
|
||||
tenant_id=tenant_id, scan_id=scan_id
|
||||
),
|
||||
aggregate_scan_category_summaries_task.si(
|
||||
tenant_id=tenant_id, scan_id=scan_id
|
||||
),
|
||||
aggregate_attack_surface_task.si(tenant_id=tenant_id, scan_id=scan_id),
|
||||
),
|
||||
)
|
||||
for scan_id in scan_ids
|
||||
).apply_async()
|
||||
|
||||
|
||||
@shared_task(base=RLSTask, name="findings-mute-latest-scans", queue="overview")
|
||||
@set_tenant(keep_tenant=True)
|
||||
def mute_findings_in_latest_scans_task(
|
||||
tenant_id: str, mute_rule_id: str, provider_ids: list[str]
|
||||
):
|
||||
"""Apply a mute rule to current scans and rebuild only changed summaries."""
|
||||
result = mute_findings_in_latest_scans(
|
||||
tenant_id=tenant_id,
|
||||
mute_rule_id=mute_rule_id,
|
||||
provider_ids=provider_ids,
|
||||
)
|
||||
_dispatch_scan_summary_reaggregation(tenant_id, result["scan_ids"])
|
||||
return result
|
||||
|
||||
|
||||
@shared_task(base=RLSTask, name="lighthouse-connection-check")
|
||||
@@ -1467,25 +1435,3 @@ def generate_compliance_reports_task(tenant_id: str, scan_id: str, provider_id:
|
||||
generate_csa=True,
|
||||
generate_cis=True,
|
||||
)
|
||||
|
||||
|
||||
@shared_task(name="findings-mute-historical")
|
||||
def mute_historical_findings_task(tenant_id: str, mute_rule_id: str):
|
||||
"""
|
||||
Background task to mute all historical findings matching a mute rule.
|
||||
|
||||
This task processes findings in batches to avoid memory issues with large datasets.
|
||||
It updates the Finding.muted, Finding.muted_at, and Finding.muted_reason fields
|
||||
for all findings whose UID is in the mute rule's finding_uids list.
|
||||
|
||||
Args:
|
||||
tenant_id (str): The tenant ID for RLS context.
|
||||
mute_rule_id (str): The primary key of the MuteRule to apply.
|
||||
|
||||
Returns:
|
||||
dict: A dictionary containing:
|
||||
- 'findings_muted' (int): Total number of findings muted.
|
||||
- 'rule_id' (str): The mute rule ID.
|
||||
- 'status' (str): Final status ('completed').
|
||||
"""
|
||||
return mute_historical_findings(tenant_id, mute_rule_id)
|
||||
|
||||
@@ -1,531 +1,205 @@
|
||||
from datetime import UTC, datetime
|
||||
from datetime import UTC, datetime, timedelta
|
||||
from uuid import uuid4
|
||||
|
||||
import pytest
|
||||
from api.models import Finding, MuteRule
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from api.models import Finding, MuteRule, Scan, StateChoices
|
||||
from prowler.lib.check.models import Severity
|
||||
from prowler.lib.outputs.finding import Status
|
||||
from tasks.jobs.muting import mute_historical_findings
|
||||
from tasks.jobs.muting import (
|
||||
mute_findings_in_latest_scans,
|
||||
reconcile_scan_mute_rules,
|
||||
)
|
||||
|
||||
|
||||
def _create_finding(scan: Scan, uid: str) -> Finding:
|
||||
return Finding.objects.create(
|
||||
tenant_id=scan.tenant_id,
|
||||
uid=uid,
|
||||
scan=scan,
|
||||
status=Status.FAIL,
|
||||
status_extended="Test finding",
|
||||
impact=Severity.high,
|
||||
severity=Severity.high,
|
||||
raw_result={},
|
||||
check_id="test_check",
|
||||
check_metadata={"CheckId": "test_check"},
|
||||
muted=False,
|
||||
)
|
||||
|
||||
|
||||
def _create_mute_rule(tenant_id, user, finding_uids, *, enabled=True) -> MuteRule:
|
||||
return MuteRule.objects.create(
|
||||
tenant_id=tenant_id,
|
||||
name=f"Mute rule {uuid4()}",
|
||||
reason="Approved exception",
|
||||
enabled=enabled,
|
||||
created_by=user,
|
||||
finding_uids=finding_uids,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
class TestMuteHistoricalFindings:
|
||||
"""
|
||||
Test suite for the mute_historical_findings function.
|
||||
class TestMuteFindingsInLatestScans:
|
||||
def test_mutes_latest_scan_and_leaves_older_scan_unchanged(
|
||||
self, scans_fixture, create_test_user
|
||||
):
|
||||
latest_scan = scans_fixture[0]
|
||||
older_scan = Scan.objects.create(
|
||||
tenant_id=latest_scan.tenant_id,
|
||||
provider=latest_scan.provider,
|
||||
name="Older scan",
|
||||
trigger=Scan.TriggerChoices.MANUAL,
|
||||
state=StateChoices.COMPLETED,
|
||||
started_at=datetime.now(UTC) - timedelta(days=1),
|
||||
completed_at=datetime.now(UTC) - timedelta(days=1),
|
||||
)
|
||||
uid = "latest-scan-only"
|
||||
older_finding = _create_finding(older_scan, uid)
|
||||
latest_finding = _create_finding(latest_scan, uid)
|
||||
mute_rule = _create_mute_rule(latest_scan.tenant_id, create_test_user, [uid])
|
||||
|
||||
This class tests the batch processing of findings to update their muted status
|
||||
based on MuteRule criteria.
|
||||
"""
|
||||
result = mute_findings_in_latest_scans(
|
||||
str(latest_scan.tenant_id),
|
||||
str(mute_rule.id),
|
||||
[str(latest_scan.provider_id)],
|
||||
)
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
def test_user(self, create_test_user):
|
||||
"""Create a test user for mute rule creation."""
|
||||
return create_test_user
|
||||
older_finding.refresh_from_db()
|
||||
latest_finding.refresh_from_db()
|
||||
assert older_finding.muted is False
|
||||
assert latest_finding.muted is True
|
||||
assert latest_finding.muted_at == mute_rule.inserted_at
|
||||
assert latest_finding.muted_reason == mute_rule.reason
|
||||
assert result == {
|
||||
"findings_muted": 1,
|
||||
"rule_id": str(mute_rule.id),
|
||||
"scan_ids": [str(latest_scan.id)],
|
||||
}
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
def mute_rule_with_findings(self, tenants_fixture, findings_fixture, test_user):
|
||||
"""
|
||||
Create a mute rule that targets the first finding in the fixture.
|
||||
"""
|
||||
def test_mutes_one_latest_scan_per_provider(self, scans_fixture, create_test_user):
|
||||
first_scan, second_scan, _ = scans_fixture
|
||||
uid = "shared-selected-uid"
|
||||
first_finding = _create_finding(first_scan, uid)
|
||||
second_finding = _create_finding(second_scan, uid)
|
||||
mute_rule = _create_mute_rule(first_scan.tenant_id, create_test_user, [uid])
|
||||
|
||||
result = mute_findings_in_latest_scans(
|
||||
str(first_scan.tenant_id),
|
||||
str(mute_rule.id),
|
||||
[str(first_scan.provider_id), str(second_scan.provider_id)],
|
||||
)
|
||||
|
||||
first_finding.refresh_from_db()
|
||||
second_finding.refresh_from_db()
|
||||
assert first_finding.muted is True
|
||||
assert second_finding.muted is True
|
||||
assert result["findings_muted"] == 2
|
||||
assert set(result["scan_ids"]) == {str(first_scan.id), str(second_scan.id)}
|
||||
|
||||
def test_provider_without_completed_scan_does_nothing(
|
||||
self, tenants_fixture, provider_factory, create_test_user
|
||||
):
|
||||
tenant = tenants_fixture[0]
|
||||
finding = findings_fixture[0]
|
||||
|
||||
mute_rule = MuteRule.objects.create(
|
||||
tenant_id=tenant.id,
|
||||
name="Test Mute Rule",
|
||||
reason="Testing mute functionality",
|
||||
enabled=True,
|
||||
created_by=test_user,
|
||||
finding_uids=[finding.uid],
|
||||
provider = provider_factory()
|
||||
mute_rule = _create_mute_rule(
|
||||
tenant.id, create_test_user, ["future-scan-finding"]
|
||||
)
|
||||
|
||||
return mute_rule
|
||||
result = mute_findings_in_latest_scans(
|
||||
str(tenant.id), str(mute_rule.id), [str(provider.id)]
|
||||
)
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
def mute_rule_multiple_findings(self, scans_fixture, test_user):
|
||||
"""
|
||||
Create multiple unmuted findings and a mute rule targeting all of them.
|
||||
"""
|
||||
assert result == {
|
||||
"findings_muted": 0,
|
||||
"rule_id": str(mute_rule.id),
|
||||
"scan_ids": [],
|
||||
}
|
||||
|
||||
def test_retry_does_not_report_changed_scans_twice(
|
||||
self, scans_fixture, create_test_user
|
||||
):
|
||||
scan = scans_fixture[0]
|
||||
tenant_id = scan.tenant_id
|
||||
|
||||
# Create 5 unmuted findings
|
||||
finding_uids = []
|
||||
for i in range(5):
|
||||
finding = Finding.objects.create(
|
||||
tenant_id=tenant_id,
|
||||
uid=f"test_finding_uid_mute_{i}",
|
||||
scan=scan,
|
||||
status=Status.FAIL,
|
||||
status_extended=f"Test status {i}",
|
||||
impact=Severity.high,
|
||||
severity=Severity.high,
|
||||
raw_result={
|
||||
"status": Status.FAIL,
|
||||
"impact": Severity.high,
|
||||
"severity": Severity.high,
|
||||
},
|
||||
check_id=f"test_check_id_{i}",
|
||||
check_metadata={
|
||||
"CheckId": f"test_check_id_{i}",
|
||||
"Description": f"Test description {i}",
|
||||
},
|
||||
muted=False,
|
||||
)
|
||||
finding_uids.append(finding.uid)
|
||||
|
||||
# Create mute rule targeting all findings
|
||||
mute_rule = MuteRule.objects.create(
|
||||
tenant_id=tenant_id,
|
||||
name="Test Multiple Findings Mute Rule",
|
||||
reason="Testing batch muting",
|
||||
enabled=True,
|
||||
created_by=test_user,
|
||||
finding_uids=finding_uids,
|
||||
finding = _create_finding(scan, "idempotent-mute")
|
||||
mute_rule = _create_mute_rule(scan.tenant_id, create_test_user, [finding.uid])
|
||||
args = (
|
||||
str(scan.tenant_id),
|
||||
str(mute_rule.id),
|
||||
[str(scan.provider_id)],
|
||||
)
|
||||
|
||||
return mute_rule, finding_uids
|
||||
first_result = mute_findings_in_latest_scans(*args)
|
||||
second_result = mute_findings_in_latest_scans(*args)
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
def mute_rule_already_muted(self, findings_fixture, test_user):
|
||||
"""
|
||||
Create a mute rule that targets an already-muted finding.
|
||||
"""
|
||||
tenant_id = findings_fixture[1].tenant_id
|
||||
already_muted_finding = findings_fixture[1]
|
||||
assert first_result["scan_ids"] == [str(scan.id)]
|
||||
assert second_result["findings_muted"] == 0
|
||||
assert second_result["scan_ids"] == []
|
||||
|
||||
mute_rule = MuteRule.objects.create(
|
||||
tenant_id=tenant_id,
|
||||
name="Test Already Muted Rule",
|
||||
reason="Testing already muted findings",
|
||||
enabled=True,
|
||||
created_by=test_user,
|
||||
finding_uids=[already_muted_finding.uid],
|
||||
def test_does_not_cross_tenant_boundary(
|
||||
self, tenants_fixture, provider_factory, create_test_user
|
||||
):
|
||||
tenant = tenants_fixture[0]
|
||||
other_tenant = tenants_fixture[2]
|
||||
other_provider = provider_factory(tenant=other_tenant)
|
||||
other_scan = Scan.objects.create(
|
||||
tenant_id=other_tenant.id,
|
||||
provider=other_provider,
|
||||
name="Other tenant scan",
|
||||
trigger=Scan.TriggerChoices.MANUAL,
|
||||
state=StateChoices.COMPLETED,
|
||||
started_at=datetime.now(UTC),
|
||||
completed_at=datetime.now(UTC),
|
||||
)
|
||||
other_finding = _create_finding(other_scan, "tenant-isolated-uid")
|
||||
mute_rule = _create_mute_rule(tenant.id, create_test_user, [other_finding.uid])
|
||||
|
||||
result = mute_findings_in_latest_scans(
|
||||
str(tenant.id), str(mute_rule.id), [str(other_provider.id)]
|
||||
)
|
||||
|
||||
return mute_rule
|
||||
other_finding.refresh_from_db()
|
||||
assert other_finding.muted is False
|
||||
assert result["scan_ids"] == []
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
def mute_rule_mixed_findings(self, scans_fixture, test_user):
|
||||
"""
|
||||
Create a mute rule with a mix of muted and unmuted findings.
|
||||
"""
|
||||
def test_nonexistent_rule_raises(self, tenants_fixture):
|
||||
with pytest.raises(MuteRule.DoesNotExist):
|
||||
mute_findings_in_latest_scans(str(tenants_fixture[0].id), str(uuid4()), [])
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
class TestReconcileScanMuteRules:
|
||||
def test_applies_only_enabled_rules_to_requested_scan(
|
||||
self, scans_fixture, create_test_user
|
||||
):
|
||||
scan = scans_fixture[0]
|
||||
tenant_id = scan.tenant_id
|
||||
|
||||
# Create 3 unmuted findings
|
||||
unmuted_uids = []
|
||||
for i in range(3):
|
||||
finding = Finding.objects.create(
|
||||
tenant_id=tenant_id,
|
||||
uid=f"unmuted_finding_{i}",
|
||||
scan=scan,
|
||||
status=Status.FAIL,
|
||||
status_extended=f"Unmuted status {i}",
|
||||
impact=Severity.medium,
|
||||
severity=Severity.medium,
|
||||
raw_result={
|
||||
"status": Status.FAIL,
|
||||
"impact": Severity.medium,
|
||||
"severity": Severity.medium,
|
||||
},
|
||||
check_id=f"unmuted_check_{i}",
|
||||
check_metadata={
|
||||
"CheckId": f"unmuted_check_{i}",
|
||||
"Description": f"Unmuted description {i}",
|
||||
},
|
||||
muted=False,
|
||||
)
|
||||
unmuted_uids.append(finding.uid)
|
||||
|
||||
# Create 2 already muted findings
|
||||
muted_uids = []
|
||||
for i in range(2):
|
||||
finding = Finding.objects.create(
|
||||
tenant_id=tenant_id,
|
||||
uid=f"muted_finding_{i}",
|
||||
scan=scan,
|
||||
status=Status.FAIL,
|
||||
status_extended=f"Muted status {i}",
|
||||
impact=Severity.low,
|
||||
severity=Severity.low,
|
||||
raw_result={
|
||||
"status": Status.FAIL,
|
||||
"impact": Severity.low,
|
||||
"severity": Severity.low,
|
||||
},
|
||||
check_id=f"muted_check_{i}",
|
||||
check_metadata={
|
||||
"CheckId": f"muted_check_{i}",
|
||||
"Description": f"Muted description {i}",
|
||||
},
|
||||
muted=True,
|
||||
muted_at=datetime.now(UTC),
|
||||
muted_reason="Already muted",
|
||||
)
|
||||
muted_uids.append(finding.uid)
|
||||
|
||||
# Create mute rule targeting all findings
|
||||
all_uids = unmuted_uids + muted_uids
|
||||
mute_rule = MuteRule.objects.create(
|
||||
tenant_id=tenant_id,
|
||||
name="Test Mixed Findings Rule",
|
||||
reason="Testing mixed muted/unmuted findings",
|
||||
enabled=True,
|
||||
created_by=test_user,
|
||||
finding_uids=all_uids,
|
||||
active_finding = _create_finding(scan, "active-rule-uid")
|
||||
disabled_finding = _create_finding(scan, "disabled-rule-uid")
|
||||
active_rule = _create_mute_rule(
|
||||
scan.tenant_id, create_test_user, [active_finding.uid]
|
||||
)
|
||||
|
||||
return mute_rule, unmuted_uids, muted_uids
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
def mute_rule_batch_test(self, scans_fixture, test_user):
|
||||
"""
|
||||
Create enough findings to test batch processing (>1000 for default batch size).
|
||||
"""
|
||||
scan = scans_fixture[0]
|
||||
tenant_id = scan.tenant_id
|
||||
|
||||
# Create 1500 findings to exceed default batch size of 1000
|
||||
finding_uids = []
|
||||
for i in range(1500):
|
||||
finding = Finding.objects.create(
|
||||
tenant_id=tenant_id,
|
||||
uid=f"batch_test_finding_{i}",
|
||||
scan=scan,
|
||||
status=Status.FAIL,
|
||||
status_extended=f"Batch test status {i}",
|
||||
impact=Severity.critical,
|
||||
severity=Severity.critical,
|
||||
raw_result={
|
||||
"status": Status.FAIL,
|
||||
"impact": Severity.critical,
|
||||
"severity": Severity.critical,
|
||||
},
|
||||
check_id=f"batch_test_check_{i}",
|
||||
check_metadata={
|
||||
"CheckId": f"batch_test_check_{i}",
|
||||
"Description": f"Batch test description {i}",
|
||||
},
|
||||
muted=False,
|
||||
)
|
||||
finding_uids.append(finding.uid)
|
||||
|
||||
# Create mute rule targeting all findings
|
||||
mute_rule = MuteRule.objects.create(
|
||||
tenant_id=tenant_id,
|
||||
name="Test Batch Processing Rule",
|
||||
reason="Testing batch processing functionality",
|
||||
enabled=True,
|
||||
created_by=test_user,
|
||||
finding_uids=finding_uids,
|
||||
_create_mute_rule(
|
||||
scan.tenant_id,
|
||||
create_test_user,
|
||||
[disabled_finding.uid],
|
||||
enabled=False,
|
||||
)
|
||||
|
||||
return mute_rule, finding_uids
|
||||
|
||||
def test_mute_historical_findings_single_finding(
|
||||
self, mute_rule_with_findings, findings_fixture
|
||||
):
|
||||
"""
|
||||
Test muting a single historical finding.
|
||||
"""
|
||||
mute_rule = mute_rule_with_findings
|
||||
tenant_id = str(mute_rule.tenant_id)
|
||||
finding = findings_fixture[0]
|
||||
|
||||
# Ensure the finding is not muted before execution
|
||||
finding.refresh_from_db()
|
||||
assert finding.muted is False
|
||||
assert finding.muted_at is None
|
||||
assert finding.muted_reason is None
|
||||
|
||||
# Execute the muting function
|
||||
result = mute_historical_findings(tenant_id, str(mute_rule.id))
|
||||
|
||||
# Verify return value
|
||||
assert result["findings_muted"] == 1
|
||||
assert result["rule_id"] == str(mute_rule.id)
|
||||
|
||||
# Verify the finding was muted
|
||||
finding.refresh_from_db()
|
||||
assert finding.muted is True
|
||||
assert finding.muted_at == mute_rule.inserted_at
|
||||
assert finding.muted_reason == mute_rule.reason
|
||||
|
||||
def test_mute_historical_findings_multiple_findings(
|
||||
self, mute_rule_multiple_findings
|
||||
):
|
||||
"""
|
||||
Test muting multiple historical findings.
|
||||
"""
|
||||
mute_rule, finding_uids = mute_rule_multiple_findings
|
||||
tenant_id = str(mute_rule.tenant_id)
|
||||
|
||||
# Verify all findings are unmuted
|
||||
findings = Finding.objects.filter(tenant_id=tenant_id, uid__in=finding_uids)
|
||||
assert findings.count() == 5
|
||||
for finding in findings:
|
||||
assert finding.muted is False
|
||||
|
||||
# Execute the muting function
|
||||
result = mute_historical_findings(tenant_id, str(mute_rule.id))
|
||||
|
||||
# Verify return value
|
||||
assert result["findings_muted"] == 5
|
||||
assert result["rule_id"] == str(mute_rule.id)
|
||||
|
||||
# Verify all findings were muted
|
||||
findings = Finding.objects.filter(tenant_id=tenant_id, uid__in=finding_uids)
|
||||
for finding in findings:
|
||||
assert finding.muted is True
|
||||
assert finding.muted_at == mute_rule.inserted_at
|
||||
assert finding.muted_reason == mute_rule.reason
|
||||
|
||||
def test_mute_historical_findings_already_muted(
|
||||
self, mute_rule_already_muted, findings_fixture
|
||||
):
|
||||
"""
|
||||
Test that already-muted findings are not counted or updated.
|
||||
"""
|
||||
mute_rule = mute_rule_already_muted
|
||||
tenant_id = str(mute_rule.tenant_id)
|
||||
finding = findings_fixture[1]
|
||||
|
||||
# Verify the finding is already muted
|
||||
finding.refresh_from_db()
|
||||
assert finding.muted is True
|
||||
original_muted_at = finding.muted_at
|
||||
original_muted_reason = finding.muted_reason
|
||||
|
||||
# Execute the muting function
|
||||
result = mute_historical_findings(tenant_id, str(mute_rule.id))
|
||||
|
||||
# Verify no findings were muted
|
||||
assert result["findings_muted"] == 0
|
||||
assert result["rule_id"] == str(mute_rule.id)
|
||||
|
||||
# Verify the finding's mute status did not change
|
||||
finding.refresh_from_db()
|
||||
assert finding.muted is True
|
||||
assert finding.muted_at == original_muted_at
|
||||
assert finding.muted_reason == original_muted_reason
|
||||
|
||||
def test_mute_historical_findings_mixed_status(self, mute_rule_mixed_findings):
|
||||
"""
|
||||
Test muting when some findings are already muted and others are not.
|
||||
"""
|
||||
mute_rule, unmuted_uids, muted_uids = mute_rule_mixed_findings
|
||||
tenant_id = str(mute_rule.tenant_id)
|
||||
|
||||
# Execute the muting function
|
||||
result = mute_historical_findings(tenant_id, str(mute_rule.id))
|
||||
|
||||
# Verify only unmuted findings were counted
|
||||
assert result["findings_muted"] == 3
|
||||
assert result["rule_id"] == str(mute_rule.id)
|
||||
|
||||
# Verify unmuted findings are now muted
|
||||
unmuted_findings = Finding.objects.filter(
|
||||
tenant_id=tenant_id, uid__in=unmuted_uids
|
||||
older_scan = Scan.objects.create(
|
||||
tenant_id=scan.tenant_id,
|
||||
provider=scan.provider,
|
||||
name="Older matching scan",
|
||||
trigger=Scan.TriggerChoices.MANUAL,
|
||||
state=StateChoices.COMPLETED,
|
||||
started_at=datetime.now(UTC) - timedelta(days=1),
|
||||
completed_at=datetime.now(UTC) - timedelta(days=1),
|
||||
)
|
||||
for finding in unmuted_findings:
|
||||
assert finding.muted is True
|
||||
assert finding.muted_at == mute_rule.inserted_at
|
||||
assert finding.muted_reason == mute_rule.reason
|
||||
older_finding = _create_finding(older_scan, active_finding.uid)
|
||||
|
||||
# Verify already-muted findings remained unchanged
|
||||
already_muted_findings = Finding.objects.filter(
|
||||
tenant_id=tenant_id, uid__in=muted_uids
|
||||
)
|
||||
for finding in already_muted_findings:
|
||||
assert finding.muted is True
|
||||
assert finding.muted_reason == "Already muted"
|
||||
result = reconcile_scan_mute_rules(str(scan.tenant_id), str(scan.id))
|
||||
|
||||
def test_mute_historical_findings_nonexistent_rule(self, tenants_fixture):
|
||||
"""
|
||||
Test that a nonexistent mute rule raises ObjectDoesNotExist.
|
||||
"""
|
||||
tenant_id = str(tenants_fixture[0].id)
|
||||
nonexistent_rule_id = str(uuid4())
|
||||
|
||||
with pytest.raises(ObjectDoesNotExist):
|
||||
mute_historical_findings(tenant_id, nonexistent_rule_id)
|
||||
|
||||
def test_mute_historical_findings_no_matching_findings(
|
||||
self, tenants_fixture, test_user
|
||||
):
|
||||
"""
|
||||
Test muting when no findings match the rule's UIDs.
|
||||
"""
|
||||
tenant_id = str(tenants_fixture[0].id)
|
||||
|
||||
# Create a mute rule with non-existent finding UIDs
|
||||
mute_rule = MuteRule.objects.create(
|
||||
tenant_id=tenant_id,
|
||||
name="Test No Match Rule",
|
||||
reason="Testing no matching findings",
|
||||
enabled=True,
|
||||
created_by=test_user,
|
||||
finding_uids=[
|
||||
"nonexistent_uid_1",
|
||||
"nonexistent_uid_2",
|
||||
"nonexistent_uid_3",
|
||||
],
|
||||
)
|
||||
|
||||
# Execute the muting function
|
||||
result = mute_historical_findings(tenant_id, str(mute_rule.id))
|
||||
|
||||
# Verify no findings were muted
|
||||
assert result["findings_muted"] == 0
|
||||
assert result["rule_id"] == str(mute_rule.id)
|
||||
|
||||
def test_mute_historical_findings_batch_processing(self, mute_rule_batch_test):
|
||||
"""
|
||||
Test that large numbers of findings are processed in batches correctly.
|
||||
"""
|
||||
mute_rule, finding_uids = mute_rule_batch_test
|
||||
tenant_id = str(mute_rule.tenant_id)
|
||||
|
||||
# Verify all findings exist and are unmuted
|
||||
findings = Finding.objects.filter(tenant_id=tenant_id, uid__in=finding_uids)
|
||||
assert findings.count() == 1500
|
||||
for finding in findings:
|
||||
assert finding.muted is False
|
||||
|
||||
# Execute the muting function
|
||||
result = mute_historical_findings(tenant_id, str(mute_rule.id))
|
||||
|
||||
# Verify return value
|
||||
assert result["findings_muted"] == 1500
|
||||
assert result["rule_id"] == str(mute_rule.id)
|
||||
|
||||
# Verify all findings were muted
|
||||
findings = Finding.objects.filter(tenant_id=tenant_id, uid__in=finding_uids)
|
||||
for finding in findings:
|
||||
assert finding.muted is True
|
||||
assert finding.muted_at == mute_rule.inserted_at
|
||||
assert finding.muted_reason == mute_rule.reason
|
||||
|
||||
def test_mute_historical_findings_preserves_muted_at_timestamp(
|
||||
self, mute_rule_with_findings, findings_fixture
|
||||
):
|
||||
"""
|
||||
Test that muted_at is set to the rule's inserted_at, not the current time.
|
||||
"""
|
||||
mute_rule = mute_rule_with_findings
|
||||
tenant_id = str(mute_rule.tenant_id)
|
||||
finding = findings_fixture[0]
|
||||
|
||||
# Execute the muting function
|
||||
result = mute_historical_findings(tenant_id, str(mute_rule.id))
|
||||
|
||||
# Verify the finding was muted
|
||||
assert result["findings_muted"] == 1
|
||||
|
||||
# Verify muted_at matches the rule's inserted_at timestamp
|
||||
finding.refresh_from_db()
|
||||
assert finding.muted_at == mute_rule.inserted_at
|
||||
assert finding.muted_at is not None
|
||||
|
||||
def test_mute_historical_findings_partial_match(self, scans_fixture, test_user):
|
||||
"""
|
||||
Test muting when only some of the rule's UIDs exist as findings.
|
||||
"""
|
||||
scan = scans_fixture[0]
|
||||
tenant_id = str(scan.tenant_id)
|
||||
|
||||
# Create 3 findings
|
||||
existing_uids = []
|
||||
for i in range(3):
|
||||
finding = Finding.objects.create(
|
||||
tenant_id=tenant_id,
|
||||
uid=f"partial_match_finding_{i}",
|
||||
scan=scan,
|
||||
status=Status.FAIL,
|
||||
status_extended=f"Partial match status {i}",
|
||||
impact=Severity.high,
|
||||
severity=Severity.high,
|
||||
raw_result={
|
||||
"status": Status.FAIL,
|
||||
"impact": Severity.high,
|
||||
"severity": Severity.high,
|
||||
},
|
||||
check_id=f"partial_match_check_{i}",
|
||||
check_metadata={
|
||||
"CheckId": f"partial_match_check_{i}",
|
||||
"Description": f"Partial match description {i}",
|
||||
},
|
||||
muted=False,
|
||||
)
|
||||
existing_uids.append(finding.uid)
|
||||
|
||||
# Create a mute rule with both existing and non-existing UIDs
|
||||
all_uids = existing_uids + [
|
||||
"nonexistent_uid_1",
|
||||
"nonexistent_uid_2",
|
||||
]
|
||||
mute_rule = MuteRule.objects.create(
|
||||
tenant_id=tenant_id,
|
||||
name="Test Partial Match Rule",
|
||||
reason="Testing partial matching",
|
||||
enabled=True,
|
||||
created_by=test_user,
|
||||
finding_uids=all_uids,
|
||||
)
|
||||
|
||||
# Execute the muting function
|
||||
result = mute_historical_findings(tenant_id, str(mute_rule.id))
|
||||
|
||||
# Verify only existing findings were muted
|
||||
assert result["findings_muted"] == 3
|
||||
assert result["rule_id"] == str(mute_rule.id)
|
||||
|
||||
# Verify the existing findings were muted
|
||||
findings = Finding.objects.filter(tenant_id=tenant_id, uid__in=existing_uids)
|
||||
assert findings.count() == 3
|
||||
for finding in findings:
|
||||
assert finding.muted is True
|
||||
assert finding.muted_at == mute_rule.inserted_at
|
||||
assert finding.muted_reason == mute_rule.reason
|
||||
|
||||
def test_mute_historical_findings_empty_uids(self, tenants_fixture, test_user):
|
||||
"""
|
||||
Test muting when the rule has an empty finding_uids array.
|
||||
"""
|
||||
tenant_id = str(tenants_fixture[0].id)
|
||||
|
||||
# Create a mute rule with empty finding_uids
|
||||
mute_rule = MuteRule.objects.create(
|
||||
tenant_id=tenant_id,
|
||||
name="Test Empty UIDs Rule",
|
||||
reason="Testing empty UIDs",
|
||||
enabled=True,
|
||||
created_by=test_user,
|
||||
finding_uids=[],
|
||||
)
|
||||
|
||||
# Execute the muting function
|
||||
result = mute_historical_findings(tenant_id, str(mute_rule.id))
|
||||
|
||||
# Verify no findings were muted
|
||||
assert result["findings_muted"] == 0
|
||||
assert result["rule_id"] == str(mute_rule.id)
|
||||
|
||||
def test_mute_historical_findings_return_format(self, mute_rule_with_findings):
|
||||
"""
|
||||
Test that the return value has the correct format and fields.
|
||||
"""
|
||||
mute_rule = mute_rule_with_findings
|
||||
tenant_id = str(mute_rule.tenant_id)
|
||||
|
||||
result = mute_historical_findings(tenant_id, str(mute_rule.id))
|
||||
|
||||
# Verify return value structure
|
||||
assert isinstance(result, dict)
|
||||
assert "findings_muted" in result
|
||||
assert "rule_id" in result
|
||||
assert isinstance(result["findings_muted"], int)
|
||||
assert isinstance(result["rule_id"], str)
|
||||
assert result["rule_id"] == str(mute_rule.id)
|
||||
active_finding.refresh_from_db()
|
||||
disabled_finding.refresh_from_db()
|
||||
older_finding.refresh_from_db()
|
||||
assert active_finding.muted is True
|
||||
assert active_finding.muted_at == active_rule.inserted_at
|
||||
assert disabled_finding.muted is False
|
||||
assert older_finding.muted is False
|
||||
assert result == {"findings_muted": 1, "scan_id": str(scan.id)}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import uuid
|
||||
from contextlib import contextmanager
|
||||
from datetime import UTC, datetime, timedelta
|
||||
from datetime import UTC, datetime
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import httpx
|
||||
@@ -33,10 +33,10 @@ from tasks.tasks import (
|
||||
check_integrations_task,
|
||||
check_lighthouse_provider_connection_task,
|
||||
generate_outputs_task,
|
||||
mute_findings_in_latest_scans_task,
|
||||
perform_attack_paths_scan_task,
|
||||
perform_scan_task,
|
||||
perform_scheduled_scan_task,
|
||||
reaggregate_all_finding_group_summaries_task,
|
||||
refresh_lighthouse_provider_models_task,
|
||||
s3_integration_task,
|
||||
security_hub_integration_task,
|
||||
@@ -2959,6 +2959,7 @@ class TestPerformScheduledScanTask:
|
||||
with (
|
||||
patch("tasks.tasks.perform_prowler_scan", side_effect=_complete_scan),
|
||||
patch("tasks.tasks._perform_scan_complete_tasks"),
|
||||
patch("tasks.tasks.reconcile_scan_mute_rules") as mock_reconcile,
|
||||
self._override_task_request(perform_scheduled_scan_task, id=task_id),
|
||||
):
|
||||
perform_scheduled_scan_task.run(
|
||||
@@ -2982,6 +2983,13 @@ class TestPerformScheduledScanTask:
|
||||
).count()
|
||||
== 1
|
||||
)
|
||||
completed_scan = Scan.objects.get(
|
||||
tenant_id=tenant.id,
|
||||
provider=provider,
|
||||
trigger=Scan.TriggerChoices.SCHEDULED,
|
||||
state=StateChoices.COMPLETED,
|
||||
)
|
||||
mock_reconcile.assert_called_once_with(str(tenant.id), str(completed_scan.id))
|
||||
assert (
|
||||
Scan.objects.filter(
|
||||
tenant_id=tenant.id,
|
||||
@@ -3176,7 +3184,10 @@ class TestPerformScanTask:
|
||||
task=queued_task,
|
||||
)
|
||||
|
||||
events = []
|
||||
|
||||
def _complete_scan(tenant_id, scan_id, provider_id, checks_to_execute=None):
|
||||
events.append("scan")
|
||||
scan_instance = Scan.objects.get(id=scan_id)
|
||||
scan_instance.state = StateChoices.COMPLETED
|
||||
scan_instance.save()
|
||||
@@ -3184,7 +3195,14 @@ class TestPerformScanTask:
|
||||
|
||||
with (
|
||||
patch("tasks.tasks.perform_prowler_scan", side_effect=_complete_scan),
|
||||
patch("tasks.tasks._perform_scan_complete_tasks"),
|
||||
patch(
|
||||
"tasks.tasks.reconcile_scan_mute_rules",
|
||||
side_effect=lambda *_args: events.append("reconcile"),
|
||||
),
|
||||
patch(
|
||||
"tasks.tasks._perform_scan_complete_tasks",
|
||||
side_effect=lambda *_args: events.append("summaries"),
|
||||
),
|
||||
patch("tasks.tasks.perform_scan_task.apply_async") as mock_apply_async,
|
||||
):
|
||||
with django_capture_on_commit_callbacks(execute=True):
|
||||
@@ -3196,6 +3214,7 @@ class TestPerformScanTask:
|
||||
|
||||
queued_task_result.refresh_from_db()
|
||||
assert result == {"status": "ok"}
|
||||
assert events == ["scan", "reconcile", "summaries"]
|
||||
assert queued_task_result.status == states.PENDING
|
||||
mock_apply_async.assert_called_once_with(
|
||||
kwargs={
|
||||
@@ -3241,10 +3260,7 @@ class TestPerformScanTask:
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
class TestReaggregateAllFindingGroupSummaries:
|
||||
def setup_method(self):
|
||||
self.tenant_id = str(uuid.uuid4())
|
||||
|
||||
class TestMuteFindingsInLatestScansTask:
|
||||
@patch("tasks.tasks.chain")
|
||||
@patch("tasks.tasks.group")
|
||||
@patch("tasks.tasks.aggregate_attack_surface_task")
|
||||
@@ -3253,10 +3269,10 @@ class TestReaggregateAllFindingGroupSummaries:
|
||||
@patch("tasks.tasks.aggregate_finding_group_summaries_task")
|
||||
@patch("tasks.tasks.aggregate_daily_severity_task")
|
||||
@patch("tasks.tasks.perform_scan_summary_task")
|
||||
@patch("tasks.tasks.Scan.objects.filter")
|
||||
def test_dispatches_subtasks_for_each_provider_per_day(
|
||||
@patch("tasks.tasks.mute_findings_in_latest_scans")
|
||||
def test_reaggregates_only_changed_scans(
|
||||
self,
|
||||
mock_scan_filter,
|
||||
mock_mute_findings,
|
||||
mock_scan_summary_task,
|
||||
mock_daily_severity_task,
|
||||
mock_finding_group_task,
|
||||
@@ -3265,119 +3281,36 @@ class TestReaggregateAllFindingGroupSummaries:
|
||||
mock_attack_surface_task,
|
||||
mock_group,
|
||||
mock_chain,
|
||||
tenants_fixture,
|
||||
):
|
||||
provider_id_1 = uuid.uuid4()
|
||||
provider_id_2 = uuid.uuid4()
|
||||
scan_id_today_p1 = uuid.uuid4()
|
||||
scan_id_yesterday_p1 = uuid.uuid4()
|
||||
scan_id_today_p2 = uuid.uuid4()
|
||||
today = datetime.now(tz=UTC)
|
||||
yesterday = today - timedelta(days=1)
|
||||
|
||||
mock_outer_group_result = MagicMock()
|
||||
# The first `group()` call wraps the inner parallel step; subsequent
|
||||
# calls wrap the outer per-scan generator.
|
||||
mock_group.side_effect = lambda *args, **kwargs: (
|
||||
list(args[0]) if args and hasattr(args[0], "__iter__") else None,
|
||||
mock_outer_group_result,
|
||||
)[1]
|
||||
|
||||
mock_scan_filter.return_value.order_by.return_value.values.return_value = [
|
||||
{
|
||||
"id": scan_id_today_p1,
|
||||
"completed_at": today,
|
||||
"provider_id": provider_id_1,
|
||||
},
|
||||
{
|
||||
"id": scan_id_today_p2,
|
||||
"completed_at": today,
|
||||
"provider_id": provider_id_2,
|
||||
},
|
||||
{
|
||||
"id": scan_id_yesterday_p1,
|
||||
"completed_at": yesterday,
|
||||
"provider_id": provider_id_1,
|
||||
},
|
||||
]
|
||||
|
||||
result = reaggregate_all_finding_group_summaries_task(tenant_id=self.tenant_id)
|
||||
|
||||
assert result == {"scans_reaggregated": 3}
|
||||
expected_scan_ids = {
|
||||
str(scan_id_today_p1),
|
||||
str(scan_id_today_p2),
|
||||
str(scan_id_yesterday_p1),
|
||||
tenant_id = str(tenants_fixture[0].id)
|
||||
mute_rule_id = str(uuid.uuid4())
|
||||
provider_ids = [str(uuid.uuid4()), str(uuid.uuid4())]
|
||||
scan_ids = [str(uuid.uuid4()), str(uuid.uuid4())]
|
||||
result = {
|
||||
"findings_muted": 2,
|
||||
"rule_id": mute_rule_id,
|
||||
"scan_ids": scan_ids,
|
||||
}
|
||||
for task_mock in (
|
||||
mock_scan_summary_task,
|
||||
mock_daily_severity_task,
|
||||
mock_finding_group_task,
|
||||
mock_resource_group_task,
|
||||
mock_category_task,
|
||||
mock_attack_surface_task,
|
||||
):
|
||||
assert task_mock.si.call_count == 3
|
||||
dispatched = {
|
||||
call.kwargs["scan_id"] for call in task_mock.si.call_args_list
|
||||
}
|
||||
assert dispatched == expected_scan_ids
|
||||
for call in task_mock.si.call_args_list:
|
||||
assert call.kwargs["tenant_id"] == self.tenant_id
|
||||
assert mock_chain.call_count == 3
|
||||
mock_outer_group_result.apply_async.assert_called_once()
|
||||
|
||||
@patch("tasks.tasks.chain")
|
||||
@patch("tasks.tasks.group")
|
||||
@patch("tasks.tasks.aggregate_attack_surface_task")
|
||||
@patch("tasks.tasks.aggregate_scan_category_summaries_task")
|
||||
@patch("tasks.tasks.aggregate_scan_resource_group_summaries_task")
|
||||
@patch("tasks.tasks.aggregate_finding_group_summaries_task")
|
||||
@patch("tasks.tasks.aggregate_daily_severity_task")
|
||||
@patch("tasks.tasks.perform_scan_summary_task")
|
||||
@patch("tasks.tasks.Scan.objects.filter")
|
||||
def test_dedupes_scans_to_latest_per_provider_per_day(
|
||||
self,
|
||||
mock_scan_filter,
|
||||
mock_scan_summary_task,
|
||||
mock_daily_severity_task,
|
||||
mock_finding_group_task,
|
||||
mock_resource_group_task,
|
||||
mock_category_task,
|
||||
mock_attack_surface_task,
|
||||
mock_group,
|
||||
mock_chain,
|
||||
):
|
||||
"""When several scans run on the same day for the same provider, only
|
||||
the latest one is dispatched (matching the daily summary unique key)."""
|
||||
provider_id = uuid.uuid4()
|
||||
latest_scan_today = uuid.uuid4()
|
||||
earlier_scan_today = uuid.uuid4()
|
||||
today_late = datetime.now(tz=UTC)
|
||||
today_early = today_late - timedelta(hours=4)
|
||||
|
||||
mock_mute_findings.return_value = result
|
||||
mock_outer_group_result = MagicMock()
|
||||
mock_group.side_effect = lambda *args, **kwargs: (
|
||||
list(args[0]) if args and hasattr(args[0], "__iter__") else None,
|
||||
mock_outer_group_result,
|
||||
)[1]
|
||||
|
||||
# Returned ordered by `-completed_at`, so the most recent comes first.
|
||||
mock_scan_filter.return_value.order_by.return_value.values.return_value = [
|
||||
{
|
||||
"id": latest_scan_today,
|
||||
"completed_at": today_late,
|
||||
"provider_id": provider_id,
|
||||
},
|
||||
{
|
||||
"id": earlier_scan_today,
|
||||
"completed_at": today_early,
|
||||
"provider_id": provider_id,
|
||||
},
|
||||
]
|
||||
task_result = mute_findings_in_latest_scans_task(
|
||||
tenant_id=tenant_id,
|
||||
mute_rule_id=mute_rule_id,
|
||||
provider_ids=provider_ids,
|
||||
)
|
||||
|
||||
result = reaggregate_all_finding_group_summaries_task(tenant_id=self.tenant_id)
|
||||
|
||||
assert result == {"scans_reaggregated": 1}
|
||||
assert task_result == result
|
||||
mock_mute_findings.assert_called_once_with(
|
||||
tenant_id=tenant_id,
|
||||
mute_rule_id=mute_rule_id,
|
||||
provider_ids=provider_ids,
|
||||
)
|
||||
for task_mock in (
|
||||
mock_scan_summary_task,
|
||||
mock_daily_severity_task,
|
||||
@@ -3386,23 +3319,35 @@ class TestReaggregateAllFindingGroupSummaries:
|
||||
mock_category_task,
|
||||
mock_attack_surface_task,
|
||||
):
|
||||
task_mock.si.assert_called_once_with(
|
||||
tenant_id=self.tenant_id, scan_id=str(latest_scan_today)
|
||||
)
|
||||
mock_chain.assert_called_once()
|
||||
assert task_mock.si.call_count == 2
|
||||
assert {
|
||||
call.kwargs["scan_id"] for call in task_mock.si.call_args_list
|
||||
} == set(scan_ids)
|
||||
assert mock_chain.call_count == 2
|
||||
mock_outer_group_result.apply_async.assert_called_once()
|
||||
|
||||
@patch("tasks.tasks.chain")
|
||||
@patch("tasks.tasks.group")
|
||||
@patch("tasks.tasks.Scan.objects.filter")
|
||||
def test_no_completed_scans_skips_dispatch(
|
||||
self, mock_scan_filter, mock_group, mock_chain
|
||||
@patch("tasks.tasks.mute_findings_in_latest_scans")
|
||||
def test_skips_reaggregation_when_no_scan_changed(
|
||||
self, mock_mute_findings, mock_group, mock_chain, tenants_fixture
|
||||
):
|
||||
mock_scan_filter.return_value.order_by.return_value.values.return_value = []
|
||||
tenant_id = str(tenants_fixture[0].id)
|
||||
mute_rule_id = str(uuid.uuid4())
|
||||
result = {
|
||||
"findings_muted": 0,
|
||||
"rule_id": mute_rule_id,
|
||||
"scan_ids": [],
|
||||
}
|
||||
mock_mute_findings.return_value = result
|
||||
|
||||
result = reaggregate_all_finding_group_summaries_task(tenant_id=self.tenant_id)
|
||||
task_result = mute_findings_in_latest_scans_task(
|
||||
tenant_id=tenant_id,
|
||||
mute_rule_id=mute_rule_id,
|
||||
provider_ids=[],
|
||||
)
|
||||
|
||||
assert result == {"scans_reaggregated": 0}
|
||||
assert task_result == result
|
||||
mock_group.assert_not_called()
|
||||
mock_chain.assert_not_called()
|
||||
|
||||
|
||||
@@ -4836,7 +4836,7 @@ wheels = [
|
||||
[[package]]
|
||||
name = "prowler"
|
||||
version = "5.41.0"
|
||||
source = { git = "https://github.com/prowler-cloud/prowler.git?rev=master#f05a490cd74a2c0f11a5d66d8ce29d03fa5c64a2" }
|
||||
source = { git = "https://github.com/prowler-cloud/prowler.git?rev=v5.41#18453e592e0a2550c726a754fda79870de428abf" }
|
||||
dependencies = [
|
||||
{ name = "alibabacloud-actiontrail20200706" },
|
||||
{ name = "alibabacloud-credentials" },
|
||||
@@ -4938,7 +4938,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "prowler-api"
|
||||
version = "1.42.0"
|
||||
version = "1.42.1"
|
||||
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.41" },
|
||||
{ name = "psycopg2-binary", specifier = "==2.9.9" },
|
||||
{ name = "pytest-celery", extras = ["redis"], specifier = "==1.3.0" },
|
||||
{ name = "reportlab", specifier = "==4.4.10" },
|
||||
|
||||
@@ -129,12 +129,42 @@ Each check **must** populate the `report.status` and `report.status_extended` fi
|
||||
- Status field: `report.status`
|
||||
- `PASS` – Assigned when the check confirms compliance with the configured value.
|
||||
- `FAIL` – Assigned when the check detects non-compliance with the configured value.
|
||||
- `MANUAL` – This status must not be used unless manual verification is necessary to determine whether the status (`report.status`) passes (`PASS`) or fails (`FAIL`).
|
||||
- `MANUAL` – This status must not be used unless manual verification is necessary to determine whether the status (`report.status`) passes (`PASS`) or fails (`FAIL`). This includes the case where Prowler could not retrieve the data needed to evaluate the resource (see below).
|
||||
|
||||
- Status extended field: `report.status_extended`
|
||||
- It **must** end with a period (`.`).
|
||||
- It **must** include the audited service, the resource, and a concise explanation of the check result, for instance: `EC2 AMI ami-0123456789 is not public.`.
|
||||
|
||||
### Permission and Data-Availability Errors Are Not Findings
|
||||
|
||||
A `FAIL` must only be emitted when an insecure condition has actually been detected. A check **must never** report `FAIL` because the underlying API call failed: missing permissions or scopes on the scanning identity, an API that is not enabled, a feature that is not licensed, or data that could not be retrieved are scan-configuration problems, not security issues. Reporting them as `FAIL` surfaces a misleading (and often high-severity) finding to the user and skews compliance scores.
|
||||
|
||||
When the service layer cannot obtain the data a check depends on, the check must:
|
||||
|
||||
1. Emit a single `MANUAL` finding scoped to the widest affected resource (the tenant, account, project or subscription), not one finding per resource. For example, if user registration details cannot be read, emit one tenant-level `MANUAL` instead of one per user.
|
||||
2. Explain in `status_extended` that the check could not be evaluated and what to fix, naming the permission, scope, API or license required, for instance: `Cannot evaluate credential exposure for privileged users: unable to query Microsoft Defender XDR Advanced Hunting. Verify that the ThreatHunting.Read.All permission is granted to the scanning application.`
|
||||
3. Leave the check's severity untouched. Do not override `report.check_metadata.Severity` to hide the problem.
|
||||
|
||||
The service layer must make the distinction possible: log the error and expose it to checks in a way that cannot be confused with a legitimate empty result. Common patterns already used in Prowler are:
|
||||
|
||||
- Defaulting the attribute to `None` (data could not be read) instead of `[]`/`{}` (data was read and is empty), e.g. the `metric_filters is not None` guard in `prowler/providers/aws/services/cloudwatch/lib/metric_filters.py`.
|
||||
- Keeping an availability flag raised on any denied listing, e.g. `logs_client.metric_filters_unavailable` consumed by the AWS CloudWatch metric filter checks.
|
||||
- Keeping an error flag or message next to the data, e.g. `entra_client.user_registration_details_error` in M365 or `*_scan_errors` in AWS Bedrock.
|
||||
- Keeping a set of resources whose lookup failed, e.g. `accessapproval_client.settings_lookup_failed` in GCP.
|
||||
|
||||
Make sure the error branch only captures real access errors. A `404`/not-found response frequently means the feature is simply not configured, which **is** a legitimate `FAIL`; a `403` or an unexpected exception is not. An "API not enabled" error is usually a scan-configuration problem too — **except** when the API's activation is itself the control being audited (e.g. GCP Access Approval: with `accessapproval.googleapis.com` disabled the feature provably cannot be enabled, so a definitive API-disabled state is a legitimate `FAIL`, while an undetermined state stays `MANUAL`).
|
||||
|
||||
```python
|
||||
if <service>_client.<data> is None:
|
||||
report = CheckReport<Provider>(metadata=self.metadata(), resource={})
|
||||
report.resource_name = "<Tenant/Account-level resource>"
|
||||
report.resource_id = "<stable-id>"
|
||||
report.status = "MANUAL"
|
||||
report.status_extended = "Cannot evaluate <requirement>: <data> could not be retrieved. Verify that <permission/API/license> is granted to the scanning identity."
|
||||
findings.append(report)
|
||||
return findings
|
||||
```
|
||||
|
||||
### Prowler's Check Severity Levels
|
||||
|
||||
The severity of each check is defined in the metadata file using the `Severity` field. Severity values are always lowercase and must be one of the predefined categories below.
|
||||
@@ -437,6 +467,7 @@ The metadata structure is enforced in code using a Pydantic model. For reference
|
||||
- Use clear, actionable, and user-friendly language in `status_extended` to explain the result. Always provide information to identify the resource.
|
||||
- Use helper functions/utilities for repeated logic to avoid code duplication. Save them in the `lib` folder of the service.
|
||||
- Handle exceptions gracefully: catch errors per resource, log them, and continue processing other resources.
|
||||
- Never report `FAIL` because data could not be retrieved (missing permissions, API not enabled, feature not licensed). Emit a single `MANUAL` finding explaining what is required instead; see [Permission and Data-Availability Errors Are Not Findings](#permission-and-data-availability-errors-are-not-findings).
|
||||
- Document the check with a class and function level docstring explaining what it does, what it checks, and any caveats or provider-specific behaviors.
|
||||
- Use type hints for the `execute()` method (e.g., `-> list[CheckReport<Provider>]`) for clarity and static analysis.
|
||||
- Ensure checks are efficient; avoid excessive nested loops. If the complexity is high, consider refactoring the check.
|
||||
|
||||
|
Before Width: | Height: | Size: 193 KiB After Width: | Height: | Size: 194 KiB |
|
Before Width: | Height: | Size: 185 KiB After Width: | Height: | Size: 187 KiB |
|
Before Width: | Height: | Size: 120 KiB After Width: | Height: | Size: 120 KiB |
|
Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 111 KiB |
|
Before Width: | Height: | Size: 156 KiB After Width: | Height: | Size: 156 KiB |
|
Before Width: | Height: | Size: 93 KiB After Width: | Height: | Size: 93 KiB |
@@ -51,6 +51,7 @@ The following list includes all the AWS checks with configurable variables that
|
||||
| `cloudtrail_threat_detection_privilege_escalation` | `threat_detection_privilege_escalation_actions` | List of Strings | See `config.yaml` |
|
||||
| `cloudtrail_threat_detection_privilege_escalation` | `threat_detection_privilege_escalation_minutes` | Integer | `1440` |
|
||||
| `cloudtrail_threat_detection_privilege_escalation` | `threat_detection_privilege_escalation_threshold` | Float | `0.2` |
|
||||
| `cloudwatch_log_group_agentcore_data_protection_policy_enabled` | `agentcore_log_group_name_prefixes` | List of Strings | See `config.yaml` |
|
||||
| `cloudwatch_log_group_no_secrets_in_logs` | `secrets_ignore_patterns` | List of Strings | `[]` |
|
||||
| `cloudwatch_log_group_retention_policy_specific_days_enabled` | `log_group_retention_days` | Integer | `365` |
|
||||
| `codebuild_project_no_secrets_in_variables` | `excluded_sensitive_environment_variables` | List of Strings | `[]` |
|
||||
|
||||
@@ -306,9 +306,21 @@ prowler image --registry internal-registry.local --registry-insecure
|
||||
```
|
||||
|
||||
<Warning>
|
||||
Skipping TLS verification disables certificate validation for registry connections. Use this flag only for trusted internal registries with self-signed certificates.
|
||||
Skipping TLS verification disables certificate validation for registry connections, including the Trivy image pull (`TRIVY_INSECURE`). Use this flag only for trusted internal registries with self-signed certificates.
|
||||
</Warning>
|
||||
|
||||
#### On-Premises Registries and Private Networks
|
||||
|
||||
<VersionBadge version="5.42.0" />
|
||||
|
||||
By default, Prowler rejects registry-provided URLs (token endpoints, pagination links) that resolve to non-public addresses, as an SSRF defense. On-premises registries live on private networks by definition, so to scan them declare the trusted ranges explicitly:
|
||||
|
||||
```bash
|
||||
export PROWLER_IMAGE_PROVIDER_ALLOWED_PRIVATE_NETWORKS="192.168.65.254/32,10.20.0.0/16"
|
||||
```
|
||||
|
||||
The value is a comma-separated list of IPs and CIDRs. A resolved address inside an allowlisted range is permitted; every other non-public address stays blocked, so link-local (`169.254.169.254`), loopback, and the rest of the internal network remain protected. The variable applies to registry enumeration and to the connection test. Malformed entries fail at startup, and a non-empty allowlist is logged as a relaxed security control. When unset, behavior is unchanged: only public addresses are followed.
|
||||
|
||||
#### Supported Registries
|
||||
|
||||
Registry Scan Mode supports the following registry types:
|
||||
|
||||
@@ -58,12 +58,14 @@ Two of these read more broadly than they behave, and both are worth understandin
|
||||
|
||||
On the consent screen, `chat:write.public` reads as permission to post in any public channel. Prowler never uses it that way: **Prowler only ever posts to the channels authorized on the integration.** The scope exists so that authorizing a public channel does not also require someone to invite the Prowler app to it first.
|
||||
|
||||
{/* The Prowler UI deep-links to this heading's anchor, so rewording the heading breaks that link. */}
|
||||
|
||||
### Why a Private Channel Is Missing From the Channel List
|
||||
|
||||
`groups:read` reveals only the private channels the Prowler app is already a member of. A private channel therefore appears in the channel list only after someone invites `@Prowler` to it in Slack:
|
||||
`groups:read` reveals only the private channels the Prowler app is already a member of. A private channel therefore appears in the channel list only after someone invites `@Prowler Cloud` to it in Slack:
|
||||
|
||||
```text
|
||||
/invite @Prowler
|
||||
/invite @Prowler Cloud
|
||||
```
|
||||
|
||||
That invite is issued in Slack, by that channel's own members, and **the invite itself is the permission grant** — no scope bypasses it. Prowler ships no in-product flow to get the app invited, because the decision belongs to the channel's members. After inviting the app, click **Refresh channels** to re-read the list.
|
||||
@@ -100,14 +102,14 @@ Prowler posts to the channels authorized on the integration. Several channels ca
|
||||
|
||||

|
||||
|
||||
2. Select one or more channels. A selected private channel keeps its lock and **Private** identification with the list closed, so the authorized set stays readable at a glance.
|
||||
2. Select one or more channels. A selected private channel keeps the same **Private** marking with the list closed, so the authorized set stays readable at a glance.
|
||||
3. Click **Save channels**.
|
||||
|
||||
Prowler validates the selection against Slack and derives each channel name itself, so a recorded name can never drift from the channel it belongs to. Once the set is saved, the page reports where Prowler posts and runs the connection check over it.
|
||||
|
||||
If the selection reports that no channels are available, the workspace exposes nothing Prowler can see. Create a public channel, or invite `@Prowler` to a private one, then click **Refresh channels**.
|
||||
If the selection reports that no channels are available, the workspace exposes nothing Prowler can see. Create a public channel, or invite `@Prowler Cloud` to a private one, then click **Refresh channels**.
|
||||
|
||||
A workspace can hold more channels than Prowler reads in one go. When that happens, the selection says so and lists what was read: every listed channel is usable, and a channel missing from a partial list is not necessarily one `@Prowler` has to be invited to. Only listed channels can be selected: **Refresh channels** repeats the same bounded read rather than reading further, and the selection's search filters what was already read, so neither surfaces a channel the read left out.
|
||||
A workspace can hold more channels than Prowler reads in one go. When that happens, the selection says so and lists what was read: every listed channel is usable, and a channel missing from a partial list is not necessarily one `@Prowler Cloud` has to be invited to. Only listed channels can be selected: **Refresh channels** repeats the same bounded read rather than reading further, and the selection's search filters what was already read, so neither surfaces a channel the read left out.
|
||||
|
||||
Saving a new selection replaces the authorized set: channels left out of it stop being authorized, and channels added to it are authorized but not yet confirmed. Changing which channels are in the set also resets the integration's connection state, so the check runs again over the new set — reordering the same channels does not. Saving an empty selection leaves the integration with no authorized channels, and **Test connection** cannot be run again until at least one channel is authorized.
|
||||
|
||||
@@ -159,7 +161,7 @@ The Slack management page reports the state of the connection and offers these a
|
||||
| Button | Purpose | Notes |
|
||||
|--------|---------|-------|
|
||||
| **Test connection** | Verify the credential and every authorized channel, and confirm the ones not confirmed yet | Posts the confirmation message once per channel and updates the last-checked time. Cannot be run until at least one channel is authorized |
|
||||
| **Refresh channels** | Re-read the workspace's channel list | Use after inviting `@Prowler` to a private channel |
|
||||
| **Refresh channels** | Re-read the workspace's channel list | Use after inviting `@Prowler Cloud` to a private channel |
|
||||
| **Save channels** | Record the selected channels as the integration's authorized set | Enabled once the selection differs from the authorized set |
|
||||
| **Disconnect** | Remove the integration and attempt to revoke access at Slack | ⚠️ **Cannot be undone** — confirm before disconnecting |
|
||||
|
||||
@@ -171,7 +173,7 @@ The Prowler Slack app is not configured for the deployment being used, so no wor
|
||||
|
||||
### A Private Channel Does Not Appear in the Channel List
|
||||
|
||||
The Prowler app has not been invited to it. In Slack, run `/invite @Prowler` in that channel, then click **Refresh channels**. Membership is the permission: no scope reveals a private channel the app is not in.
|
||||
The Prowler app has not been invited to it. In Slack, run `/invite @Prowler Cloud` in that channel, then click **Refresh channels**. Membership is the permission: no scope reveals a private channel the app is not in.
|
||||
|
||||
### Connection Test Fails
|
||||
|
||||
|
||||
@@ -4,6 +4,23 @@ All notable changes to the **Prowler MCP Server** are documented in this file.
|
||||
|
||||
<!-- changelog: release notes start -->
|
||||
|
||||
## [0.12.0] (Prowler v5.41.0)
|
||||
|
||||
### 🚀 Added
|
||||
|
||||
- Prowler App tools now report a failure as an MCP tool execution error (`isError: true`, explanation in `content`) instead of as a successful result carrying an `{"error": ...}` object, which clients and models read as a success [(#12532)](https://github.com/prowler-cloud/prowler/pull/12532)
|
||||
|
||||
### 🔄 Changed
|
||||
|
||||
- `prowler_get_compliance_framework_state_details` now rejects a call that passes both `scan_id` and `provider_id` instead of silently ignoring the provider, which could report on a scan belonging to a different provider than the one that was asked about [(#12532)](https://github.com/prowler-cloud/prowler/pull/12532)
|
||||
|
||||
### 🐞 Fixed
|
||||
|
||||
- `prowler_hub_get_check_code` and `prowler_hub_get_check_fixer` now report a check ID that belongs to another provider as such, naming that provider, instead of reporting the ID as one that does not exist [(#12533)](https://github.com/prowler-cloud/prowler/pull/12533)
|
||||
- `prowler_docs_search` no longer reports a failed search as zero matches or an unreadable answer as a bad search term, and `prowler_docs_get_document` no longer reports a failed fetch as a missing page [(#12534)](https://github.com/prowler-cloud/prowler/pull/12534)
|
||||
|
||||
---
|
||||
|
||||
## [0.11.0] (Prowler v5.40.0)
|
||||
|
||||
### 🚀 Added
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
Prowler App tools now report a failure as an MCP tool execution error (`isError: true`, explanation in `content`) instead of as a successful result carrying an `{"error": ...}` object, which clients and models read as a success
|
||||
@@ -1 +0,0 @@
|
||||
`prowler_get_compliance_framework_state_details` now rejects a call that passes both `scan_id` and `provider_id` instead of silently ignoring the provider, which could report on a scan belonging to a different provider than the one that was asked about
|
||||
@@ -1 +0,0 @@
|
||||
`prowler_docs_search` no longer reports a failed search as zero matches or an unreadable answer as a bad search term, and `prowler_docs_get_document` no longer reports a failed fetch as a missing page
|
||||
@@ -1 +0,0 @@
|
||||
`prowler_hub_get_check_code` and `prowler_hub_get_check_fixer` now report a check ID that belongs to another provider as such, naming that provider, instead of reporting the ID as one that does not exist
|
||||
@@ -0,0 +1 @@
|
||||
`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
|
||||
@@ -4,6 +4,49 @@ All notable changes to the **Prowler SDK** are documented in this file.
|
||||
|
||||
<!-- changelog: release notes start -->
|
||||
|
||||
## [5.41.0] (Prowler v5.41.0)
|
||||
|
||||
### 🚀 Added
|
||||
|
||||
- `memorydb_cluster_in_transit_encryption_enabled` check for AWS provider, verifying MemoryDB clusters have in-transit encryption (TLS) enabled [(#12246)](https://github.com/prowler-cloud/prowler/pull/12246)
|
||||
- `elasticbeanstalk_environment_no_secrets_in_configuration` check for AWS provider, scanning the option settings of every Elastic Beanstalk environment for hardcoded secrets [(#12378)](https://github.com/prowler-cloud/prowler/pull/12378)
|
||||
- CIS Google Workspace Foundations Benchmark v1.4.0 compliance framework [(#12513)](https://github.com/prowler-cloud/prowler/pull/12513)
|
||||
- `Jira.send_finding()` returns typed creation outcomes with the issue key, immutable ID and browse URL, and supports length-safe finding and delivery-attempt labels plus marker lookup for uncertain deliveries [(#12539)](https://github.com/prowler-cloud/prowler/pull/12539)
|
||||
- `Jira.get_issues_status()` resolves issue references by immutable ID in batches and returns explicit open, done, moved, missing, forbidden or unknown outcomes without treating missing issues as deleted [(#12539)](https://github.com/prowler-cloud/prowler/pull/12539)
|
||||
- `guardduty_ai_protection_enabled` check for AWS provider, flagging GuardDuty detectors without AI Protection, which analyzes AWS CloudTrail data events from Amazon Bedrock, Amazon Bedrock AgentCore and Amazon SageMaker AI; a detector that does not report the feature is `MANUAL` rather than `FAIL` [(#12564)](https://github.com/prowler-cloud/prowler/pull/12564)
|
||||
- `guardduty_runtime_monitoring_enabled` check for AWS provider, flagging GuardDuty detectors without unified Runtime Monitoring, the only feature that covers Amazon EC2 instances and Amazon ECS on AWS Fargate tasks in addition to Amazon EKS [(#12564)](https://github.com/prowler-cloud/prowler/pull/12564)
|
||||
- `ecr_registry_enhanced_scanning_enabled` check for AWS provider, verifying that the ECR registry scan type is enhanced (Amazon Inspector, covering programming language packages and continuous rescanning) instead of basic, and reporting MANUAL when the registry scanning configuration cannot be read [(#12660)](https://github.com/prowler-cloud/prowler/pull/12660)
|
||||
- `eks_cluster_vpc_cni_network_policy_enforced` check for AWS provider, flagging EKS clusters whose Amazon VPC CNI managed add-on does not enable Kubernetes network policy enforcement, and reporting MANUAL where the EKS API cannot show the setting [(#12661)](https://github.com/prowler-cloud/prowler/pull/12661)
|
||||
- `cloudwatch_log_group_agentcore_data_protection_policy_enabled` check for AWS provider, verifying that Bedrock AgentCore log groups mask sensitive data with a CloudWatch Logs data protection policy [(#12662)](https://github.com/prowler-cloud/prowler/pull/12662)
|
||||
- `iam_policy_no_agentcore_workload_access_token_wildcard` check for AWS provider, flagging customer-managed IAM policies that allow `bedrock-agentcore:GetWorkloadAccessToken`, `GetWorkloadAccessTokenForJWT` or `GetWorkloadAccessTokenForUserId` on resources reaching workload identities other than the caller's own, which AWS documents as the only binding on the unverified user ID the token is issued for [(#12664)](https://github.com/prowler-cloud/prowler/pull/12664)
|
||||
- `iam_policy_passrole_to_bedrock_agentcore_restricted` check for AWS provider, flagging customer-managed IAM policies that allow `iam:PassRole` over every role where the passed role can reach Bedrock AgentCore, so any principal holding the policy can run agent code under any role in the account [(#12664)](https://github.com/prowler-cloud/prowler/pull/12664)
|
||||
- `iam_role_service_trust_restricts_source_to_account` check for AWS provider, flagging IAM roles whose trust policy lets an AWS service principal assume the role without confining the request to a specific source account, including trust policies that `iam_role_cross_service_confused_deputy_prevention` does not evaluate [(#12664)](https://github.com/prowler-cloud/prowler/pull/12664)
|
||||
- `PROWLER_IMAGE_PROVIDER_ALLOWED_PRIVATE_NETWORKS` environment variable so the image provider can reach container registries on allowlisted private networks, keeping every other non-public address blocked [(#12678)](https://github.com/prowler-cloud/prowler/pull/12678)
|
||||
- `PROWLER_AWS_PARTITION` environment variable to select the AWS partition used for STS credential validation and scan bootstrap, with a clear error when the account belongs to a different partition [(#12680)](https://github.com/prowler-cloud/prowler/pull/12680)
|
||||
|
||||
### 🔄 Changed
|
||||
|
||||
- Google Workspace checks mapped to CIS evaluate the full audit procedure instead of a single condition, so Gmail spoofing actions, 2-Step Verification, password expiration and alert severity left on Google's defaults no longer pass [(#12513)](https://github.com/prowler-cloud/prowler/pull/12513)
|
||||
- `security_login_challenges_configured` and `security_2sv_enforced` unmapped from CIS Google Workspace 4.1.4.1 and CISA SCuBA 0.6 `GWS.COMMONCONTROLS.1.1`, whose Post-SSO verification and phishing-resistant MFA requirements neither check can prove [(#12513)](https://github.com/prowler-cloud/prowler/pull/12513)
|
||||
|
||||
### 🐞 Fixed
|
||||
|
||||
- GitHub repository discovery for unscoped scans now paginates beyond the first 100 accessible repositories instead of silently scanning only the first page [(#12460)](https://github.com/prowler-cloud/prowler/pull/12460)
|
||||
- `rules_*_alert_configured` checks no longer pass a rule whose delivery to the alert center is disabled, the setting behind the benchmark's "Ensure that Alerts is set to On" [(#12513)](https://github.com/prowler-cloud/prowler/pull/12513)
|
||||
- `security_password_policy_strong` no longer fails a domain that never touched the password strength setting: Google enforces strong passwords by default, so an unset value is the secure default and not a missing configuration [(#12513)](https://github.com/prowler-cloud/prowler/pull/12513)
|
||||
- `security_2sv_enforced` and `security_2sv_hardware_keys_admins` report MANUAL instead of judging domain-wide values that a group or a sub-organizational unit overrides, or that were dropped because the root organizational unit could not be resolved; a domain-wide failure is still reported as such, with the override noted [(#12513)](https://github.com/prowler-cloud/prowler/pull/12513)
|
||||
- `ecr_registry_scan_images_on_push_enabled` no longer passes a registry whose scanning rules are all `MANUAL`, nor describes a `CONTINUOUS_SCAN` registry as scanning on push; each rule's `scanFrequency` is now read instead of inferred from a rule's presence [(#12560)](https://github.com/prowler-cloud/prowler/pull/12560)
|
||||
- CloudWatch log metric filter checks no longer crash with `AttributeError` when the account has a metric filter whose log group was not retrieved [(#12561)](https://github.com/prowler-cloud/prowler/pull/12561)
|
||||
- `guardduty_eks_runtime_monitoring_enabled` no longer reports `FAIL` for detectors that use unified Runtime Monitoring; the GuardDuty service now reads the `RUNTIME_MONITORING` feature, which is mutually exclusive with `EKS_RUNTIME_MONITORING` and already covers Amazon EKS [(#12564)](https://github.com/prowler-cloud/prowler/pull/12564)
|
||||
- Checks no longer report `FAIL` when the scanning identity lacks permissions, an API is not enabled or a feature is not licensed; they now emit a single `MANUAL` finding naming what is required, across 28 M365, Azure, AWS and GCP checks [(#12645)](https://github.com/prowler-cloud/prowler/pull/12645)
|
||||
- `sagemaker_notebook_instance_without_direct_internet_access_configured` check logic to read the `DirectInternetAccess` setting instead of `RootAccess`, failing a notebook instance with direct internet access enabled even when root access is disabled [(#12659)](https://github.com/prowler-cloud/prowler/pull/12659)
|
||||
- Basic authentication fallback in the image provider when a registry rejects the negotiated bearer token, so registries like Harbor that guard catalog listing behind Basic can be enumerated [(#12678)](https://github.com/prowler-cloud/prowler/pull/12678)
|
||||
- Registry catalog listing when the server answers with a Bearer challenge after negotiating Basic (or anonymous) authentication, switching to a bearer token obtained from the challenge instead of failing [(#12678)](https://github.com/prowler-cloud/prowler/pull/12678)
|
||||
- `--registry-insecure` now propagates to Trivy via `TRIVY_INSECURE`, so images in registries with self-signed certificates can be pulled and scanned, not just enumerated [(#12678)](https://github.com/prowler-cloud/prowler/pull/12678)
|
||||
- Registry scans in the Image provider now skip non-image OCI artifacts (Helm charts, cosign signatures, SBOM attestations) and no longer abort the whole scan when Trivy fails on a single discovered image; registry enumeration also runs in parallel instead of one request at a time [(#12695)](https://github.com/prowler-cloud/prowler/pull/12695)
|
||||
|
||||
---
|
||||
|
||||
## [5.40.0] (Prowler v5.40.0)
|
||||
|
||||
### 🚀 Added
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
`PROWLER_AWS_PARTITION` environment variable to select the AWS partition used for STS credential validation and scan bootstrap, with a clear error when the account belongs to a different partition
|
||||
@@ -0,0 +1 @@
|
||||
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
|
||||
@@ -1 +0,0 @@
|
||||
`elasticbeanstalk_environment_no_secrets_in_configuration` check for AWS provider, scanning the option settings of every Elastic Beanstalk environment for hardcoded secrets
|
||||
@@ -1 +0,0 @@
|
||||
GitHub repository discovery for unscoped scans now paginates beyond the first 100 accessible repositories instead of silently scanning only the first page
|
||||
@@ -0,0 +1 @@
|
||||
`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
|
||||
@@ -1 +0,0 @@
|
||||
`Jira.send_finding()` returns typed creation outcomes with the issue key, immutable ID and browse URL, and supports length-safe finding and delivery-attempt labels plus marker lookup for uncertain deliveries
|
||||
@@ -1 +0,0 @@
|
||||
`Jira.get_issues_status()` resolves issue references by immutable ID in batches and returns explicit open, done, moved, missing, forbidden or unknown outcomes without treating missing issues as deleted
|
||||
@@ -0,0 +1 @@
|
||||
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
|
||||
@@ -1 +0,0 @@
|
||||
`memorydb_cluster_in_transit_encryption_enabled` check for AWS provider, verifying MemoryDB clusters have in-transit encryption (TLS) enabled
|
||||
@@ -0,0 +1 @@
|
||||
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
|
||||
@@ -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": [
|
||||
{
|
||||
|
||||
@@ -241,6 +241,7 @@
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_policy_allows_privilege_escalation",
|
||||
"iam_inline_policy_allows_privilege_escalation",
|
||||
"iam_policy_passrole_to_bedrock_agentcore_restricted",
|
||||
"iam_role_administratoraccess_policy",
|
||||
"iam_user_administrator_access_policy",
|
||||
"iam_group_administrator_access_policy",
|
||||
@@ -269,6 +270,7 @@
|
||||
"iam_user_no_setup_initial_access_key",
|
||||
"iam_user_two_active_access_key",
|
||||
"iam_user_console_access_unused",
|
||||
"iam_policy_no_agentcore_workload_access_token_wildcard",
|
||||
"bedrock_api_key_no_long_term_credentials"
|
||||
]
|
||||
},
|
||||
@@ -305,6 +307,7 @@
|
||||
],
|
||||
"Checks": [
|
||||
"iam_role_cross_service_confused_deputy_prevention",
|
||||
"iam_role_service_trust_restricts_source_to_account",
|
||||
"iam_role_access_not_stale_to_bedrock",
|
||||
"iam_user_access_not_stale_to_bedrock",
|
||||
"iam_role_cross_account_readonlyaccess_policy"
|
||||
@@ -484,7 +487,8 @@
|
||||
"awslambda_function_no_secrets_in_variables",
|
||||
"ecs_task_definitions_no_environment_secrets",
|
||||
"ec2_instance_secrets_user_data",
|
||||
"cloudwatch_log_group_no_secrets_in_logs"
|
||||
"cloudwatch_log_group_no_secrets_in_logs",
|
||||
"cloudwatch_log_group_agentcore_data_protection_policy_enabled"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -878,9 +882,11 @@
|
||||
"guardduty_s3_protection_enabled",
|
||||
"guardduty_eks_audit_log_enabled",
|
||||
"guardduty_eks_runtime_monitoring_enabled",
|
||||
"guardduty_runtime_monitoring_enabled",
|
||||
"guardduty_lambda_protection_enabled",
|
||||
"guardduty_rds_protection_enabled",
|
||||
"guardduty_ec2_malware_protection_enabled"
|
||||
"guardduty_ec2_malware_protection_enabled",
|
||||
"guardduty_ai_protection_enabled"
|
||||
],
|
||||
"ConfigRequirements": [
|
||||
{
|
||||
@@ -1128,10 +1134,12 @@
|
||||
"eks_cluster_not_publicly_accessible",
|
||||
"eks_cluster_private_nodes_enabled",
|
||||
"eks_cluster_network_policy_enabled",
|
||||
"eks_cluster_vpc_cni_network_policy_enforced",
|
||||
"eks_cluster_uses_a_supported_version",
|
||||
"eks_control_plane_logging_all_types_enabled",
|
||||
"eks_cluster_kms_cmk_encryption_in_secrets_enabled",
|
||||
"eks_cluster_deletion_protection_enabled"
|
||||
"eks_cluster_deletion_protection_enabled",
|
||||
"ecr_registry_enhanced_scanning_enabled"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1154,7 +1162,8 @@
|
||||
"ecs_task_definitions_logging_enabled",
|
||||
"ecs_task_definitions_no_environment_secrets",
|
||||
"ecs_task_definitions_host_namespace_not_shared",
|
||||
"ecs_cluster_container_insights_enabled"
|
||||
"ecs_cluster_container_insights_enabled",
|
||||
"ecr_registry_enhanced_scanning_enabled"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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"
|
||||
]
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
]
|
||||
|
||||
@@ -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"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
]
|
||||
|
||||
@@ -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"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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' ",
|
||||
|
||||
@@ -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": [
|
||||
{
|
||||
|
||||
@@ -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"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -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": [
|
||||
{
|
||||
|
||||
@@ -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.",
|
||||
|
||||
@@ -1498,9 +1498,7 @@
|
||||
{
|
||||
"Id": "4.1.4.1",
|
||||
"Description": "Ensure login challenges are enforced",
|
||||
"Checks": [
|
||||
"security_login_challenges_configured"
|
||||
],
|
||||
"Checks": [],
|
||||
"Attributes": [
|
||||
{
|
||||
"Section": "4 Security",
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
"Id": "GWS.COMMONCONTROLS.1.1",
|
||||
"Description": "Phishing-resistant MFA SHALL be required for all users",
|
||||
"Checks": [
|
||||
"security_2sv_enforced",
|
||||
"security_2sv_hardware_keys_admins"
|
||||
],
|
||||
"Attributes": [
|
||||
|
||||
@@ -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"
|
||||
]
|
||||
},
|
||||
|
||||
@@ -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"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -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.41.1"
|
||||
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"
|
||||
|
||||
@@ -119,6 +119,14 @@ aws:
|
||||
# aws.cloudwatch_log_group_retention_policy_specific_days_enabled --> by default is 365 days
|
||||
log_group_retention_days: 365
|
||||
|
||||
# aws.cloudwatch_log_group_agentcore_data_protection_policy_enabled
|
||||
# Log group name prefixes that hold Bedrock AgentCore agent telemetry. This list REPLACES
|
||||
# the defaults rather than adding to them, so keep both entries below when adding your own
|
||||
# or the log groups AgentCore creates itself stop being assessed.
|
||||
agentcore_log_group_name_prefixes:
|
||||
- "/aws/bedrock-agentcore/"
|
||||
- "/aws/vendedlogs/bedrock-agentcore/"
|
||||
|
||||
# AWS CloudFormation Configuration
|
||||
# cloudformation_stack_cdktoolkit_bootstrap_version --> by default is 21
|
||||
recommended_cdk_bootstrap_version: 21
|
||||
|
||||
@@ -267,6 +267,15 @@ class AWSProviderConfig(ProviderConfigBase):
|
||||
f"values accepted by the AWS API: {list(_CLOUDWATCH_RETENTION_DAYS)}."
|
||||
),
|
||||
)
|
||||
agentcore_log_group_name_prefixes: Optional[list[str]] = Field(
|
||||
default=None,
|
||||
description=(
|
||||
"Log group name prefixes that identify Bedrock AgentCore agent "
|
||||
"telemetry. Set this when AgentCore log delivery is pointed at log "
|
||||
"groups outside the service defaults; the value replaces the "
|
||||
"defaults, so list them alongside any prefix of your own."
|
||||
),
|
||||
)
|
||||
recommended_cdk_bootstrap_version: Optional[int] = Field(
|
||||
default=None,
|
||||
ge=1,
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -24,10 +24,25 @@ class bedrock_agent_role_least_privilege(Check):
|
||||
|
||||
Returns:
|
||||
A list of ``Check_Report_AWS`` with one entry per agent. The
|
||||
status is ``FAIL`` when any of the criteria above is violated,
|
||||
or when the execution role cannot be resolved in IAM.
|
||||
status is ``FAIL`` when any of the criteria above is violated and
|
||||
``MANUAL`` when the execution role cannot be resolved in IAM. When
|
||||
the IAM role inventory itself could not be listed, a single
|
||||
account-level ``MANUAL`` report is returned instead.
|
||||
"""
|
||||
findings = []
|
||||
|
||||
if iam_client.roles is None and bedrock_agent_client.agents:
|
||||
# iam:ListRoles was denied: this is an account-wide condition, so
|
||||
# emit one account-level MANUAL instead of one per agent.
|
||||
report = Check_Report_AWS(metadata=self.metadata(), resource={})
|
||||
report.region = iam_client.region
|
||||
report.resource_id = iam_client.audited_account
|
||||
report.resource_arn = iam_client.audited_account_arn
|
||||
report.status = "MANUAL"
|
||||
report.status_extended = "Cannot evaluate Bedrock Agent execution roles: the IAM roles could not be listed. Verify that the scanning credentials are allowed to call iam:ListRoles."
|
||||
findings.append(report)
|
||||
return findings
|
||||
|
||||
roles_by_arn = {role.arn: role for role in (iam_client.roles or [])}
|
||||
|
||||
for agent in bedrock_agent_client.agents.values():
|
||||
@@ -39,10 +54,11 @@ class bedrock_agent_role_least_privilege(Check):
|
||||
|
||||
role = roles_by_arn.get(agent.role_arn) if agent.role_arn else None
|
||||
if role is None:
|
||||
report.status = "FAIL"
|
||||
report.status = "MANUAL"
|
||||
report.status_extended = (
|
||||
f"Bedrock Agent {agent.name} execution role could not be "
|
||||
f"resolved in IAM and cannot be evaluated for least privilege."
|
||||
f"resolved in IAM and cannot be evaluated for least privilege; "
|
||||
f"verify the role manually."
|
||||
)
|
||||
findings.append(report)
|
||||
continue
|
||||
|
||||
@@ -15,6 +15,9 @@ class Cloudtrail(AWSService):
|
||||
super().__init__(__class__.__name__, provider)
|
||||
self.trail_arn_template = f"arn:{self.audited_partition}:cloudtrail:{self.region}:{self.audited_account}:trail"
|
||||
self.trails = {}
|
||||
# True when DescribeTrails was denied in at least one audited region,
|
||||
# so the trail inventory may be incomplete.
|
||||
self.trails_unavailable = False
|
||||
self.__threading_call__(self._get_trails)
|
||||
if self.trails:
|
||||
self._get_trail_status()
|
||||
@@ -79,13 +82,16 @@ class Cloudtrail(AWSService):
|
||||
logger.error(
|
||||
f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
|
||||
)
|
||||
self.trails_unavailable = True
|
||||
if not self.trails:
|
||||
self.trails = None
|
||||
else:
|
||||
self.trails_unavailable = True
|
||||
logger.error(
|
||||
f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
|
||||
)
|
||||
except Exception as error:
|
||||
self.trails_unavailable = True
|
||||
logger.error(
|
||||
f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
|
||||
)
|
||||
|
||||
@@ -13,7 +13,24 @@ from prowler.providers.aws.services.cloudwatch.logs_client import logs_client
|
||||
|
||||
|
||||
class cloudwatch_changes_to_network_acls_alarm_configured(Check):
|
||||
def execute(self):
|
||||
"""CloudWatch log metric filter and alarm exist for Network ACL (NACL) change events.
|
||||
|
||||
Looks for a CloudWatch Logs metric filter matching the expected pattern on a
|
||||
log group used by a CloudTrail trail, with at least one alarm on its metric.
|
||||
|
||||
- PASS: A matching metric filter with an associated alarm exists.
|
||||
- FAIL: No matching metric filter, or a filter without an alarm, was found.
|
||||
- MANUAL: CloudTrail trails, log groups, metric filters or alarms could
|
||||
not be listed in at least one region, so the absence of a filter/alarm
|
||||
cannot be asserted.
|
||||
"""
|
||||
|
||||
def execute(self) -> list[Check_Report_AWS]:
|
||||
"""Evaluate the metric filter and alarm coverage for the account.
|
||||
|
||||
Returns:
|
||||
list[Check_Report_AWS]: A single report for the account.
|
||||
"""
|
||||
pattern = build_metric_filter_pattern(
|
||||
event_names=[
|
||||
"CreateNetworkAcl",
|
||||
@@ -34,16 +51,29 @@ class cloudwatch_changes_to_network_acls_alarm_configured(Check):
|
||||
self.metadata(),
|
||||
)
|
||||
|
||||
if cloudtrail_client.trails is not None:
|
||||
if report is None:
|
||||
report = Check_Report_AWS(metadata=self.metadata(), resource={})
|
||||
report.status = "FAIL"
|
||||
report.status_extended = "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
report.region = logs_client.region
|
||||
report.resource_id = logs_client.audited_account
|
||||
report.resource_arn = logs_client.log_group_arn_template
|
||||
report.resource_tags = []
|
||||
inventory_unavailable = (
|
||||
cloudtrail_client.trails_unavailable
|
||||
or logs_client.log_groups_unavailable
|
||||
or logs_client.metric_filters_unavailable
|
||||
or cloudwatch_client.metric_alarms_unavailable
|
||||
)
|
||||
|
||||
findings.append(report)
|
||||
if report is None:
|
||||
report = Check_Report_AWS(metadata=self.metadata(), resource={})
|
||||
report.status = "FAIL"
|
||||
report.status_extended = "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
report.region = logs_client.region
|
||||
report.resource_id = logs_client.audited_account
|
||||
report.resource_arn = logs_client.log_group_arn_template
|
||||
report.resource_tags = []
|
||||
|
||||
# A denied listing in any region means the inventory is incomplete: a
|
||||
# PASS is still backed by a real filter and alarm, but a FAIL (nothing
|
||||
# found, or a filter found without its alarm) cannot be trusted.
|
||||
if report.status == "FAIL" and inventory_unavailable:
|
||||
report.status = "MANUAL"
|
||||
report.status_extended = "Cannot evaluate CloudWatch metric filters and alarms: CloudTrail trails, log groups, metric filters or alarms could not be listed in at least one region. Verify that the scanning credentials are allowed to call cloudtrail:DescribeTrails, logs:DescribeLogGroups, logs:DescribeMetricFilters and cloudwatch:DescribeAlarms."
|
||||
|
||||
findings.append(report)
|
||||
|
||||
return findings
|
||||
|
||||
@@ -13,7 +13,24 @@ from prowler.providers.aws.services.cloudwatch.logs_client import logs_client
|
||||
|
||||
|
||||
class cloudwatch_changes_to_network_gateways_alarm_configured(Check):
|
||||
def execute(self):
|
||||
"""CloudWatch Logs metric filter and alarm exist for changes to network gateways.
|
||||
|
||||
Looks for a CloudWatch Logs metric filter matching the expected pattern on a
|
||||
log group used by a CloudTrail trail, with at least one alarm on its metric.
|
||||
|
||||
- PASS: A matching metric filter with an associated alarm exists.
|
||||
- FAIL: No matching metric filter, or a filter without an alarm, was found.
|
||||
- MANUAL: CloudTrail trails, log groups, metric filters or alarms could
|
||||
not be listed in at least one region, so the absence of a filter/alarm
|
||||
cannot be asserted.
|
||||
"""
|
||||
|
||||
def execute(self) -> list[Check_Report_AWS]:
|
||||
"""Evaluate the metric filter and alarm coverage for the account.
|
||||
|
||||
Returns:
|
||||
list[Check_Report_AWS]: A single report for the account.
|
||||
"""
|
||||
pattern = build_metric_filter_pattern(
|
||||
event_names=[
|
||||
"CreateCustomerGateway",
|
||||
@@ -34,16 +51,29 @@ class cloudwatch_changes_to_network_gateways_alarm_configured(Check):
|
||||
self.metadata(),
|
||||
)
|
||||
|
||||
if cloudtrail_client.trails is not None:
|
||||
if report is None:
|
||||
report = Check_Report_AWS(metadata=self.metadata(), resource={})
|
||||
report.status = "FAIL"
|
||||
report.status_extended = "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
report.region = logs_client.region
|
||||
report.resource_id = logs_client.audited_account
|
||||
report.resource_arn = logs_client.log_group_arn_template
|
||||
report.resource_tags = []
|
||||
inventory_unavailable = (
|
||||
cloudtrail_client.trails_unavailable
|
||||
or logs_client.log_groups_unavailable
|
||||
or logs_client.metric_filters_unavailable
|
||||
or cloudwatch_client.metric_alarms_unavailable
|
||||
)
|
||||
|
||||
findings.append(report)
|
||||
if report is None:
|
||||
report = Check_Report_AWS(metadata=self.metadata(), resource={})
|
||||
report.status = "FAIL"
|
||||
report.status_extended = "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
report.region = logs_client.region
|
||||
report.resource_id = logs_client.audited_account
|
||||
report.resource_arn = logs_client.log_group_arn_template
|
||||
report.resource_tags = []
|
||||
|
||||
# A denied listing in any region means the inventory is incomplete: a
|
||||
# PASS is still backed by a real filter and alarm, but a FAIL (nothing
|
||||
# found, or a filter found without its alarm) cannot be trusted.
|
||||
if report.status == "FAIL" and inventory_unavailable:
|
||||
report.status = "MANUAL"
|
||||
report.status_extended = "Cannot evaluate CloudWatch metric filters and alarms: CloudTrail trails, log groups, metric filters or alarms could not be listed in at least one region. Verify that the scanning credentials are allowed to call cloudtrail:DescribeTrails, logs:DescribeLogGroups, logs:DescribeMetricFilters and cloudwatch:DescribeAlarms."
|
||||
|
||||
findings.append(report)
|
||||
|
||||
return findings
|
||||
|
||||
@@ -13,7 +13,24 @@ from prowler.providers.aws.services.cloudwatch.logs_client import logs_client
|
||||
|
||||
|
||||
class cloudwatch_changes_to_network_route_tables_alarm_configured(Check):
|
||||
def execute(self):
|
||||
"""Account monitors VPC route table changes with a CloudWatch Logs metric filter and alarm.
|
||||
|
||||
Looks for a CloudWatch Logs metric filter matching the expected pattern on a
|
||||
log group used by a CloudTrail trail, with at least one alarm on its metric.
|
||||
|
||||
- PASS: A matching metric filter with an associated alarm exists.
|
||||
- FAIL: No matching metric filter, or a filter without an alarm, was found.
|
||||
- MANUAL: CloudTrail trails, log groups, metric filters or alarms could
|
||||
not be listed in at least one region, so the absence of a filter/alarm
|
||||
cannot be asserted.
|
||||
"""
|
||||
|
||||
def execute(self) -> list[Check_Report_AWS]:
|
||||
"""Evaluate the metric filter and alarm coverage for the account.
|
||||
|
||||
Returns:
|
||||
list[Check_Report_AWS]: A single report for the account.
|
||||
"""
|
||||
pattern = build_metric_filter_pattern(
|
||||
event_source="ec2.amazonaws.com",
|
||||
event_names=[
|
||||
@@ -36,16 +53,29 @@ class cloudwatch_changes_to_network_route_tables_alarm_configured(Check):
|
||||
self.metadata(),
|
||||
)
|
||||
|
||||
if cloudtrail_client.trails is not None:
|
||||
if report is None:
|
||||
report = Check_Report_AWS(metadata=self.metadata(), resource={})
|
||||
report.status = "FAIL"
|
||||
report.status_extended = "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
report.region = logs_client.region
|
||||
report.resource_id = logs_client.audited_account
|
||||
report.resource_arn = logs_client.log_group_arn_template
|
||||
report.resource_tags = []
|
||||
inventory_unavailable = (
|
||||
cloudtrail_client.trails_unavailable
|
||||
or logs_client.log_groups_unavailable
|
||||
or logs_client.metric_filters_unavailable
|
||||
or cloudwatch_client.metric_alarms_unavailable
|
||||
)
|
||||
|
||||
findings.append(report)
|
||||
if report is None:
|
||||
report = Check_Report_AWS(metadata=self.metadata(), resource={})
|
||||
report.status = "FAIL"
|
||||
report.status_extended = "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
report.region = logs_client.region
|
||||
report.resource_id = logs_client.audited_account
|
||||
report.resource_arn = logs_client.log_group_arn_template
|
||||
report.resource_tags = []
|
||||
|
||||
# A denied listing in any region means the inventory is incomplete: a
|
||||
# PASS is still backed by a real filter and alarm, but a FAIL (nothing
|
||||
# found, or a filter found without its alarm) cannot be trusted.
|
||||
if report.status == "FAIL" and inventory_unavailable:
|
||||
report.status = "MANUAL"
|
||||
report.status_extended = "Cannot evaluate CloudWatch metric filters and alarms: CloudTrail trails, log groups, metric filters or alarms could not be listed in at least one region. Verify that the scanning credentials are allowed to call cloudtrail:DescribeTrails, logs:DescribeLogGroups, logs:DescribeMetricFilters and cloudwatch:DescribeAlarms."
|
||||
|
||||
findings.append(report)
|
||||
|
||||
return findings
|
||||
|
||||
@@ -13,7 +13,24 @@ from prowler.providers.aws.services.cloudwatch.logs_client import logs_client
|
||||
|
||||
|
||||
class cloudwatch_changes_to_vpcs_alarm_configured(Check):
|
||||
def execute(self):
|
||||
"""AWS account has a CloudWatch Logs metric filter and alarm for VPC changes.
|
||||
|
||||
Looks for a CloudWatch Logs metric filter matching the expected pattern on a
|
||||
log group used by a CloudTrail trail, with at least one alarm on its metric.
|
||||
|
||||
- PASS: A matching metric filter with an associated alarm exists.
|
||||
- FAIL: No matching metric filter, or a filter without an alarm, was found.
|
||||
- MANUAL: CloudTrail trails, log groups, metric filters or alarms could
|
||||
not be listed in at least one region, so the absence of a filter/alarm
|
||||
cannot be asserted.
|
||||
"""
|
||||
|
||||
def execute(self) -> list[Check_Report_AWS]:
|
||||
"""Evaluate the metric filter and alarm coverage for the account.
|
||||
|
||||
Returns:
|
||||
list[Check_Report_AWS]: A single report for the account.
|
||||
"""
|
||||
pattern = build_metric_filter_pattern(
|
||||
event_names=[
|
||||
"CreateVpc",
|
||||
@@ -39,16 +56,29 @@ class cloudwatch_changes_to_vpcs_alarm_configured(Check):
|
||||
self.metadata(),
|
||||
)
|
||||
|
||||
if cloudtrail_client.trails is not None:
|
||||
if report is None:
|
||||
report = Check_Report_AWS(metadata=self.metadata(), resource={})
|
||||
report.status = "FAIL"
|
||||
report.status_extended = "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
report.region = logs_client.region
|
||||
report.resource_id = logs_client.audited_account
|
||||
report.resource_arn = logs_client.log_group_arn_template
|
||||
report.resource_tags = []
|
||||
inventory_unavailable = (
|
||||
cloudtrail_client.trails_unavailable
|
||||
or logs_client.log_groups_unavailable
|
||||
or logs_client.metric_filters_unavailable
|
||||
or cloudwatch_client.metric_alarms_unavailable
|
||||
)
|
||||
|
||||
findings.append(report)
|
||||
if report is None:
|
||||
report = Check_Report_AWS(metadata=self.metadata(), resource={})
|
||||
report.status = "FAIL"
|
||||
report.status_extended = "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
report.region = logs_client.region
|
||||
report.resource_id = logs_client.audited_account
|
||||
report.resource_arn = logs_client.log_group_arn_template
|
||||
report.resource_tags = []
|
||||
|
||||
# A denied listing in any region means the inventory is incomplete: a
|
||||
# PASS is still backed by a real filter and alarm, but a FAIL (nothing
|
||||
# found, or a filter found without its alarm) cannot be trusted.
|
||||
if report.status == "FAIL" and inventory_unavailable:
|
||||
report.status = "MANUAL"
|
||||
report.status_extended = "Cannot evaluate CloudWatch metric filters and alarms: CloudTrail trails, log groups, metric filters or alarms could not be listed in at least one region. Verify that the scanning credentials are allowed to call cloudtrail:DescribeTrails, logs:DescribeLogGroups, logs:DescribeMetricFilters and cloudwatch:DescribeAlarms."
|
||||
|
||||
findings.append(report)
|
||||
|
||||
return findings
|
||||
|
||||