Skip to content

feat(lab11): hardened nginx + WAF sidecar#1551

Open
RanisKhaertdinov wants to merge 29 commits into
inno-devops-labs:mainfrom
RanisKhaertdinov:feature/lab11
Open

feat(lab11): hardened nginx + WAF sidecar#1551
RanisKhaertdinov wants to merge 29 commits into
inno-devops-labs:mainfrom
RanisKhaertdinov:feature/lab11

Conversation

@RanisKhaertdinov

Copy link
Copy Markdown

Goal

Complete Lab 11 (bonus): harden Nginx in front of Juice Shop with TLS 1.3 + a full security-header set + rate limiting, document the production posture (timeouts, cipher
hardening, cert-rotation runbook), and drop a ModSecurity + OWASP CRS WAF sidecar in front of it that blocks an attack Nginx alone lets through.

Changes

  • labs/lab11/reverse-proxy/nginx.conf — hardened from the starter config:
    • TLS 1.3 only (ssl_protocols TLSv1.3), HSTS bumped to 2 years, ssl_ecdh_curve X25519:secp384r1, session tickets off
    • Connection limit (limit_conn conn 50) added alongside the existing login rate limiter
    • TLS 1.3 cipher suite set via ssl_conf_command Ciphersuites ... instead of ssl_ciphers (see Testing — ssl_ciphers doesn't understand TLS 1.3 suite names and crashes
      nginx)
  • labs/lab11/waf/docker-compose.override.yml (bonus) — adds a ModSecurity v3 + OWASP CRS sidecar (owasp/modsecurity-crs:nginx-alpine) in front of the hardened Nginx, paranoia
    level 1, blocking mode (not detection-only)
  • submissions/lab11.md — full writeup for both tasks + the bonus, written in short, plain sentences: TLS/header proofs, rate-limit and timeout test results, cipher verification,
    a 7-step cert-rotation runbook, and the WAF before/after SQLi test with the exact OWASP CRS rule that fired

Testing

  • HTTPS redirect: curl -sI http://localhost308 to https://localhost/
  • TLS 1.3: openssl s_client -tls1_3Protocol version: TLSv1.3, TLS_AES_256_GCM_SHA384
  • All 6 required security headers confirmed present on a live response (HSTS, X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Permissions-Policy, CSP-Report-Only)
  • Rate limit: 60 concurrent requests to /rest/user/login → 54×429, matching the configured limiter
  • Timeout: the lab's suggested nc-based test doesn't actually test client_header_timeout (plaintext on a TLS-only port just fails the handshake instantly) — wrote a small
    TLS-aware Python script that sends a genuinely incomplete HTTP request and confirmed the server closes it at ~10.02s, matching client_header_timeout 10s
  • Cipher: confirmed TLS_AES_256_GCM_SHA384 + X25519 in use via openssl s_client
  • WAF bonus: ' OR 1=1-- sent to /rest/products/search — through Nginx alone it reached Juice Shop's SQLite layer unfiltered (SQLITE_ERROR: incomplete input); through the WAF
    it returned 403, with the audit log showing OWASP CRS rule 942100 (SQL Injection Attack Detected via libinjection) plus the anomaly-score block rule 949110
  • Two real bugs in the official WAF image were hit and fixed along the way (both explained in the override file and the submission): a relative-path resolution gotcha in the
    compose override, and a mismatched env var name (PROXY_SSL_CERT vs. the image's documented PROXY_SSL_CERT_FILE)

Artifacts & Screenshots

No screenshots — all proof is command output, quoted directly in submissions/lab11.md (redirect headers, TLS handshake output, rate-limit counts, timeout timing, cipher
confirmation, WAF audit log excerpt).

Checklist

  • Title is clear
  • No secrets (self-signed cert/key are gitignored — labs/lab11/reverse-proxy/certs/ never leaves the machine)
  • Submission exists
  • Task 1 — TLS 1.3 + 6 security headers (with proof)
  • Task 2 — Rate limit + timeouts + cipher hardening + cert-rotation runbook
  • Bonus — ModSec WAF + OWASP CRS catching a payload Nginx-alone passes

RanisKhaertdinov and others added 29 commits June 11, 2026 15:28
feat(lab1): juice shop deployment and CI setup
feat(lab2): Threagile threat model + secure variant + auth flow
feat(lab3): SSH signing + gitleaks pre-commit + history rewrite
feat(lab4): SBOM generation + Grype/Trivy SCA comparison + sign-ready attestation
feat(lab5): ZAP baseline + auth + Semgrep + correlation
feat(lab6): Checkov + KICS scans + custom policy
feat(lab7): trivy + PSS restricted + conftest gate
feat(lab8): cosign sign + SBOM/provenance attestations + blob signing
feat(lab9): falco custom rules + conftest hardening policies
feat(lab10): defectdojo governance report + capstone walkthrough
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant