DIPDAP home

owasp.dipdap.org · Public architecture & governance note

OWASP Security Baseline Decision Engine

How a high-level system profile becomes enforceable edge controls: a WAF baseline (Coraza with OWASP CRS, or the WAF you use), bot and rate-limit policy, coverage of every OWASP risk list, and a cross-walk to ITSG-33, with NIST SP 800-53 Rev. 5 as the secondary standard. Results download as Markdown, PDF or CSV.

Open the engine

1. System mission

Security policy is written as control statements (“the system monitors and controls communications at the external boundary”, SC-7). Edge enforcement is written as WAF directives (tx.blocking_paranoia_level=3). Teams usually translate between the two by hand, and the result varies from one team to the next.

The engine closes that gap. An architect describes what the system is (one or more archetypes), what it holds (data classification) and what protects it (WAF and bot-protection vendors). The engine returns:

  • a ready-to-deploy Caddy + Coraza configuration, or starting-point configuration for ModSecurity, AWS WAF, Azure WAF, F5 Advanced WAF, hCaptcha and F5 Bot Defense (Distributed Cloud or On-Prem);
  • the bot-management and rate-limit policy;
  • every item of the selected OWASP lists, marked required or recommended, with its controls and how the edge enforces it;
  • a vendor-to-OWASP coverage table for each selected product, split into its WAF policy and its bot policy;
  • the ASVS target level, the OWASP CI/CD Top 10 and SAMM practices;
  • a protection coverage score per layer and per ITSG-33 control family, with per-layer scope, Implemented / N/A ticks per item, and the effect of mandatory MFA or FIDO2 / WebAuthn;
  • a control-by-control ITSG-33 cross-walk (primary) with the NIST SP 800-53 Rev. 5 equivalents (secondary), with implementation text.

2. Architecture

