From 6bca505f11fb1b64d17ed73a19ea6a17cc773796 Mon Sep 17 00:00:00 2001 From: Scott Piper Date: Fri, 19 Jun 2020 16:34:39 -0600 Subject: [PATCH 1/4] Detect if request smuggling is denied in ALBs; Resolves #599 --- audit_config.yaml | 8 +++++++- collect_commands.yaml | 5 +++++ shared/audit.py | 21 +++++++++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/audit_config.yaml b/audit_config.yaml index a3a25f9b1..6eca1fcae 100644 --- a/audit_config.yaml +++ b/audit_config.yaml @@ -382,4 +382,10 @@ ACCESSANALYZER_OFF: title: Access Analyzer off description: Access Analyzer is a free service that can tell you when resources are public or shared with unexpected accounts. severity: Medium - group: AccessAnalyzer \ No newline at end of file + group: AccessAnalyzer + +REQUEST_SMUGGLING: + title: Request smuggling not denied + description: "HTTP request smuggling is possible against ALBs, as described here: https://99designs.com/blog/engineering/request-smuggling/" + severity: Low + group: ELB \ No newline at end of file diff --git a/collect_commands.yaml b/collect_commands.yaml index 094630911..0aaaf5e8d 100644 --- a/collect_commands.yaml +++ b/collect_commands.yaml @@ -152,6 +152,11 @@ Parameters: - Name: TargetGroupArn Value: elbv2-describe-target-groups/*|.TargetGroups[].TargetGroupArn +- Service: elbv2 + Request: describe-load-balancer-attributes + Parameters: + - Name: LoadBalancerArn + Value: elbv2-describe-load-balancers.json|.LoadBalancers[].LoadBalancerArn - Service: elbv2 Request: describe-tags Parameters: diff --git a/shared/audit.py b/shared/audit.py index 3b2e5916d..3ea4fa058 100644 --- a/shared/audit.py +++ b/shared/audit.py @@ -834,6 +834,26 @@ def audit_ec2(findings, region): ) +def audit_elbv2(findings, region): + json_blob = query_aws(region.account, "elbv2-describe-load-balancers", region) + + for load_balancer in json_blob.get("LoadBalancers", []): + arn = load_balancer["LoadBalancerArn"] + + # Check attributes + attributes_json = get_parameter_file( + region, "elbv2", "describe-load-balancer-attributes", arn + ) + # print(json.dumps(attributes_json, indent=2)) + + for attribute in attributes_json.get("Attributes", []): + if ( + attribute["Key"] == "routing.http.drop_invalid_header_fields.enabled" + and attribute["Value"] == "false" + ): + findings.add(Finding(region, "REQUEST_SMUGGLING", arn)) + + def audit_sg(findings, region): # TODO Check if security groups allow large CIDR range (ex. 1.2.3.4/3) # TODO Check if an SG restricts IPv4 and then opens IPv6 or vice versa. @@ -1143,6 +1163,7 @@ def audit(accounts): audit_redshift(findings, region) audit_es(findings, region) audit_ec2(findings, region) + audit_elbv2(findings, region) audit_sg(findings, region) audit_lambda(findings, region) audit_glacier(findings, region) From 692b336310df09282a84c2a1d5b67ee2ede68c1d Mon Sep 17 00:00:00 2001 From: Scott Piper Date: Fri, 19 Jun 2020 16:35:30 -0600 Subject: [PATCH 2/4] Bump version --- cloudmapper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloudmapper.py b/cloudmapper.py index 178f280a7..ee38bedb2 100755 --- a/cloudmapper.py +++ b/cloudmapper.py @@ -30,7 +30,7 @@ import pkgutil import importlib -__version__ = "2.9.0" +__version__ = "2.9.1" def show_help(commands): From 8d495a26e91c45b3915a19562423a512715ceb43 Mon Sep 17 00:00:00 2001 From: Scott Piper Date: Fri, 19 Jun 2020 16:44:42 -0600 Subject: [PATCH 3/4] Add files needed for testing --- .../accessanalzyer-list-analyzers.json | 14 ++++++++ ...89012%3Aloadbalancer%2Fapp%2Fdemo%2Fqwerty | 32 +++++++++++++++++++ shared/audit.py | 1 - tests/unit/test_audit.py | 3 +- 4 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 account-data/demo/us-east-1/accessanalzyer-list-analyzers.json create mode 100644 account-data/demo/us-east-1/elbv2-describe-load-balancer-attributes/arn%3Aaws%3Aelasticloadbalancing%3Aus-east-1%3A123456789012%3Aloadbalancer%2Fapp%2Fdemo%2Fqwerty diff --git a/account-data/demo/us-east-1/accessanalzyer-list-analyzers.json b/account-data/demo/us-east-1/accessanalzyer-list-analyzers.json new file mode 100644 index 000000000..55ce4da8b --- /dev/null +++ b/account-data/demo/us-east-1/accessanalzyer-list-analyzers.json @@ -0,0 +1,14 @@ +{ + "analyzers": [ + { + "arn": "arn:aws:access-analyzer:us-east-1:000000000000:analyzer/default", + "createdAt": "2020-06-19T21:20:04Z", + "lastResourceAnalyzed": "arn:aws:sqs:us-east-1:000000000000:test", + "lastResourceAnalyzedAt": "2020-06-19T21:20:04.664Z", + "name": "default", + "status": "ACTIVE", + "tags": {}, + "type": "ACCOUNT" + } + ] +} diff --git a/account-data/demo/us-east-1/elbv2-describe-load-balancer-attributes/arn%3Aaws%3Aelasticloadbalancing%3Aus-east-1%3A123456789012%3Aloadbalancer%2Fapp%2Fdemo%2Fqwerty b/account-data/demo/us-east-1/elbv2-describe-load-balancer-attributes/arn%3Aaws%3Aelasticloadbalancing%3Aus-east-1%3A123456789012%3Aloadbalancer%2Fapp%2Fdemo%2Fqwerty new file mode 100644 index 000000000..afde4c8eb --- /dev/null +++ b/account-data/demo/us-east-1/elbv2-describe-load-balancer-attributes/arn%3Aaws%3Aelasticloadbalancing%3Aus-east-1%3A123456789012%3Aloadbalancer%2Fapp%2Fdemo%2Fqwerty @@ -0,0 +1,32 @@ +{ + "Attributes": [ + { + "Key": "access_logs.s3.enabled", + "Value": "false" + }, + { + "Key": "access_logs.s3.bucket", + "Value": "" + }, + { + "Key": "access_logs.s3.prefix", + "Value": "" + }, + { + "Key": "idle_timeout.timeout_seconds", + "Value": "60" + }, + { + "Key": "deletion_protection.enabled", + "Value": "false" + }, + { + "Key": "routing.http2.enabled", + "Value": "true" + }, + { + "Key": "routing.http.drop_invalid_header_fields.enabled", + "Value": "false" + } + ] +} \ No newline at end of file diff --git a/shared/audit.py b/shared/audit.py index 3ea4fa058..47714e7b9 100644 --- a/shared/audit.py +++ b/shared/audit.py @@ -844,7 +844,6 @@ def audit_elbv2(findings, region): attributes_json = get_parameter_file( region, "elbv2", "describe-load-balancer-attributes", arn ) - # print(json.dumps(attributes_json, indent=2)) for attribute in attributes_json.get("Attributes", []): if ( diff --git a/tests/unit/test_audit.py b/tests/unit/test_audit.py index efe71f7e0..926e484fb 100644 --- a/tests/unit/test_audit.py +++ b/tests/unit/test_audit.py @@ -46,7 +46,8 @@ def test_audit(self): "EC2_OLD", "IAM_UNEXPECTED_S3_EXFIL_PRINCIPAL", "IAM_LINTER", - "EC2_IMDSV2_NOT_ENFORCED" + "EC2_IMDSV2_NOT_ENFORCED", + "REQUEST_SMUGGLING" ] ), ) From 57f62f3de89a00a36e6aa6ca20efe6cc36e91b3d Mon Sep 17 00:00:00 2001 From: Scott Piper Date: Fri, 19 Jun 2020 16:44:51 -0600 Subject: [PATCH 4/4] Update parliament --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index ac563715b..d20a6f703 100644 --- a/requirements.txt +++ b/requirements.txt @@ -19,7 +19,7 @@ mock==4.0.2 netaddr==0.7.19 nose==1.3.7 pandas==1.0.4 -parliament==0.4.14 +parliament==0.5.0 policyuniverse==1.1.0.1 pycodestyle==2.5.0 pyflakes==2.2.0