Implementing and Securing OWASP Juice Shop with AWS WAF

This project demonstrates AWS security engineering through the implementation and optimization of OWASP Juice Shop with WAF protection. The implementation follows an approach to deploy, test, and optimize security controls using Infrastructure as Code, automated testing, real-time analytics, and emergency response capabilities.

Our primary objectives include:

  • Deploy security infrastructure using Infrastructure as Code
  • Implement WAF protection with AWS WAF v2 and managed rule sets
  • Build real-time security analytics
  • Create automated CI/CD security pipeline with guardrails and compliance scanning
  • Develop emergency response capabilities with sub-30-second threat mitigation

Tools

  • AWS ECS Fargate - Container orchestration and application hosting
  • AWS Application Load Balancer - Traffic distribution and SSL termination
  • AWS WAF v2 - Web application firewall and edge protection
  • Terraform - Infrastructure as Code automation and configuration management
  • Amazon Kinesis Data Firehose - Real-time data streaming to S3
  • Amazon Athena - Serverless SQL analytics for WAF logs
  • Amazon S3 - Log storage and data lake functionality
  • Amazon CloudWatch - Real-time monitoring and dashboard visualization
  • GitHub Actions - CI/CD pipeline automation
  • tfsec - Static security analysis for Terraform
  • Checkov - Infrastructure security scanning

Phase 1: Infrastructure Deployment

Step 1: Terraform Infrastructure Setup

The deployment establishes a multi-layered architecture using Infrastructure as Code. The implementation creates scalable, secure, and maintainable infrastructure components.

git clone https://github.com/ToluGIT/aws-waf-takeithome.git
cd aws-waf-takeithome
terraform init
terraform plan -var-file="terraform.tfvars" 
terraform apply -var-file="terraform.tfvars"

Review the terraform.tfvars file for parameters such as allowed_cidr_blocks that can be modified according to specific requirements.

Terraform Apply Success

Step 2: WAF Module Implementation

The WAF implementation follows a modular design pattern, creating reusable components for security rules and configurations:

