WAF-SEC-040 β Encryption in Transit β TLS Enforcement
Description
All network communication between clients and services, and between internal services, MUST use TLS 1.2 or higher. HTTP listeners on application load balancers MUST either redirect to HTTPS or be prohibited. CloudFront distributions MUST enforce a minimum TLS policy of TLSv1.2. Internal service-to-service communication within VPCs MUST be encrypted. Expired, self-signed, or untrusted TLS certificates MUST NOT be used in production environments.
Rationale
| Risk | Description |
|---|---|
Risk |
Sensitive data is exposed if storage or transport lacks strong encryption. |
Risk |
Compromised keys or weak key rotation extend the blast radius of a breach. |
Requirements
-
All network communication between clients and services, and between internal services, MUST use TLS 1.2 or higher.
-
HTTP listeners on application load balancers MUST either redirect to HTTPS or be prohibited.
-
CloudFront distributions MUST enforce a minimum TLS policy of TLSv1.2.
-
Internal service-to-service communication within VPCs MUST be encrypted.
-
Expired, self-signed, or untrusted TLS certificates MUST NOT be used in production environments.
Implementation Guidance
-
Implement the required configuration as code in Terraform or equivalent IaC.
-
Add an automated check to CI/CD so deviations are caught before deployment.
Maturity Levels
| Level | Name | Criteria |
|---|---|---|
L1 |
Ad hoc β control not consistently applied |
* Manual evidence exists for some workloads, but coverage is unknown. |
L2 |
Standardised β policy defined and communicated |
* A version-controlled policy, ADR, or standard describes the requirement. |
L3 |
Integrated β automated validation in CI/CD |
* Terraform checks run automatically on pull requests and report results. |
L4 |
Auditable β metrics and exceptions tracked |
* Control coverage, failures, and approved exceptions are reported quarterly. |
L5 |
Optimised β continuous improvement based on data |
* Control effectiveness is measured and iteratively improved. |
Checks
waf-sec-040.tf.aws.alb-https-listener
Engine: terraform | Provider: aws | Automated: Yes
ALB and NLB listeners must use HTTPS, not HTTP
Application and Network Load Balancer listeners must be configured with the HTTPS protocol (or TLS for NLB). Listeners configured with plain HTTP on port 80 are only acceptable if they redirect to HTTPS via a fixed-response redirect rule and do not forward traffic to targets.
Scope: resource β aws_lb_listener, aws_alb_listener
Assertions:
* protocol not equals HTTP β Load balancer listener MUST use HTTPS (or HTTP-to-HTTPS redirect), not plain HTTP forwarding.
Remediation: Change the listener protocol to HTTPS and provide a valid ACM certificate ARN. If a port 80 listener is required for redirect purposes, change the default_action to type = "redirect" with redirect { protocol = "HTTPS", status_code = "HTTP_301" }.
resource "aws_lb_listener" "https" {
load_balancer_arn = aws_lb.main.arn
port = 443
protocol = "HTTPS"
ssl_policy = "ELBSecurityPolicy-TLS13-1-2-2021-06"
certificate_arn = aws_acm_certificate.main.arn
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.app.arn
}
}
resource "aws_lb_listener" "redirect_http" {
load_balancer_arn = aws_lb.main.arn
port = 80
protocol = "HTTP"
default_action {
type = "redirect"
redirect {
port = "443"
protocol = "HTTPS"
status_code = "HTTP_301"
}
}
}
resource "aws_lb_listener" "http" {
load_balancer_arn = aws_lb.main.arn
port = 80
protocol = "HTTP" # WAF-SEC-040 violation: plain HTTP forwarding
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.app.arn
}
}
waf-sec-040.tf.aws.cloudfront-tls-policy
Engine: terraform | Provider: aws | Automated: Yes
CloudFront distributions must enforce TLS 1.2 or higher
CloudFront distributions must have a viewer_certificate block with minimum_protocol_version set to at least TLSv1.2_2021 to prevent connections using outdated TLS versions.
Scope: resource β aws_cloudfront_distribution
Assertions:
* viewer_certificate attribute exists β CloudFront distribution must have an explicit viewer_certificate block configured.
Remediation: Add a viewer_certificate block to the aws_cloudfront_distribution resource. Set minimum_protocol_version = "TLSv1.2_2021" and ssl_support_method = "sni-only". Use a custom ACM certificate instead of the default CloudFront certificate for production workloads with custom domains.
resource "aws_cloudfront_distribution" "main" {
# ... origin and cache behavior config
viewer_certificate {
acm_certificate_arn = aws_acm_certificate.cdn.arn
ssl_support_method = "sni-only"
minimum_protocol_version = "TLSv1.2_2021"
}
}
resource "aws_cloudfront_distribution" "main" {
# ... origin and cache behavior config
viewer_certificate {
cloudfront_default_certificate = true
# minimum_protocol_version not set β defaults to TLSv1 (WAF-SEC-040 violation)
}
}
waf-sec-040.tf.azurerm.web-app-min-tls
Engine: terraform | Provider: azurerm | Automated: Yes
Azure App Service and Function Apps must enforce TLS 1.2
All azurerm_linux_web_app, azurerm_windows_web_app, azurerm_linux_function_app, and azurerm_windows_function_app resources must set site_config.minimum_tls_version to "1.2".
Scope: resource β azurerm_linux_web_app, azurerm_windows_web_app, azurerm_linux_function_app, azurerm_windows_function_app
Assertions:
* site_config.minimum_tls_version equals 1.2 β App Service / Function App must enforce TLS 1.2 minimum.
Remediation: Set minimum_tls_version = "1.2" in the site_config block of every App Service and Function App resource.
resource "azurerm_linux_web_app" "app" {
name = "app-service"
resource_group_name = azurerm_resource_group.main.name
location = azurerm_resource_group.main.location
service_plan_id = azurerm_service_plan.app.id
site_config {
minimum_tls_version = "1.2"
ftps_state = "Disabled"
}
}
resource "azurerm_linux_web_app" "app" {
name = "app-service"
resource_group_name = azurerm_resource_group.main.name
location = azurerm_resource_group.main.location
service_plan_id = azurerm_service_plan.app.id
site_config {
# minimum_tls_version defaults to "1.0" on older APIs
}
}
waf-sec-040.tf.azurerm.cdn-no-http
Engine: terraform | Provider: azurerm | Automated: Yes
Azure CDN endpoints must not allow plain HTTP delivery
All azurerm_cdn_endpoint resources must set is_http_allowed to false so content is only served over HTTPS.
Scope: resource β azurerm_cdn_endpoint
Assertions:
* is_http_allowed is false β CDN endpoint must not allow plain HTTP delivery.
Remediation: Set is_http_allowed = false on every azurerm_cdn_endpoint resource. Configure HTTPS delivery and a valid custom domain certificate if needed.
resource "azurerm_cdn_endpoint" "app" {
name = "app-cdn"
profile_name = azurerm_cdn_profile.app.name
location = azurerm_resource_group.main.location
resource_group_name = azurerm_resource_group.main.name
is_http_allowed = false
origin_host_header = azurerm_storage_account.app.primary_web_host
}
resource "azurerm_cdn_endpoint" "app" {
name = "app-cdn"
profile_name = azurerm_cdn_profile.app.name
location = azurerm_resource_group.main.location
resource_group_name = azurerm_resource_group.main.name
# is_http_allowed defaults to true
}
waf-sec-040.tf.google.ssl-policy-tls-1-2
Engine: terraform | Provider: google | Automated: Yes
Google Cloud SSL policies must enforce TLS 1.2 or higher
All google_compute_ssl_policy resources must set min_tls_version to "TLS_1_2" or "TLS_1_3".
Scope: resource β google_compute_ssl_policy
Assertions:
* min_tls_version in ['TLS_1_2', 'TLS_1_3'] β SSL policy must enforce TLS 1.2 or higher.
Remediation: Set min_tls_version = "TLS_1_2" (or "TLS_1_3") on every google_compute_ssl_policy resource.
resource "google_compute_ssl_policy" "app" {
name = "app-ssl-policy"
profile = "CUSTOM"
min_tls_version = "TLS_1_2"
custom_features = ["TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"]
}
resource "google_compute_ssl_policy" "app" {
name = "app-ssl-policy"
profile = "COMPATIBLE"
# min_tls_version defaults to TLS_1_0 in COMPATIBLE profile
}
waf-sec-040.tf.stackit.resource-data-class-tags
Engine: terraform | Provider: stackit | Automated: Yes
STACKIT resources must be tagged with data classification
All STACKIT resources that store or process data must carry a data-class tag (public, internal, confidential, restricted) to enforce appropriate security controls.
Scope: resource β stackit_object_storage_bucket, stackit_postgres_flex_instance, stackit_mysql_instance, stackit_redis_instance, stackit_opensearch_instance, stackit_load_balancer, stackit_network
Assertions:
* tags key exists β STACKIT resource must have a 'data-class' tag.
Remediation: Add a data-class tag to all STACKIT resources. Use a shared tagging module and enforce it via CI/CD checks.
resource "stackit_object_storage_bucket" "app" {
project_id = var.stackit_project_id
name = "app-data"
tags = {
data-class = "confidential"
owner = "platform-team"
}
}
resource "stackit_object_storage_bucket" "app" {
project_id = var.stackit_project_id
name = "app-data"
# Missing data-class tag β WAF-SEC-040 violation
}
waf-sec-040.tf.ovh.resource-data-class-tags
Engine: terraform | Provider: ovh | Automated: Yes
OVHcloud resources must be tagged with data classification
All OVHcloud resources that store or process data must carry a data-class tag or label (public, internal, confidential, restricted) to enforce appropriate security controls.
Scope: resource β ovh_cloud_project_instance, ovh_vps, ovh_dedicated_server, ovh_cloud_project
Assertions:
* tags key exists β OVHcloud resource must have a 'data-class' tag or label.
Remediation: Add a data-class tag or label to all OVHcloud resources. Document the tagging scheme and enforce it via CI/CD checks.
resource "ovh_cloud_project_instance" "app" {
project_id = var.ovh_project_id
name = "app-vm"
flavor = "b2-7"
image = "Ubuntu 22.04"
tags = {
data-class = "confidential"
owner = "platform-team"
}
}
resource "ovh_cloud_project_instance" "app" {
project_id = var.ovh_project_id
name = "app-vm"
flavor = "b2-7"
image = "Ubuntu 22.04"
# Missing data-class tag β WAF-SEC-040 violation
}
waf-sec-040.tf.hcloud.resource-data-class-labels
Engine: terraform | Provider: hcloud | Automated: Yes
Hetzner Cloud resources must be labelled with data classification
All Hetzner Cloud resources that store or process data must carry a data-class label (public, internal, confidential, restricted) to enforce appropriate security controls.
Scope: resource β hcloud_server, hcloud_volume, hcloud_network, hcloud_load_balancer
Assertions:
* labels key exists β Hetzner Cloud resource must have a 'data-class' label.
Remediation: Add a data-class label to all Hetzner Cloud resources. Use a shared labelling module and enforce it via CI/CD checks.
resource "hcloud_server" "app" {
name = "app-server"
server_type = "cx22"
image = "ubuntu-22.04"
labels = {
data-class = "confidential"
owner = "platform-team"
}
}
resource "hcloud_server" "app" {
name = "app-server"
server_type = "cx22"
image = "ubuntu-22.04"
# Missing data-class label β WAF-SEC-040 violation
}
Evidence
| Kind | Required | Description |
|---|---|---|
|
Required |
Terraform configuration implementing the control. |
|
Required |
Policy, ADR, or standard documenting the requirement. |
|
Optional |
Cloud console or API output confirming runtime state. |
Related Controls
-
WAF-AGN-010 == Regulatory Mapping
| Framework | Controls |
|---|---|
ISO 27001:2022 |
* A.8.20 β Networks security * A.8.21 β Security of network services * A.8.24 β Use of cryptography |
ISO 27017 |
* CLD.13.1 β Network security management in cloud services |
ISO 27018 |
* A.11.2 β PII transmission security |
CIS Controls v8 |
* CIS 3.10 β Encrypt sensitive data in transit * CIS 12.6 β Secure network communications |
CSA STAR |
* CCM CEK-04 β Data in Transit Encryption * CCM IVS-03 β Network Security |
PCI DSS v4.0 |
* Req 4 β Protect cardholder data with strong cryptography during transmission |
SOC 2 Type II |
* CC6.6 β Protection of data in transit |
GDPR |
* Art. 32 β Security of processing * Art. 25 β Data protection by design |
NIS2 |
* Art. 21(2)(h) β Cryptography and encryption |
DORA |
* Art. 9 β Protection and prevention of ICT incidents |
EUCS (ENISA) |
* CKM-01 β Cryptographic policy * CSC-04 β Communications security |
BSI C5:2020 |
* CRY-01 β Use of cryptography * CRY-04 β Encryption of data in transit * COM-01 β Communications security |
IT-Grundschutz |
* NET.3.3 β VPN * CON.1 β Kryptokonzept |
TISAX |
* Information security β Encrypted data transmission |
ANSSI SecNumCloud |
* Domain β Communications security and cryptography |
BIO |
* BIO β Beveiliging van netwerktransport |
ENS High |
* mp.com.2 β ProtecciΓ³n de la confidencialidad * mp.com.3 β ProtecciΓ³n de la autenticidad y de la integridad |
UK Cyber Essentials |
* CE.SC β Secure configuration |
UK NCSC CAF |
* B3.c β Data in transit β encryption |
UK GDPR |
* Art. 32 β Security of processing |
NIST SP 800-53 |
* SC-8 β Transmission Confidentiality and Integrity * SC-13 β Cryptographic Protection * SC-23 β Session Authenticity |
NIST CSF 2.0 |
* PR.DS-02 β Data-in-transit is protected |
FedRAMP |
* SC-8, SC-13, SC-23 (Moderate/High baseline) |
HIPAA |
* Β§ 164.312(e)(1) β Transmission security |
CMMC 2.0 |
* SC.L2-3.13.8 β Cryptographic mechanisms during transit |
IRAP |
* ISM β Cryptography β Transport Layer Security |
CCCS PBMM |
* SC-8 β Transmission confidentiality and integrity |
MAS TRM |
* Ch.11 β Cryptography |
ISMAP |
* Communications security β Encryption of data in transit |
FISC |
* Technical measures β Communications encryption |