mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-04-06 02:58:15 +00:00
feat(cloudflare): add TLS/SSL and email security checks for zones
Adds 9 additional security checks for Cloudflare zones: TLS/SSL checks: - zones_tls_1_3_enabled: Validates TLS 1.3 is enabled - zones_hsts_include_subdomains: Ensures HSTS includes subdomains - zones_automatic_https_rewrites_enabled: Validates automatic HTTPS rewrites - zones_universal_ssl_enabled: Ensures Universal SSL is enabled Email security checks: - zones_dmarc_record_exists: Validates DMARC record exists - zones_spf_record_exists: Validates SPF record exists - zones_caa_record_exists: Validates CAA record exists - zones_email_obfuscation_enabled: Ensures email obfuscation is enabled Security configuration: - zones_security_level: Validates security level configuration
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"Provider": "cloudflare",
|
||||
"CheckID": "zones_automatic_https_rewrites_enabled",
|
||||
"CheckTitle": "Automatic HTTPS Rewrites is enabled to resolve mixed content issues",
|
||||
"CheckType": [],
|
||||
"ServiceName": "zones",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "",
|
||||
"Severity": "medium",
|
||||
"ResourceType": "Zone",
|
||||
"Description": "Verifies that Automatic HTTPS Rewrites is enabled to automatically rewrite insecure HTTP links to HTTPS, resolving mixed content issues and enhancing site security.",
|
||||
"Risk": "Without Automatic HTTPS Rewrites, pages may contain mixed content where HTTP resources load over HTTPS pages. Browsers block or warn about mixed content, degrading user experience and leaving resources vulnerable to interception.",
|
||||
"RelatedUrl": "https://developers.cloudflare.com/ssl/edge-certificates/additional-options/automatic-https-rewrites/",
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "",
|
||||
"NativeIaC": "",
|
||||
"Other": "",
|
||||
"Terraform": "resource \"cloudflare_zone_settings_override\" \"example\" {\n zone_id = var.zone_id\n settings {\n automatic_https_rewrites = \"on\"\n }\n}"
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "Enable Automatic HTTPS Rewrites as part of a comprehensive HTTPS strategy. Combine with Always Use HTTPS and HSTS to enforce encrypted transport for all traffic following defense in depth principles.",
|
||||
"Url": "https://hub.prowler.com/checks/zones_automatic_https_rewrites_enabled"
|
||||
}
|
||||
},
|
||||
"Categories": [
|
||||
"encryption"
|
||||
],
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": "This feature works best when combined with Always Use HTTPS to ensure the entire site is served over HTTPS."
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
from prowler.lib.check.models import Check, CheckReportCloudflare
|
||||
from prowler.providers.cloudflare.services.zones.zones_client import zones_client
|
||||
|
||||
|
||||
class zones_automatic_https_rewrites_enabled(Check):
|
||||
def execute(self) -> list[CheckReportCloudflare]:
|
||||
findings = []
|
||||
for zone in zones_client.zones:
|
||||
report = CheckReportCloudflare(
|
||||
metadata=self.metadata(),
|
||||
resource=zone,
|
||||
)
|
||||
automatic_https_rewrites = (
|
||||
zone.settings.automatic_https_rewrites or ""
|
||||
).lower()
|
||||
if automatic_https_rewrites == "on":
|
||||
report.status = "PASS"
|
||||
report.status_extended = (
|
||||
f"Automatic HTTPS Rewrites is enabled for zone {zone.name}."
|
||||
)
|
||||
else:
|
||||
report.status = "FAIL"
|
||||
report.status_extended = (
|
||||
f"Automatic HTTPS Rewrites is not enabled for zone {zone.name}."
|
||||
)
|
||||
findings.append(report)
|
||||
return findings
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"Provider": "cloudflare",
|
||||
"CheckID": "zones_caa_record_exists",
|
||||
"CheckTitle": "CAA record exists to restrict certificate authority issuance",
|
||||
"CheckType": [],
|
||||
"ServiceName": "zones",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "",
|
||||
"Severity": "low",
|
||||
"ResourceType": "Zone",
|
||||
"Description": "Verifies that a CAA (Certificate Authority Authorization) DNS record exists to specify which certificate authorities are permitted to issue certificates for the domain.",
|
||||
"Risk": "Without CAA records, any certificate authority can issue certificates for the domain, increasing the risk of unauthorized certificate issuance through CA compromise or social engineering attacks against CAs.",
|
||||
"RelatedUrl": "https://developers.cloudflare.com/ssl/edge-certificates/caa-records/",
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "",
|
||||
"NativeIaC": "",
|
||||
"Other": "",
|
||||
"Terraform": "resource \"cloudflare_record\" \"caa\" {\n zone_id = var.zone_id\n name = \"@\"\n type = \"CAA\"\n data {\n flags = \"0\"\n tag = \"issue\"\n value = \"letsencrypt.org\"\n }\n}"
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "Add CAA records specifying authorized certificate authorities for your domain. This provides an additional layer of defense against unauthorized certificate issuance as part of a comprehensive PKI security strategy.",
|
||||
"Url": "https://hub.prowler.com/checks/zones_caa_record_exists"
|
||||
}
|
||||
},
|
||||
"Categories": [
|
||||
"encryption"
|
||||
],
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": "CAA records help prevent unauthorized SSL/TLS certificate issuance."
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
from prowler.lib.check.models import Check, CheckReportCloudflare
|
||||
from prowler.providers.cloudflare.services.dns.dns_client import dns_client
|
||||
from prowler.providers.cloudflare.services.zones.zones_client import zones_client
|
||||
|
||||
|
||||
class zones_caa_record_exists(Check):
|
||||
def execute(self) -> list[CheckReportCloudflare]:
|
||||
findings = []
|
||||
|
||||
for zone in zones_client.zones:
|
||||
report = CheckReportCloudflare(
|
||||
metadata=self.metadata(),
|
||||
resource=zone,
|
||||
)
|
||||
|
||||
# CAA records restrict which CAs can issue certificates
|
||||
caa_records = [
|
||||
record
|
||||
for record in dns_client.records
|
||||
if record.zone.id == zone.id and record.type == "CAA"
|
||||
]
|
||||
|
||||
if caa_records:
|
||||
report.status = "PASS"
|
||||
report.status_extended = (
|
||||
f"CAA record exists for zone {zone.name} "
|
||||
f"({len(caa_records)} record(s))."
|
||||
)
|
||||
else:
|
||||
report.status = "FAIL"
|
||||
report.status_extended = f"No CAA record found for zone {zone.name}."
|
||||
findings.append(report)
|
||||
|
||||
return findings
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"Provider": "cloudflare",
|
||||
"CheckID": "zones_dmarc_record_exists",
|
||||
"CheckTitle": "DMARC record exists for email authentication and reporting",
|
||||
"CheckType": [],
|
||||
"ServiceName": "zones",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "",
|
||||
"Severity": "medium",
|
||||
"ResourceType": "Zone",
|
||||
"Description": "Verifies that a DMARC (Domain-based Message Authentication, Reporting, and Conformance) TXT record exists to define email authentication policy and enable reporting on spoofing attempts.",
|
||||
"Risk": "Without DMARC, there is no policy enforcement for SPF and DKIM failures, allowing attackers to spoof emails from your domain for phishing campaigns while you receive no visibility into abuse attempts.",
|
||||
"RelatedUrl": "https://developers.cloudflare.com/dns/manage-dns-records/how-to/email-records/",
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "",
|
||||
"NativeIaC": "",
|
||||
"Other": "",
|
||||
"Terraform": "resource \"cloudflare_record\" \"dmarc\" {\n zone_id = var.zone_id\n name = \"_dmarc\"\n type = \"TXT\"\n value = \"v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com\"\n}"
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "Implement DMARC as part of a complete email authentication strategy with SPF and DKIM. Start with a monitoring policy (p=none) to gather data, then progressively enforce stricter policies (quarantine, reject).",
|
||||
"Url": "https://hub.prowler.com/checks/zones_dmarc_record_exists"
|
||||
}
|
||||
},
|
||||
"Categories": [
|
||||
"email-security"
|
||||
],
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": "DMARC records are TXT records at _dmarc subdomain starting with 'v=DMARC1'."
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
from prowler.lib.check.models import Check, CheckReportCloudflare
|
||||
from prowler.providers.cloudflare.services.dns.dns_client import dns_client
|
||||
from prowler.providers.cloudflare.services.zones.zones_client import zones_client
|
||||
|
||||
|
||||
class zones_dmarc_record_exists(Check):
|
||||
def execute(self) -> list[CheckReportCloudflare]:
|
||||
findings = []
|
||||
|
||||
for zone in zones_client.zones:
|
||||
report = CheckReportCloudflare(
|
||||
metadata=self.metadata(),
|
||||
resource=zone,
|
||||
)
|
||||
|
||||
# DMARC records are TXT records at _dmarc subdomain starting with "v=DMARC1"
|
||||
dmarc_records = [
|
||||
record
|
||||
for record in dns_client.records
|
||||
if record.zone.id == zone.id
|
||||
and record.type == "TXT"
|
||||
and record.name.startswith("_dmarc")
|
||||
and "v=DMARC1" in record.content.upper()
|
||||
]
|
||||
|
||||
if dmarc_records:
|
||||
report.status = "PASS"
|
||||
report.status_extended = f"DMARC record exists for zone {zone.name}."
|
||||
else:
|
||||
report.status = "FAIL"
|
||||
report.status_extended = f"No DMARC record found for zone {zone.name}."
|
||||
findings.append(report)
|
||||
|
||||
return findings
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"Provider": "cloudflare",
|
||||
"CheckID": "zones_email_obfuscation_enabled",
|
||||
"CheckTitle": "Email Obfuscation is enabled to protect against email harvesting",
|
||||
"CheckType": [],
|
||||
"ServiceName": "zones",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "",
|
||||
"Severity": "low",
|
||||
"ResourceType": "Zone",
|
||||
"Description": "Verifies that Email Obfuscation (Scrape Shield) is enabled to protect email addresses on the website from automated harvesting by bots and spammers.",
|
||||
"Risk": "Without Email Obfuscation, email addresses displayed on the website can be harvested by bots, leading to spam, phishing attacks targeting employees or users, and potential social engineering attempts.",
|
||||
"RelatedUrl": "https://developers.cloudflare.com/waf/tools/scrape-shield/email-address-obfuscation/",
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "",
|
||||
"NativeIaC": "",
|
||||
"Other": "",
|
||||
"Terraform": "resource \"cloudflare_zone_settings_override\" \"example\" {\n zone_id = var.zone_id\n settings {\n email_obfuscation = \"on\"\n }\n}"
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "Enable Email Obfuscation as part of anti-scraping protections. The feature automatically encodes email addresses for bots while keeping them visible and functional for human visitors.",
|
||||
"Url": "https://hub.prowler.com/checks/zones_email_obfuscation_enabled"
|
||||
}
|
||||
},
|
||||
"Categories": [
|
||||
"internet-exposed"
|
||||
],
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": "Email Obfuscation automatically hides email addresses from bots while keeping them visible and clickable for human visitors."
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
from prowler.lib.check.models import Check, CheckReportCloudflare
|
||||
from prowler.providers.cloudflare.services.zones.zones_client import zones_client
|
||||
|
||||
|
||||
class zones_email_obfuscation_enabled(Check):
|
||||
def execute(self) -> list[CheckReportCloudflare]:
|
||||
findings = []
|
||||
for zone in zones_client.zones:
|
||||
report = CheckReportCloudflare(
|
||||
metadata=self.metadata(),
|
||||
resource=zone,
|
||||
)
|
||||
email_obfuscation = (zone.settings.email_obfuscation or "").lower()
|
||||
if email_obfuscation == "on":
|
||||
report.status = "PASS"
|
||||
report.status_extended = (
|
||||
f"Email Obfuscation is enabled for zone {zone.name}."
|
||||
)
|
||||
else:
|
||||
report.status = "FAIL"
|
||||
report.status_extended = (
|
||||
f"Email Obfuscation is not enabled for zone {zone.name}."
|
||||
)
|
||||
findings.append(report)
|
||||
return findings
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"Provider": "cloudflare",
|
||||
"CheckID": "zones_hsts_include_subdomains",
|
||||
"CheckTitle": "HSTS includes subdomains directive for comprehensive protection",
|
||||
"CheckType": [],
|
||||
"ServiceName": "zones",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "",
|
||||
"Severity": "medium",
|
||||
"ResourceType": "Zone",
|
||||
"Description": "Verifies that HSTS is configured with the includeSubDomains directive to enforce HTTPS across all subdomains, preventing SSL stripping attacks on any subdomain.",
|
||||
"Risk": "Without includeSubDomains, subdomains remain vulnerable to SSL stripping attacks even when the main domain has HSTS enabled, allowing attackers to intercept traffic on subdomain services.",
|
||||
"RelatedUrl": "https://developers.cloudflare.com/ssl/edge-certificates/additional-options/http-strict-transport-security/",
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "",
|
||||
"NativeIaC": "",
|
||||
"Other": "",
|
||||
"Terraform": "resource \"cloudflare_zone_settings_override\" \"example\" {\n zone_id = var.zone_id\n settings {\n security_header {\n enabled = true\n include_subdomains = true\n max_age = 31536000\n }\n }\n}"
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "Enable includeSubDomains after verifying all subdomains support HTTPS. This ensures consistent security policy across the entire domain hierarchy following the principle of complete mediation.",
|
||||
"Url": "https://hub.prowler.com/checks/zones_hsts_include_subdomains"
|
||||
}
|
||||
},
|
||||
"Categories": [
|
||||
"encryption"
|
||||
],
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": "Ensure all subdomains are accessible via HTTPS before enabling includeSubDomains to avoid accessibility issues."
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
from prowler.lib.check.models import Check, CheckReportCloudflare
|
||||
from prowler.providers.cloudflare.services.zones.zones_client import zones_client
|
||||
|
||||
|
||||
class zones_hsts_include_subdomains(Check):
|
||||
def execute(self) -> list[CheckReportCloudflare]:
|
||||
findings = []
|
||||
for zone in zones_client.zones:
|
||||
report = CheckReportCloudflare(
|
||||
metadata=self.metadata(),
|
||||
resource=zone,
|
||||
)
|
||||
if zone.settings.hsts_enabled and zone.settings.hsts_include_subdomains:
|
||||
report.status = "PASS"
|
||||
report.status_extended = f"HSTS is enabled with includeSubDomains directive for zone {zone.name}."
|
||||
elif zone.settings.hsts_enabled:
|
||||
report.status = "FAIL"
|
||||
report.status_extended = f"HSTS is enabled but does not include subdomains for zone {zone.name}."
|
||||
else:
|
||||
report.status = "FAIL"
|
||||
report.status_extended = f"HSTS is not enabled for zone {zone.name}."
|
||||
findings.append(report)
|
||||
return findings
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"Provider": "cloudflare",
|
||||
"CheckID": "zones_security_level",
|
||||
"CheckTitle": "Security level is set to medium or higher for adequate threat protection",
|
||||
"CheckType": [],
|
||||
"ServiceName": "zones",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "",
|
||||
"Severity": "medium",
|
||||
"ResourceType": "Zone",
|
||||
"Description": "Verifies that the security level is set to medium, high, or under_attack to ensure adequate threat protection based on visitor reputation scores.",
|
||||
"Risk": "A low security level allows more potentially malicious traffic to reach the origin, increasing the attack surface and risk of successful attacks against web applications.",
|
||||
"RelatedUrl": "https://developers.cloudflare.com/waf/tools/security-level/",
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "",
|
||||
"NativeIaC": "",
|
||||
"Other": "",
|
||||
"Terraform": ""
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "Set security level to Medium or High based on your threat tolerance. Use Under Attack mode during active attacks, but avoid keeping it enabled permanently as it may impact legitimate user experience.",
|
||||
"Url": "https://hub.prowler.com/checks/zones_security_level"
|
||||
}
|
||||
},
|
||||
"Categories": [],
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": ""
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
from prowler.lib.check.models import Check, CheckReportCloudflare
|
||||
from prowler.providers.cloudflare.services.zones.zones_client import zones_client
|
||||
|
||||
|
||||
class zones_security_level(Check):
|
||||
def execute(self) -> list[CheckReportCloudflare]:
|
||||
findings = []
|
||||
acceptable_levels = ["medium", "high", "under_attack"]
|
||||
|
||||
for zone in zones_client.zones:
|
||||
report = CheckReportCloudflare(
|
||||
metadata=self.metadata(),
|
||||
resource=zone,
|
||||
)
|
||||
security_level = (zone.settings.security_level or "").lower()
|
||||
if security_level in acceptable_levels:
|
||||
report.status = "PASS"
|
||||
report.status_extended = (
|
||||
f"Security level is set to '{security_level}' for zone {zone.name}."
|
||||
)
|
||||
else:
|
||||
report.status = "FAIL"
|
||||
report.status_extended = (
|
||||
f"Security level is set to '{security_level}' for zone {zone.name}."
|
||||
)
|
||||
findings.append(report)
|
||||
return findings
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"Provider": "cloudflare",
|
||||
"CheckID": "zones_spf_record_exists",
|
||||
"CheckTitle": "SPF record exists for email authentication",
|
||||
"CheckType": [],
|
||||
"ServiceName": "zones",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "",
|
||||
"Severity": "medium",
|
||||
"ResourceType": "Zone",
|
||||
"Description": "Verifies that an SPF (Sender Policy Framework) TXT record exists to specify which mail servers are authorized to send email on behalf of the domain.",
|
||||
"Risk": "Without SPF, attackers can forge emails appearing to come from your domain, enabling phishing attacks, brand impersonation, and reputation damage that impacts email deliverability.",
|
||||
"RelatedUrl": "https://developers.cloudflare.com/dns/manage-dns-records/how-to/email-records/",
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "",
|
||||
"NativeIaC": "",
|
||||
"Other": "",
|
||||
"Terraform": "resource \"cloudflare_record\" \"spf\" {\n zone_id = var.zone_id\n name = \"@\"\n type = \"TXT\"\n value = \"v=spf1 include:_spf.google.com ~all\"\n}"
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "Configure SPF records listing authorized mail servers. Combine SPF with DKIM and DMARC for comprehensive email authentication following defense in depth principles for email security.",
|
||||
"Url": "https://hub.prowler.com/checks/zones_spf_record_exists"
|
||||
}
|
||||
},
|
||||
"Categories": [
|
||||
"email-security"
|
||||
],
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": "SPF records start with 'v=spf1' and define authorized mail servers."
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
from prowler.lib.check.models import Check, CheckReportCloudflare
|
||||
from prowler.providers.cloudflare.services.dns.dns_client import dns_client
|
||||
from prowler.providers.cloudflare.services.zones.zones_client import zones_client
|
||||
|
||||
|
||||
class zones_spf_record_exists(Check):
|
||||
def execute(self) -> list[CheckReportCloudflare]:
|
||||
findings = []
|
||||
|
||||
for zone in zones_client.zones:
|
||||
report = CheckReportCloudflare(
|
||||
metadata=self.metadata(),
|
||||
resource=zone,
|
||||
)
|
||||
|
||||
# SPF records are TXT records starting with "v=spf1"
|
||||
spf_records = [
|
||||
record
|
||||
for record in dns_client.records
|
||||
if record.zone.id == zone.id
|
||||
and record.type == "TXT"
|
||||
and record.content.startswith("v=spf1")
|
||||
]
|
||||
|
||||
if spf_records:
|
||||
report.status = "PASS"
|
||||
report.status_extended = f"SPF record exists for zone {zone.name}."
|
||||
else:
|
||||
report.status = "FAIL"
|
||||
report.status_extended = f"No SPF record found for zone {zone.name}."
|
||||
findings.append(report)
|
||||
|
||||
return findings
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"Provider": "cloudflare",
|
||||
"CheckID": "zones_tls_1_3_enabled",
|
||||
"CheckTitle": "TLS 1.3 is enabled for improved security and performance",
|
||||
"CheckType": [],
|
||||
"ServiceName": "zones",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "",
|
||||
"Severity": "medium",
|
||||
"ResourceType": "Zone",
|
||||
"Description": "Verifies that TLS 1.3 is enabled to benefit from improved security through simplified cipher suites and faster handshakes with zero round-trip time resumption.",
|
||||
"Risk": "Without TLS 1.3, connections use older TLS versions with more complex cipher negotiations, slower handshakes, and lack of modern security improvements that protect against downgrade attacks.",
|
||||
"RelatedUrl": "https://developers.cloudflare.com/ssl/edge-certificates/additional-options/tls-13/",
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "",
|
||||
"NativeIaC": "",
|
||||
"Other": "",
|
||||
"Terraform": ""
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "Enable TLS 1.3 to provide the most secure and efficient TLS connections. All modern browsers support TLS 1.3, ensuring broad compatibility while improving security posture.",
|
||||
"Url": "https://hub.prowler.com/checks/zones_tls_1_3_enabled"
|
||||
}
|
||||
},
|
||||
"Categories": [
|
||||
"encryption"
|
||||
],
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": ""
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
from prowler.lib.check.models import Check, CheckReportCloudflare
|
||||
from prowler.providers.cloudflare.services.zones.zones_client import zones_client
|
||||
|
||||
|
||||
class zones_tls_1_3_enabled(Check):
|
||||
def execute(self) -> list[CheckReportCloudflare]:
|
||||
findings = []
|
||||
for zone in zones_client.zones:
|
||||
report = CheckReportCloudflare(
|
||||
metadata=self.metadata(),
|
||||
resource=zone,
|
||||
)
|
||||
tls_1_3 = (zone.settings.tls_1_3 or "").lower()
|
||||
if tls_1_3 in ["on", "zrt"]:
|
||||
report.status = "PASS"
|
||||
report.status_extended = f"TLS 1.3 is enabled for zone {zone.name}."
|
||||
else:
|
||||
report.status = "FAIL"
|
||||
report.status_extended = f"TLS 1.3 is not enabled for zone {zone.name}."
|
||||
findings.append(report)
|
||||
return findings
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"Provider": "cloudflare",
|
||||
"CheckID": "zones_universal_ssl_enabled",
|
||||
"CheckTitle": "Universal SSL is enabled to provide SSL/TLS certificates",
|
||||
"CheckType": [],
|
||||
"ServiceName": "zones",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "",
|
||||
"Severity": "high",
|
||||
"ResourceType": "Zone",
|
||||
"Description": "Verifies that Universal SSL is enabled to provide free SSL/TLS certificates for the domain and its subdomains, enabling HTTPS connections.",
|
||||
"Risk": "Without Universal SSL, visitors cannot establish HTTPS connections, leaving all traffic unencrypted and vulnerable to interception. Browsers will display security warnings, degrading trust and user experience.",
|
||||
"RelatedUrl": "https://developers.cloudflare.com/ssl/edge-certificates/universal-ssl/",
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "",
|
||||
"NativeIaC": "",
|
||||
"Other": "",
|
||||
"Terraform": ""
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "Enable Universal SSL to provide HTTPS capability for your domain. This is the foundation for transport security and is required before implementing HSTS or other HTTPS-dependent features.",
|
||||
"Url": "https://hub.prowler.com/checks/zones_universal_ssl_enabled"
|
||||
}
|
||||
},
|
||||
"Categories": [
|
||||
"encryption"
|
||||
],
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": ""
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
from prowler.lib.check.models import Check, CheckReportCloudflare
|
||||
from prowler.providers.cloudflare.services.zones.zones_client import zones_client
|
||||
|
||||
|
||||
class zones_universal_ssl_enabled(Check):
|
||||
def execute(self) -> list[CheckReportCloudflare]:
|
||||
findings = []
|
||||
for zone in zones_client.zones:
|
||||
report = CheckReportCloudflare(
|
||||
metadata=self.metadata(),
|
||||
resource=zone,
|
||||
)
|
||||
universal_ssl = (zone.settings.universal_ssl or "").lower()
|
||||
if universal_ssl == "on":
|
||||
report.status = "PASS"
|
||||
report.status_extended = (
|
||||
f"Universal SSL is enabled for zone {zone.name}."
|
||||
)
|
||||
else:
|
||||
report.status = "FAIL"
|
||||
report.status_extended = (
|
||||
f"Universal SSL is not enabled for zone {zone.name}."
|
||||
)
|
||||
findings.append(report)
|
||||
return findings
|
||||
Reference in New Issue
Block a user