# terraform/modules/edge_waf/main.tf
resource "aws_wafv2_web_acl" "main" {
  name  = var.waf_name
  scope = "CLOUDFRONT"

  default_action {
    allow {}
  }

  # AWS Managed Rules - Common Rule Set
  rule {
    name     = "AWSManagedRulesCommonRuleSet"
    priority = 1
    
    override_action {
      none {}
    }

    statement {
      managed_rule_group_statement {
        name        = "AWSManagedRulesCommonRuleSet"
        vendor_name = "AWS"
      }
    }

    visibility_config {
      cloudwatch_metrics_enabled = true
      metric_name                = "CommonRuleSetMetric"
      sampled_requests_enabled   = true
    }
  }

Important: If attaching to an ALB/ECS, set WAF scope = REGIONAL in the same region. If using CloudFront, scope = CLOUDFRONT and create/manage it in us-east-1.

Step 3: ECS Infrastructure Verification

The ECS service deployment confirms proper multi-AZ distribution, healthy task status, and Application Load Balancer connectivity:

ECS Cluster Overview ECS Service Details ECS Task Configuration

Step 4: Application Verification and Baseline Testing

Application verification confirms successful deployment and establishes baseline functionality before security testing:

Application Verification

Phase 2: Security Testing and Analysis

Step 1: Security Testing Framework Development

The testing combines positive tests (legitimate traffic) with negative tests (attack vectors).

Positive Test Cases (Expected to Pass):

  • basic_homepage: GET /
  • products_page: GET /#/products
  • login_page: GET /#/login
  • legitimate_search: GET /rest/products/search?q=apple

Negative Test Cases (Expected to Block):

  • juice_shop_sqli: GET /rest/products/search?q=’ OR 1=1—
  • classic_sqli_union: GET /rest/products/search?q=apple’ UNION SELECT * FROM users—
  • xss_script_tag: GET /rest/products/search?q=
  • path_traversal: GET /../../etc/passwd

Step 2: Initial Security Assessment

Manual testing of path traversal functionality reveals WAF blocking:

Path Traversal Test Result

Step 3: Automated Testing Execution

Execute security testing using the automated framework:

# Install Python dependencies
pip3 install -r requirements.txt

python3 scripts/smoke_test.py --url $(terraform output -raw juice_shop_url)

The testing framework implementation:

import requests
import json
from datetime import datetime

class SecurityTester:
    def __init__(self, base_url):
        self.base_url = base_url
        self.results = {"positive": [], "negative": []}
    
    def test_positive_cases(self):
        """traffic that should be allowed"""
        positive_tests = [
            {"name": "Homepage Access", "method": "GET", "path": "/"},
            {"name": "Product Listing", "method": "GET", "path": "/rest/products"},
            {"name": "User Login", "method": "POST", "path": "/rest/user/login", 
             "data": {"email": "test@test.com", "password": "test123"}},
            {"name": "Product Search", "method": "GET", "path": "/rest/products/search?q=apple"}
        ]

    def test_negative_cases(self):
        """attacks that should be blocked"""
        attack_tests = [
            {"name": "SQL Injection - Classic", "payload": "' OR 1=1--"},
            {"name": "SQL Injection - Juice Shop", "payload": "')) OR true--"},
            {"name": "XSS - Script Tag", "payload": "<script>alert('xss')</script>"},
            {"name": "Command Injection", "payload": "; cat /etc/passwd"},
            {"name": "Path Traversal", "payload": "../../../../../etc/passwd"},
            {"name": "Remote File Inclusion", "payload": "http://evil.com/shell.php"}
        ]

Step 4: Initial Results Analysis

The initial testing revealed security gaps with 50% effectiveness:

Initial Test Results

Positive Tests: 4/4 passed (All legitimate traffic allowed)
Negative Tests: 3/10 passed (Only 3 attacks blocked)

GAPS IDENTIFIED:
Path traversal attacks: NOT BLOCKED
Command injection: NOT BLOCKED  
Large headers: NOT BLOCKED

Step 5: WAF Configuration Optimization

Root cause analysis identified that managed rules apply their vendor action unless you override. Start new rules in Count for safe tuning, then switch to Block. The configuration fix enables proper attack blocking:

# terraform/modules/edge_waf/main.tf - Remove rule overrides
resource "aws_wafv2_web_acl" "main" {
  # ... existing configuration ...

  rule {
    name     = "AWSManagedRulesSQLiRuleSet"
    priority = 2
    
    # override_action { none {} } means "no override" - let managed rules apply their vendor action
    override_action {
      none {}
    }

    statement {
      managed_rule_group_statement {
        name        = "AWSManagedRulesSQLiRuleSet"
        vendor_name = "AWS"
      }
    }
  }
}

WAF Rule Configuration WAF Rule Details

Step 6: Security Effectiveness Validation

After tuning, 100% of our test suite was blocked:

Final Test Results

Which demonstrates the importance of configuration validation in security effectiveness measurement.

Phase 3: Security Analytics Pipeline

Step 1: Athena Database Configuration

Navigate to Amazon Athena and launch the query editor to establish the analytics foundation:

CREATE DATABASE IF NOT EXISTS waf_analytics;

Athena Database Creation

Step 2: Query Results Location Setup

Configure S3 results location for Athena query processing. Set the query results location to the existing WAF logs bucket:

s3://juice-shop-waf-logs-xxxxxx/athena-results/

Athena Query Results Location

Step 3: External Table Creation

Create Athena external table for WAF log analysis. Modify the create_table.sql query with the correct S3 bucket location:

-- athena/queries/create_table.sql
LOCATION 's3://juice-shop-waf-logs-2od5y8gt/'

'storage.location.template'='s3://juice-shop-waf-logs-2od5y8gt/year=${year}/month=${month}/day=${day}/hour=${hour}/'

Retrieve the S3 bucket name using:

terraform output s3_waf_logs_bucket

Athena Table Creation

Step 4: Security KPI Analysis

Execute KPI metrics queries to generate security analytics:

KPI Metrics Query Results

The simple_kpi_metrics_single.sql query returns CORE_METRICS and TOP_ATTACK_VECTORS views for the last 24 hours

Step 5: Real-Time Monitoring Implementation

Configure CloudWatch dashboard and WAF console monitoring for visibility:

CloudWatch WAF Dashboard:

  • Navigate: CloudWatch → Dashboards → select the WAF dashboard
  • Terraform provisions dashboard named juice-shop-waf-dashboard
  • Panels include: Allowed vs Blocked requests, BlockedRequests by rule

CloudWatch WAF Dashboard

WAF Console Monitoring:

  • Navigate: WAF → Web ACLs → juice-shop-web-acl → Traffic Overview

WAF Console Traffic Overview

Note: WAF logs to S3 via Firehose buffer (approximately 5 minutes or 5 MB). Expect short delays before data appears in Athena.

Phase 4: CI/CD Security Pipeline

Step 1: GitHub Actions Workflow Implementation

The PR-based GitHub Actions pipeline (.github/workflows/edge-ci.yml) enforces security guardrails and produces deployable plans with approval gates:

Workflow Components:

  • Change Detection: Executes only when Terraform, scripts, or workflow files change
  • Security Scans: tfsec and Checkov analyze terraform/ directory and upload SARIF results
  • Terraform Planning: Initializes Terraform, executes terraform plan, and posts summary to PR comments
  • Cost Analysis: Infracost calculates cost deltas (soft-fail for demonstration)
  • Manual Approval Gate: Environment production-approval requires approval before apply
  • Gated Apply: Post-approval execution of terraform apply -auto-approve

The pipeline integrates static security analysis tools:

  • tfsec: Terraform static security analysis with SARIF output
  • Checkov: Infrastructure security scanning with policy enforcement
  • GitHub Security Tab: Automated security findings integration

GitHub Actions Pipeline 1 GitHub Actions Pipeline 2 GitHub Actions Pipeline 3 GitHub Actions Pipeline 4 GitHub Actions Pipeline 5

Phase 5: Emergency Response with Sub-30 Second Threat Mitigation

Step 1: Emergency Blocking Script Development

The emergency response automation (scripts/push_block.py) enables rapid threat mitigation through programmatic WAF rule deployment:

# scripts/push_block.py - Emergency response automation
import boto3
import json
import sys
import ipaddress
from datetime import datetime, timezone

class EmergencyWAFBlocker:
    def __init__(self, web_acl_name, web_acl_id, scope='CLOUDFRONT'):
        self.waf_client = boto3.client('wafv2')
        self.web_acl_name = web_acl_name
        self.web_acl_id = web_acl_id
        self.scope = scope
        
    def validate_ip(self, ip_input):
        """Validate IP address or CIDR range"""
        try:
            # Handle both single IPs and CIDR ranges
            ipaddress.ip_network(ip_input, strict=False)
            return True
        except ValueError:
            return False
    
    def get_web_acl_lock_token(self):
        """Get current lock token for WAF updates"""
        try:
            response = self.waf_client.get_web_acl(
                Name=self.web_acl_name,
                Scope=self.scope,
                Id=self.web_acl_id
            )
            return response['LockToken'], response['WebACL']
        except Exception as e:
            raise Exception(f"Failed to get WAF lock token: {str(e)}")
    
    def create_ip_block_rule(self, ip_address, rule_name=None, dry_run=True):
        """Create IP blocking rule"""
        
        # Validate IP address
        if not self.validate_ip(ip_address):
            raise ValueError(f"Invalid IP address or CIDR: {ip_address}")
        
        # Generate rule name if not provided
        if not rule_name:
            timestamp = datetime.now(timezone.utc).strftime("%Y%m%d_%H%M%S")
            clean_ip = ip_address.replace('.', '_').replace('/', '_')
            rule_name = f"EmergencyBlock_IP_{clean_ip}_{timestamp}"
        
        # Prepare the new rule
        new_rule = {
            'Name': rule_name,
            'Priority': 10,  # High priority for emergency rules
            'Statement': {
                'IPSetReferenceStatement': {
                    'ARN': f'arn:aws:wafv2:us-east-1:{boto3.client("sts").get_caller_identity()["Account"]}:global/ipset/{rule_name}_ipset/{rule_name}'
                }
            },
            'Action': {
                'Block': {}
            },
            'VisibilityConfig': {
                'SampledRequestsEnabled': True,
                'CloudWatchMetricsEnabled': True,
                'MetricName': rule_name
            }
        }

Step 2: Emergency Response Testing and Validation

Execute testing of emergency blocking capabilities:

# Test IP blocking (dry-run mode)
python scripts/push_block.py --ip 192.168.1.100/32 --web-acl-id $(terraform output waf_web_acl_arn) --dry-run

# Test CIDR range blocking (dry-run mode)  
python scripts/push_block.py --ip 10.0.0.0/24 --web-acl-id $(terraform output waf_web_acl_arn) --dry-run

# Test URI pattern blocking (dry-run mode)
python scripts/push_block.py --uri "/admin/*" $(terraform output waf_web_acl_arn) --dry-run

Step 3: IP Address Verification and Testing

Verify current IP address using AWS service:

curl https://checkip.amazonaws.com

IP Address Verification

Step 4: Dry Run Emergency Blocking

Execute dry run test to validate blocking functionality:

python scripts/push_block.py --ip x.x.x.x/32 --web-acl-id $(terraform output waf_web_acl_arn) --dry-run

Emergency Block Dry Run

Step 5: Production Emergency Blocking Execution

Execute emergency blocking without dry-run flag:

python scripts/push_block.py --ip x.x.x.x/32 --web-acl-id $(terraform output waf_web_acl_arn)

Results demonstrate sub-30-second response times:

Emergency Block Execution Emergency Block Response Time

Step 6: Verification of Rule Enforcement

Confirm rule enforcement through AWS WAF Console:

WAF Console Rule Enforcement

Verify blocking effectiveness through application access testing:

Site Blocked 403 Error

Conclusion

Summary of Achievements

This project demonstrates implementation of security infrastructure with measurable results and operational excellence.

Infrastructure Automation: Complete environment deployment using Infrastructure as Code with modular, reusable components adaptable across different applications and environments.

Evidence-Based Security Optimization: Improvement from 50% to 100% security effectiveness through iterative testing, analysis, and rule refinement based on actual attack patterns rather than theoretical threats.

Operational Resilience: Emergency response capabilities with sub-30-second deployment times, safety controls, and detailed audit logging enabling rapid threat mitigation without operational risk.

Lessons Learned

Configuration Validation is Critical: The difference between 50% and 100% security effectiveness resulted from a single configuration parameter. Managed rules apply their vendor action unless you override - proper configuration ensures expected blocking behavior.

Measurement Enables Optimization: Quantifiable security metrics provide the foundation for systematic improvement and evidence-based decision making in security engineering.

Automation Reduces Risk: Emergency response automation eliminates manual processes during critical incidents, reducing response time from minutes to seconds while maintaining safety controls.

AWS WAF Security OWASP Terraform DevSecOps Infrastructure CloudWatch Athena CI/CD