AWS ELB Should Have WAF Enabled
More Info:
WAF should be enabled so that this firewall will prevent malicious attackers to intrude into your system.
Risk Level
High
Address
Security
Compliance Standards
- APRA CPS 234 (Australia)
- AWS Startup Security Baseline
- BSI C5 (Germany)
- Brazil LGPD
- CCPA / CPRA (California)
- CIS Critical Security Controls v8
- CMMC 2.0
- CSA Cloud Controls Matrix v4
- DPDPA
- Digital Operational Resilience Act (EU)
- Essential 8
- HITRUST CSF
- ISO/IEC 27017
- ISO/IEC 27018
- ISO/IEC 27701
- KSA PDPL
- MAS Technology Risk Management (Singapore)
- MITRE ATT&CK (Cloud)
- NIS2 Directive
- NIST CSF
- NIST SP 800-171
- NYDFS 23 NYCRR 500
- PCI
- Reserve Bank of India (RBI) Cyber Security Framework
- Reserve Bank of India (RBI) Master Direction – Information Technology Framework
- SOC2
- SWIFT Customer Security Controls Framework
- Sarbanes-Oxley IT General Controls
- UK NCSC Cyber Assessment Framework
Triage and Remediation
- Remediation
Remediation
Using Console
To remediate the misconfiguration "ELB Should Have WAF Enabled" in AWS using the AWS console, you can follow the below steps:
- Login to the AWS console.
- Navigate to the EC2 dashboard.
- Click on the Load Balancers option from the left-hand menu.
- Select the ELB for which you want to enable the WAF.
- Click on the Listeners tab.
- Click on the Edit button next to the listener for which you want to enable the WAF.
- In the Edit Listener dialog box, click on the Add Rule button.
- Select the AWS WAF option from the dropdown menu.
- Choose the WebACL that you want to associate with the ELB.
- Click on the Save button to save the changes.
Once you have completed the above steps, the WAF will be enabled for your ELB in AWS.
Using CLI
To remediate the misconfiguration of ELB not having WAF enabled in AWS using AWS CLI, follow the below steps:
- Open AWS CLI on your local machine and run the following command to list all the AWS Elastic Load Balancers:
aws elbv2 describe-load-balancers
-
From the response, identify the ARN of the ELB that you want to enable WAF for.
-
Run the following command to create an AWS WAF WebACL:
aws wafv2 create-web-acl --name MyWebACL --scope REGIONAL
Note: Replace "MyWebACL" with a name of your choice for the WebACL.
-
From the response, note down the ARN of the newly created WebACL.
-
Run the following command to associate the WebACL with the ELB:
aws wafv2 associate-web-acl --web-acl-arn arn:aws:wafv2:us-west-2:123456789012:regional/webacl/MyWebACL --resource-arn arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/app/my-load-balancer/1234567890abcdef
Note: Replace the WebACL ARN and ELB ARN with the ARNs that you noted down in the previous steps.
- Finally, verify that the WAF is enabled for the ELB by running the following command:
aws elbv2 describe-load-balancers --load-balancer-arns arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/app/my-load-balancer/1234567890abcdef
Note: Replace the ELB ARN with the ARN of the ELB that you enabled WAF for.
Once you have completed these steps, WAF will be enabled for the specified ELB in your AWS environment.
Using Python
To remediate the misconfiguration of ELB not having WAF enabled in AWS using Python, follow these steps:
- Import the necessary libraries:
import boto3
- Create a boto3 client for AWS WAF:
waf = boto3.client('waf')
- Create a boto3 client for AWS ELB:
elbv2 = boto3.client('elbv2')
- Get a list of all the ELBs in the region:
elbs = elbv2.describe_load_balancers()
- Loop through each ELB and check if WAF is enabled:
for elb in elbs['LoadBalancers']:
elb_arn = elb['LoadBalancerArn']
waf_associations = elbv2.describe_load_balancer_waf_enabling_ip_sets(LoadBalancerArn=elb_arn)
if len(waf_associations['WebACLs']) == 0:
# WAF is not enabled for this ELB
# Enable WAF for this ELB
waf.create_web_acl(
Name='MyWebACL',
MetricName='MyWebACLMetric',
DefaultAction={
'Type': 'ALLOW'
}
)
waf_rules = waf.list_rules()
rule_id = None
for rule in waf_rules['Rules']:
if rule['Name'] == 'AWS-AWSManagedRulesCommonRuleSet':
rule_id = rule['RuleId']
break
if rule_id is None:
# No rule found
# Exit the loop
break
waf.update_web_acl(
WebACLId=web_acl_id,
ChangeToken=waf.get_change_token()['ChangeToken'],
Updates=[
{
'Action': 'INSERT',
'ActivatedRule': {
'Priority': 1,
'RuleId': rule_id,
'Action': {
'Type': 'BLOCK'
}
}
}
]
)
elbv2.associate_web_acl(
WebACLArn=waf_arn,
ResourceArns=[elb_arn]
)
-
If WAF is not enabled for an ELB, create a new web ACL, add a rule to it, and associate it with the ELB.
-
The final code will look like this:
import boto3
# Create a boto3 client for AWS WAF
waf = boto3.client('waf')
# Create a boto3 client for AWS ELB
elbv2 = boto3.client('elbv2')
# Get a list of all the ELBs in the region
elbs = elbv2.describe_load_balancers()
# Loop through each ELB and check if WAF is enabled
for elb in elbs['LoadBalancers']:
elb_arn = elb['LoadBalancerArn']
waf_associations = elbv2.describe_load_balancer_waf_enabling_ip_sets(LoadBalancerArn=elb_arn)
if len(waf_associations['WebACLs']) == 0:
# WAF is not enabled for this ELB
# Enable WAF for this ELB
waf.create_web_acl(
Name='MyWebACL',
MetricName='MyWebACLMetric',
DefaultAction={
'Type': 'ALLOW'
}
)
waf_rules = waf.list_rules()
rule_id = None
for rule in waf_rules['Rules']:
if rule['Name'] == 'AWS-AWSManagedRulesCommonRuleSet':
rule_id = rule['RuleId']
break
if rule_id is None:
# No rule found
# Exit the loop
break
waf.update_web_acl(
WebACLId=web_acl_id,
ChangeToken=waf.get_change_token()['ChangeToken'],
Updates=[
{
'Action': 'INSERT',
'ActivatedRule': {
'Priority': 1,
'RuleId': rule_id,
'Action': {
'Type': 'BLOCK'
}
}
}
]
)
elbv2.associate_web_acl(
WebACLArn=waf_arn,
ResourceArns=[elb_arn]
)
Note: This code is just an example. You may need to modify it according to your specific requirements.
Using Terraform
resource "aws_wafv2_web_acl_association" "alb_waf" {
resource_arn = aws_lb.app.arn # existing Application Load Balancer
web_acl_arn = aws_wafv2_web_acl.app_waf.arn # or replace with "WEB_ACL_ARN" for an existing ACL
}
resource "aws_lb" "app" {
name = "APP_ALB_NAME" # replace with your ALB name
internal = false
load_balancer_type = "application"
subnets = [SUBNET_ID_1, SUBNET_ID_2] # replace with your subnet IDs
security_groups = [SECURITY_GROUP_ID] # replace with your security group ID
}
resource "aws_wafv2_web_acl" "app_waf" {
name = "APP_WAF_NAME" # replace with your Web ACL name
description = "WAF for Application Load Balancer"
scope = "REGIONAL"
default_action {
allow {}
}
visibility_config {
cloudwatch_metrics_enabled = true
metric_name = "app-waf-metrics"
sampled_requests_enabled = true
}
# Add rules here, initially in COUNT mode to avoid blocking legitimate traffic.
}
Associating the Web ACL via aws_wafv2_web_acl_association may change how traffic is handled but does not force replacement of the load balancer itself; it only creates or replaces the WAF association for that ALB.
After updating Terraform, terraform plan should show one new aws_wafv2_web_acl_association to be created (or updated if it existed) with resource_arn set to the ALB ARN and web_acl_arn set to the desired WAFv2 Web ACL ARN.