Internet traffic passes through Caddy TLS termination, per-IP rate limiting and the Coraza WAF with OWASP CRS. Floods receive 429 and anomalous payloads 403. Clean requests are routed to the static documentation or the Flask decision engine. Logs flow to the SIEM.
The engine itself sits behind the controls it recommends: every request passes rate limiting, then Coraza inspection, before any route is served.
  1. TLS termination. Caddy’s automatic HTTPS, TLS 1.3 only, with HSTS, covers SC-8 / SC-8(1). TLS 1.3 is the only protocol every site on this host can offer: TLS 1.2 is refused, with or without a server name.
  2. Rate limiting. caddy-ratelimit zones run before the WAF, so floods and credential stuffing are dropped with 429 before any payload is parsed. The engine's API has its own, stricter zone.
  3. Coraza WAF. OWASP CRS v4 in anomaly-scoring mode, plus local rules (prompt injection, auth telemetry, replay guards). If the summed score reaches the threshold, the request is denied with 403 at CRS 949 (inbound) or 959 (outbound).
  4. Routing. The engine has its own site, owasp.dipdap.org, with its own Let’s Encrypt certificate (renewed automatically) and its own WAF route. /about/* (this page) is served statically; everything else (the UI at /, /api/v1/*, /health) is proxied to the Flask app (gunicorn, WSGI). The old addresses, www.dipdap.org/OWASP/… and www.dipdap.org/public/OWASP/… in any capitalisation, are redirected here with 308, path and query kept (the docs to /about/).
  5. Telemetry. The Caddy JSON access log and the Coraza JSON audit log are shipped to the SIEM (AU-2, AU-6, AU-12, SI-4).

3. Threat model: how data classification escalates paranoia

CRS rules are grouped by Paranoia Level. Higher levels add stricter rules: more aggressive regexes, restricted character sets, and header-consistency checks. They catch more evasions but also produce more false positives. The anomaly threshold is the score at which a request is blocked. A critical match scores 5, an error 4, a warning 3, a notice 2.

The engine sizes both settings, and the ASVS verification level, to the injury that a compromise would cause. The most sensitive class selected sets the baseline.

Data classificationBlocking PLDetection-only PLInbound thresholdASVSRationale
Purely publicPL1PL25L1Low injury. Block clear attacks with near-zero false positives.
CredentialsPL2PL35L2Account takeover risk. Adds session-fixation and protocol-strictness rules.
Protected APL2PL35L2Limited injury to individuals.
Protected BPL3PL43L2Serious injury. Strict payload parsing; a single error-level match blocks.
Financial / taxPL3PL43L3Fraud and PCI DSS exposure. Strict fingerprinting, replay guards, edge IP reputation.

Detection-only PL. The engine sets CRS tx.detection_paranoia_level one level above the blocking level. Rules at that level are logged but never block. Operators can then measure false positives before raising the blocking level. PL4 is only reachable through an explicit override, which the engine flags as tuning-intensive.

Archetype adjustments. Mobile and API-to-API profiles accept PUT/PATCH/DELETE and JSON. They disable CRS 920300 and, for M2M, 920320, because native and service clients routinely omit Accept and User-Agent. GenAI profiles add an inference zone, a prompt-size cap and LLM-specific local rules.

Combined archetypes. An application can be several archetypes at once. The engine then merges them: everything a legitimate client of any part needs is allowed (methods, content types, the largest body), the site-wide rate limit is the most generous of them, and the strict auth, inference and transaction zones are kept. A web portal with a chatbot therefore gets the portal's form handling and the GenAI prompt controls together.

4. OWASP standards coverage

Every item of every selected list is evaluated against the profile. An item is required when it applies (for example A07 Authentication Failures once credentials are handled) and recommended otherwise. Each item carries its engineering controls, the layer that owns it (edge, application, pipeline or mobile client) and what the primary WAF does about it at the edge, so gaps that no WAF can close are visible.

ListItemsSelected by default for
OWASP Top 10 2025 (2021 selectable)A01–A10Web portal, AI / GenAI portal
OWASP API Security Top 10 2023API1–API10Mobile portal, API-to-API
OWASP Mobile Top 10 2024M1–M10Mobile portal
OWASP Top 10 for LLM Applications 2025 (2023 selectable)LLM01–LLM10AI / GenAI portal
OWASP Automated ThreatsOAT-001 … OAT-021 (14 relevant threats)Web portal, mobile portal, AI / GenAI portal

Three engineering baselines are always included:

  • ASVS 5.0 target level from the data classes (table above): L1 opportunistic, L2 standard, L3 advanced / critical.
  • OWASP Top 10 CI/CD Security Risks (CICD-SEC-1 to CICD-SEC-10), with controls such as signed artifacts, pipeline least privilege and secret hygiene, plus the pipeline tests to run (dependency scanning, an OWASP ZAP baseline scan, a synthetic attack set).
  • OWASP SAMM v2: the fifteen practices of its five business functions, each tied to what this baseline contributes.

Compliance references follow the Top 10 edition in use: input validation cites A05:2025, or A03:2021 when the 2021 list is selected.

5. Vendors

One or more products can be selected. Each gets a coverage table against every OWASP item in the profile: edge (the product mitigates it when configured), partial (it helps or detects; the application must still fix it) or none (an application or pipeline control), plus notes on what the product cannot express.

ProductTypeGenerated configurationTypical notes
Caddy + Coraza (OWASP CRS)WAFcoraza.conf, CaddyfileReference target: paranoia levels, thresholds, local rules, response inspection.
Apache + ModSecurity (OWASP CRS)WAFModSecurity configurationSame rule language; rate limits need mod_qos, mod_evasive or the CRS DoS plugin.
AWS WAFWAFWAFv2 web ACL (JSON)Managed rule groups, Bot Control, ATP / ACFP, a silent browser challenge on the login page; rate limits from 10 per window; no response inspection, no paranoia levels.
Azure WAFWAFApplication Gateway WAF policy (ARM template)Default Rule Set 2.2 blocks at an anomaly score of 5 and runs at paranoia level 1 (no level 3 or 4); Bot Manager, rate limits, invisible JavaScript challenge (preview), log scrubbing; no response inspection.
F5 Advanced WAFWAFDeclarative WAF policy (JSON)Attack signatures, violations, Data Guard masking, brute-force and credential-stuffing protection without CAPTCHA, OpenAPI import; rate limits (L7 DoS) and the on-box Bot Defense profile are separate profiles. F5 BD / DI (Distributed Cloud or On-Prem) is listed under bot protection.
ALTCHABot protection—Invisible proof-of-work, no cookies or tracking: the most accessible choice.
Google reCAPTCHA v3 / EnterpriseBot protection—Invisible score; sends telemetry to a third party (privacy warning on Protected and financial data).
hCaptcha Enterprise (passive)Bot protectionPage and server integration, CSPInvisible widget verified on the server; can fall back to a visual challenge below the passive tier (accessibility warning).
F5 Bot Defense + Data Intelligence (BD / DI), Distributed CloudBot protectionIntegration plan (protected endpoints, Data Intelligence receiver)JavaScript and Mobile SDK telemetry on protected endpoints (monitor, block or redirect), on a Distributed Cloud load balancer or a CDN connector; Data Intelligence is an add-on that delivers the data to a SIEM or bucket; third-party telemetry (privacy warning).
F5 Bot Defense + Data Intelligence (BD / DI), On-Prem (BIG-IP)Bot protectionBIG-IP integration plan (connector, protected endpoints, Defense Engine API)Runs on a BIG-IP chassis or VE (native on 17.0+, iApp on 14.1–16.x); the bot decision still comes from F5's Defense Engine API, so the BIG-IP needs outbound access, and requests continue if it does not answer in time.

Results list the WAF products first, then the bot protection products. Each product's coverage is split into its WAF policy and its bot policy, with a line saying where each lives: Azure WAF keeps both in one WAF policy (Default Rule Set 2.2 and the Bot Manager rule set), AWS WAF in one web ACL (managed rule groups, then Bot Control and Fraud Control), F5 Advanced WAF in a security policy plus a separate on-box Bot Defense profile. Caddy + Coraza and ModSecurity have no bot management of their own and should be paired with a bot protection product.

The first selected WAF is the primary one: the edge column of the OWASP coverage, the rule table and the wording of the bot-control enforcement are written for it. coraza.conf and the Caddyfile are only generated when Caddy + Coraza is selected (or when no WAF is).

6. Decision logic

Inputs

  • Archetypes (one or more): Web portal, Mobile portal, AI / GenAI portal, API-to-API
  • Data classes: Public, Credentials, Protected A, Protected B, Financial / tax
  • CRS version: v4.x (default) or v3.3.x (legacy)
  • Threat profiles: Top 10 2025 / 2021, API Top 10 2023, Mobile Top 10 2024, LLM Top 10 2025 / 2023, Automated Threats
  • Vendors: WAF products and bot-protection products (one or more)
  • Authentication: MFA is mandatory; FIDO2 / WebAuthn (security keys or secure-enclave passkeys)
  • Coverage score: layers in scope, Implemented / N/A ticks per item
  • Optional PL override, site address, upstream

Outputs

  • Summary: PL, thresholds, risk tier, ITSG-33 profile, ASVS level, protection coverage score
  • CRS families and local rules, each with a reason
  • Bot and rate-limit controls with OAT references
  • OWASP coverage (with MFA badges), vendor mappings by WAF and bot policy, engineering baselines
  • ITSG-33 and NIST SP 800-53 Rev. 5 control rows; CSV, MD and PDF downloads follow the All / ITSG-33 / NIST filter
  • Vendor configuration; the full report as Markdown or PDF

The rule matrices live as JSON in the engine (CRS families, archetype defaults, bot strategies, compliance cross-walk, OWASP catalogues, vendor coverage, engineering baselines). Configuration is rendered from templates. User-supplied host names are validated against a strict host pattern before they are interpolated into the generated configuration.

Generated coraza.conf ordering

Include @coraza.conf-recommended   # engine defaults
SecRuleEngine On                   # switch from DetectionOnly
Include @crs-setup.conf.example    # CRS defaults (pass-through SecDefaultAction)
SecAction ... id:900000 / 900110   # PL + thresholds: after setup, before rules
SecRule ... id:10100-10410         # local rules: before CRS so they score ahead of 949/959
Include @owasp_crs/*.conf          # CRS rule files
SecRuleRemoveById ...              # archetype tuning: after the rules exist

7. Bot & automated-threat controls

Challenges are invisible (proof-of-work or a risk score) to meet WCAG 2.1 AA: the generated policy never asks for a checkbox or image puzzle. Users who fail a check get an accessible step-up, such as an email or SMS one-time code.

  • All profiles: CRS 913 scanner detection (OAT-014, OAT-018), a general per-IP rate-limit zone (OAT-015), and headless-browser and honeytoken signals against scraping (OAT-011).
  • Credentials: a POST rate limit on /auth/* and account lockout (OAT-007 Credential Cracking, OAT-008 Credential Stuffing, AC-7); breached-password checks; failed-login telemetry (rule 10200) for SIEM correlation; verified sign-up with a disposable-email blocklist (OAT-019); credentials in query strings are scored.
  • Financial / tax: an edge IP-reputation blocklist, a transaction rate-limit zone, an Idempotency-Key replay guard (rule 10300), per-session limits on payment forms (OAT-001 Carding, OAT-010 Card Cracking), reservation expiry (OAT-021 Denial of Inventory), strict fingerprinting at PL3, and logging of card-number patterns in responses.
  • AI / GenAI: inference rate limit, prompt-size cap (LLM10:2025 Unbounded Consumption), prompt-injection heuristics (LLM01:2025), a system-prompt canary, and blocking of AI scrapers on inference routes.

The bot protection products (ALTCHA, reCAPTCHA, hCaptcha, F5 BD / DI in Distributed Cloud or On-Prem) are listed separately from the WAFs, and each WAF’s own bot controls (for example Azure’s Bot Manager rule set or AWS Bot Control) appear under its Bot policy in section 5. Mandatory MFA does not replace these controls: it stops the account takeover, not the traffic.

WAF prompt-injection rules are a coarse, easily evaded signal. Real guardrails belong in the application: input/output classifiers, tool allow-lists and least-privilege agents.

8. Compliance cross-walk

RequirementOWASP referenceITSG-33NIST SP 800-53 Rev. 5Applies when
Boundary protection / WAFCRS v4 / WAF coreSC-7SC-7, SC-7(5), SC-7(18)Always
Least privilege / object-level authorizationA01:2025 / API1 / API5:2023AC-6AC-6Any non-public class
Credential / brute-force mitigationOAT-007 / OAT-008AC-7AC-7, IA-5(1)Credentials
Identification & authenticationA07:2025IA-2, IA-5IA-2, IA-5Credentials
Input validationA05:2025 (+API8:2023, LLM01)SI-10, SI-16SI-10, SI-10(5), SI-16Always
Information leakage preventionCRS 950-959 outboundSI-11SI-11, SC-8Always
Strict session controlA01 / A07:2025AC-2, SC-23, AC-12AC-2, AC-3, SC-23, AC-12Protected B, Financial
Cryptographic transportA04:2025SC-8(1)SC-8(1)Any non-public class
Protection of information at restA04:2025SC-28SC-28Protected A / B, Financial
API parameter & rate inspectionAPI4:2023 / LLM10:2025SC-5SC-5, SI-4Always
Automated threat detection & auditA09:2025 / OAT-014AU-2, AU-6, AU-12, SI-4AU-2, AU-3, AU-6, AU-12, SI-4Always
Software supply chain & developer testingA03:2025 / CICD-SEC-3 / CICD-SEC-9SA-11, SA-22SA-11, SA-22Always
Transaction replay resistanceOAT-001 / OAT-012IA-2(8)IA-2(8), SC-23Financial
Service / partner authenticationAPI2 / API8:2023IA-3, IA-9IA-3, IA-9API-to-API
LLM guardrails / prompt filteringLLM01 / LLM10:2025SI-10, SC-7 (GenAI profile)SI-3, SI-10, SA-11AI archetype or LLM profile

Protected B systems are mapped to GC Security Control Profile 1 (PBMM). Each generated row carries implementation text that names the configured paranoia level, thresholds, paths and limits. Assessors can therefore trace every control statement to a specific directive.

The Compliance matrix tab filters the rows by standard (All, ITSG-33 or NIST SP 800-53 Rev. 5). The CSV, MD and PDF downloads list only the standard selected; All lists both.

9. Protection coverage score

The engine gives the deployed protection profile a number. Every OWASP item of the profile is worth 3 points if it is required and 1 point if it is recommended. It earns them in full when a selected product mitigates it at the edge, half when the product only helps (partial), and nothing otherwise. Items are grouped into six layers:

LayerWhat it holdsHow it is scored
WAF layerWeb and API risks enforced at the edgeFrom the selected WAF
Bot layerOWASP Automated ThreatsFrom the selected WAF and bot protection
Mobile layerOWASP Mobile Top 10Mostly attested (client-side controls)
LLM layerOWASP Top 10 for LLM ApplicationsMostly attested (application guardrails)
Pipeline layerSupply-chain items and the OWASP CI/CD Top 10Attested
Application layerAccess control, design, cryptography and other application controlsPartly from the WAF, otherwise attested

Layers: not applicable and scope

All six layers are always shown. A layer with nothing to score for the profile, such as the LLM layer without the AI / GenAI Portal archetype or the Mobile layer without the Mobile Portal archetype, is marked not applicable and does not count in the overall score.

Different groups own different layers. Untick In scope on a layer to leave it out: an edge team can score only the WAF and Bot layers, a development team only the Pipeline and Application layers. Excluded layers stay listed with their own figures, but the overall score, the control families and the report count only the layers in scope, and the report names them. The choice is kept in the browser.

Tick boxes per item

The engine cannot see the application, the pipeline or the mobile client, so it never awards those points by itself. Each item on the Coverage score tab has two boxes:

BoxMeaningEffect on the score
Implemented, ticked by the operatorThe control is in place in the application, pipeline or mobile clientFull points, reported as self-attested
Implemented, unticked on an item a selected product coversThe product has the feature but it is not enabled in this deployment0 points, reported as not enabled
N/AThe item does not apply to this application; Implemented is clearedLeft out of the score (no points earned or possible)

Reset ticks clears all of them. The MD and PDF reports list the self-attested, not-enabled and N/A items.

Mandatory MFA and FIDO2 / WebAuthn

Two profile options describe how users log in: MFA is mandatory, and FIDO2 / WebAuthn (security keys such as YubiKey, or passkeys held in a device secure enclave or TPM), which is phishing-resistant MFA and ticks the first option too. Items MFA neutralises are scored N/A – mitigated by MFA; items it only reduces are highlighted and still scored.

ItemMFA is mandatoryFIDO2 / WebAuthn
OAT-007 Credential Cracking, OAT-008 Credential StuffingMitigated (N/A)Mitigated (N/A); the credential cannot be phished or relayed
A07 Authentication Failures (2025, 2021)ReducedReduced; also closes phishing and relay attacks, intercepted codes, push fatigue and SIM swap
API2 Broken AuthenticationReduced (interactive logins only)Reduced (interactive logins only)
M1 Improper Credential UsageReducedReduced; no user secret in the app and the key cannot be exported
M3 Insecure Authentication / AuthorizationReducedReduced; the server verifies a device-bound assertion, but authorization checks are still needed, so M3 stays scored
M5 Insecure Communication—Reduced; an interceptor cannot capture a reusable credential
OAT-012 Cashing Out—Reduced; far fewer taken-over accounts
OAT-019 Account Creation—Reduced only when registration requires attested authenticators
LLM06:2025 / LLM08:2023 Excessive AgencyReduced only when high-impact agent actions require the user’s own step-upSame, with a request-bound passkey confirmation
Other LLM Top 10 risks——

MFA counts only when it is enforced on every login path (web, mobile, API, account recovery) with no opt-out (ITSG-33 IA-2(1), IA-2(2)). FIDO2 with user verification meets IA-2(6) and IA-2(8) (NIST SP 800-63B AAL3 when the key cannot be exported). Both protect the login only: a session cookie stolen afterwards still works, account recovery must not fall back to SMS, e-mail or one-time codes, and the login rate limits and bot controls stay in place. If passkeys sync through a cloud account, that account becomes part of the login’s security.

Roll-up and target

The score is also rolled up by ITSG-33 control family (AC, AU, CM, IA, SA, SC, SI). The target follows the most sensitive data class: 60% for public data, 70% with credentials, 75% for Protected A and 85% for Protected B or financial data. The score is indicative: it measures coverage. Not an ITSG-33 assessment: security assessment and authorization (SA&A) decides compliance.

10. Design corrections

The original brief and the source documents for the OWASP catalogues contained several statements that do not hold for current CRS, Coraza or the OWASP projects. The implementation corrects them:

  • CRS 910 / 912 are gone in v4. IP reputation and DoS protection were removed (DoS moved to a plugin). Both also rely on persistent collections that Coraza does not provide. Rate limiting is enforced by caddy-ratelimit and IP reputation by an edge remote_ip blocklist. The v3.3 output marks these families as replaced.
  • LLM Top 10 numbering. In the 2025 edition, LLM04 is Data and Model Poisoning, resource exhaustion is LLM10 Unbounded Consumption, and LLM05 is Improper Output Handling. Mappings follow the edition selected; 2025 is the default.
  • admin off breaks caddy reload. The reload command talks to the admin API. The admin API is bound to localhost:2019 instead.
  • CRS was loaded without setup or tuning. The sample Caddyfile never included crs-setup or set the PL and thresholds. Generated configs now do so, in the required order.
  • SecDefaultAction "phase:2,deny" was removed. CRS rules use block, which inherits the default action. A deny default turns anomaly scoring into first-match blocking. The only defaults added are pass-through ones for phases 3 and 4, because crs-setup sets phases 1–2 only and Coraza does not log rules of a phase that has no default. Without them, outbound (950–959) blocks would go unlogged.
  • Automated-threat identifiers follow the OWASP handbook: OAT-007 Credential Cracking, OAT-008 Credential Stuffing, OAT-001 Carding, OAT-010 Card Cracking, OAT-021 Denial of Inventory, OAT-017 Spamming.
  • CI/CD risks use the project's numbering, from CICD-SEC-1 Insufficient Flow Control Mechanisms to CICD-SEC-10 Insufficient Logging and Visibility.
  • SI-10(1) is “Manual Override Capability”, which is unrelated to WAF input validation. It was replaced by SI-10(5), “Restrict Inputs to Trusted Sources and Approved Formats”.
  • Mobile certificate pinning is done in the app; HPKP is a retired browser header.

11. Build, test & production pipeline

The engine runs on SmartOS pkgsrc zones: the DIPDAP Caddy package (Caddy 2.11, coraza-caddy, embedded OWASP CRS v4, caddy-ratelimit) in front of a Flask app under gunicorn, as an SMF service. It is its own Caddy site, owasp.dipdap.org, with a Let’s Encrypt certificate, the shared logging and security headers, its own rate limits and its own WAF route (managed with the other routes of the host).

  1. Build: export the release tag and assemble a reproducible release tarball. A build host byte-compiles it with Python 3.14, checks the JSON rule matrices, validates the SMF manifest and checks the installer. The checksums are then signed with the DIPDAP package-signing key (CICD-SEC-9).
  2. Test: the signature and checksums are verified, the release is installed on a test zone, and the test suite runs there with the zone's own packages (every archetype, data class and CRS version, combined archetypes, all vendors and both report formats). Through Caddy, synthetic SQLi, XSS, traversal, RCE, Log4Shell and scanner requests must return 403, while legitimate UI, API and report requests return 200. The checks also confirm that the old www.dipdap.org addresses redirect here, that the rest of that site still works and that the rate limit engages.
  3. Production: runs only with the operator's go-ahead. It verifies the signature, takes a backup, re-checks the tarball's SHA-256 on the server, switches the release symlink and restarts the backend. After caddy validate and a graceful reload, it checks over a trusted certificate that /health and /about/ return 200 and that the old www.dipdap.org/OWASP/ address redirects (308), and rolls back automatically on failure.

12. Limitations

  • Generated paths (/auth, /inference, /transactions) are archetype defaults and must be adjusted to the real application.
  • A WAF complements secure code and does not replace it. Access control (A01, API1), business logic and output encoding stay the application’s responsibility; the OWASP coverage shows which items no WAF can close.
  • Vendor mappings and the ModSecurity, AWS WAF, Azure WAF, F5 (Advanced WAF and Bot Defense) and hCaptcha configurations follow the vendors' public documentation as of November 2026 but have not been deployed on those products; they are starting points: verify rule-group and feature names against the vendor's current documentation before deploying.
  • The compliance implementation text describes the reference Caddy + Coraza controls; with another WAF, map them through the vendor table.
  • The effects of MFA and FIDO2 / WebAuthn on each OWASP item are the engine’s judgement, kept in score.json; review them against your own authentication design.
  • CRS v3.3 on Coraza is best-effort legacy support. Coraza targets CRS v4.
  • Any PL change should run in detection-only mode against real traffic before enforcement.