ReviewOS

zig-utils/zig-waf

[WAF-12] Implement the complete stable directive union

#13
Closed chris opened this 9 days ago ·
9 days ago

Objective

Implement the exact case-insensitive stable directive-name union accepted by pinned ModSecurity 3.0.16 and Coraza 3.7.0, with typed schemas, deterministic source-anchored validation, capability discovery, and an immutable configuration model consumed by later execution issues.

WAF-12 owns directive recognition, argument/value validation, cross-directive constraints, build-capability rejection, and configuration introspection. WAF-13 through WAF-31 own later rule updates/actions/operators/body/audit execution. Recognition must never silently claim that an unavailable runtime capability exists.

Pinned executable inventory

The registry is tested against ModSecurity src/parser/seclang-scanner.ll and seclang-parser.yy at 7ea9fefbe0ba409d8733b4d682c8c4c059cd028d, Coraza internal/seclang/directivesmap.gen.go at 27069d06c896be74b77b9a6c0b539a0cbfaca360, and deployable OWASP CRS at 55b09f5acfd16413e7b31041100711ceb7adc89c.

Rules and identity

SecRule, SecAction, SecDefaultAction, SecMarker, SecComponentSignature, SecRuleEngine, SecConnEngine, SecConnReadStateLimit, SecConnWriteStateLimit, SecWebAppId, SecServerSignature, SecSensorId, SecStatusEngine, SecRuleScript.

Request, response, and protocol limits

SecRequestBodyAccess, SecRequestBodyLimit, SecRequestBodyNoFilesLimit, SecRequestBodyInMemoryLimit, SecRequestBodyLimitAction, SecRequestBodyJsonDepthLimit, SecResponseBodyAccess, SecResponseBodyLimit, SecResponseBodyLimitAction, SecResponseBodyMimeType, SecResponseBodyMimeTypesClear, SecArgumentsLimit, SecArgumentSeparator, SecCookieFormat, SecCookieV0Separator, SecStreamInBodyInspection, SecStreamOutBodyInspection, SecContentInjection, SecDisableBackendCompression.

Audit, debug, and external logging

SecAuditEngine, SecAuditLog, SecAuditLog2, SecAuditLogType, SecAuditLogFormat, SecAuditLogStorageDir, SecAuditLogDirMode, SecAuditLogFileMode, SecAuditLogRelevantStatus, SecAuditLogParts, SecAuditLogPrefix, SecDebugLog, SecDebugLogLevel, SecGuardianLog.

Filesystem and uploads

SecDataDir, SecTmpDir, SecUploadDir, SecUploadFileMode, SecUploadFileLimit, SecUploadKeepFiles, SecTmpSaveUploadedFiles, SecChrootDir.

Rule selection and compilation controls

SecRuleRemoveById, SecRuleRemoveByMsg, SecRuleRemoveByTag, SecRuleUpdateTargetById, SecRuleUpdateTargetByMsg, SecRuleUpdateTargetByTag, SecRuleUpdateActionById, SecRuleInheritance, SecRulePerfTime, SecInterceptOnError, SecIgnoreRuleCompilationErrors, SecCacheTransformations, SecPcreMatchLimit, SecPcreMatchLimitRecursion, SecRxPreFilter.

Remote, collections, lookup, hash, Unicode, and XML

SecRemoteRules, SecRemoteRulesFailAction, SecCollectionTimeout, SecGeoLookupDb, SecGsbLookupDb, SecHttpBlKey, SecDataset, SecHashEngine, SecHashKey, SecHashParam, SecHashMethodRx, SecHashMethodPm, SecUnicodeMap, SecUnicodeMapFile, SecXmlExternalEntity, SecParseXmlIntoArgs.

Aliases and capitalization differences map to one canonical entry. No additional Sec* name is accepted without an explicit registry change and compatibility evidence.

Typed registry and configuration model

Each entry defines canonical name and aliases; upstream/CRS presence; arity and repeatability; scope and ordering; typed value schema; runtime/build capabilities; security/redaction; owning downstream issue; upstream references; and positive/negative fixtures.

Schemas cover booleans, enums, bounded unsigned integers, octal modes, byte separators, paths, URLs, regexes, ID/range lists, audit-parts expressions, MIME values/lists, key/value pairs, and directive-specific tuples.

Compilation produces immutable typed settings and preserves every source span. Defaults are explicit. Repeated lists append in source order; singular directives follow documented baseline replacement/error behavior. Unknown names, bad arity, trailing bytes, overflow, invalid enums, unsafe paths/URLs, and contradictions fail before publication.

Capability and compatibility policy

  • The official full build recognizes the complete union.
  • Reduced builds return a stable unavailable-capability diagnostic during loading; no warn-and-ignore behavior.
  • Baseline-unsupported directives still have schemas and explicit support states.
  • Deprecated no-op compatibility requires an explicit accepted_no_effect state, docs, and evidence.
  • PCRE limit directives map to bounded zig-regex controls; production never links PCRE2.
  • Remote rules require authenticated HTTPS, size/time limits, deterministic caching, and fail policy; fetching belongs to WAF-13.
  • Paths are owned normalized values; subsystem owners perform confined I/O.
  • Remote/hash/blocklist keys are redacted from diagnostics and introspection.

Diagnostics and limits

Stable WAF-DIRECTIVE-* codes carry primary/related spans for unknown/unavailable directives; arity/value/enum/integer/mode/separator/path/URL/regex/list/tuple failures; duplicate singular directives; conflicts; ordering/scope violations; missing companions; and secret-safe rendering.

Limits cover registry entries, configured directives, list items, range expansion, MIME types, path/URL/key/value bytes, total typed-setting bytes, diagnostic rendering, and remote/dataset declarations. Validation is iterative with checked arithmetic.

Deliverables

  • src/directives.zig: inventory, schemas, lookup, capability model, typed settings, validator, diagnostics, and introspection.
  • Plan/Builder integration that validates before publication.
  • Exact pinned ModSecurity/Coraza inventory-drift CI tool.
  • Positive/negative fixtures for every schema family and registry entry.
  • Cross-directive/reduced-build tests.
  • Allocation-failure injection, deterministic mutation fuzzing, repeated lifetime checks.
  • ReleaseFast validation benchmark for small and CRS configuration.
  • Documentation and machine-readable evidence.

Acceptance criteria

  • Every pinned union name appears exactly once; aliases resolve deterministically.
  • Every row links schema, capability state, owner issue, upstream presence, and tests.
  • All 58 pinned files pass recognition/schema validation with zero unexplained exclusions.
  • Deployable CRS validates as one ordered configuration set, not only unrelated files.
  • Unknown, malformed, conflicting, or unavailable directives fail with stable spans.
  • Numeric/mode/separator/list parsing is strict and overflow-safe.
  • Secrets never appear in diagnostics, fingerprints, benchmarks, or debug introspection.
  • Reduced builds reject every unavailable used directive before publication.
  • Failed validation/build/reload leaves the active generation unchanged.
  • Fingerprints match for semantically identical ordered settings.
  • Exact Pantry Zig format/test/check, inventory drift, corpus, fuzz, allocation, benchmark, and hosted CI gates pass.

Relationships

Baselines

ModSecurity 3.0.16; Coraza 3.7.0; OWASP CRS 4.28.0; Zig 0.17.0-dev.1441+d5181a9c9 through Pantry.

9 days ago

WAF-09 (#10) now explicitly blocks this scope. Its implementation contract covers bounded TX mutation plus persistent IP/SESSION/USER/GLOBAL/RESOURCE initialization, expiration, atomic conflict-safe updates, failure policy, and real Pantry-managed LMDB persistence.

Do not duplicate or weaken those semantics here; consume the WAF-09 engine/backend APIs once qualified.

9 days ago

WAF-09 (#10) is complete on main and hosted-qualified: https://github.com/zig-utils/zig-waf/actions/runs/29939075574

This issue may now consume the stable TX/persistent collection, action-facing identity binding, expiry, atomic mutation, failure-policy, capability-discovery, in-memory, and LMDB contracts. Preserve typed errors and do not add an alternate persistence path.

9 days ago

Dependency WAF-10 #11 is complete at e72709c with hosted green evidence: https://github.com/zig-utils/zig-waf/actions/runs/29942330646. This issue is now unblocked on the bounded, owned SecLang frontend.

9 days ago

Dependency update: WAF-11 #12 is complete at 19b64bc with exact hosted CI green. This issue can now consume the immutable typed IR, stable diagnostics, prefilters/macro programs, fingerprints, shared payloads, and explicit WAF plan ownership contract.

9 days ago

Implementation slice landed on main in 598f8e5: adds the 85-entry stable ModSecurity 3.0.16 / Coraza 3.7.0 directive registry with canonical case-insensitive lookup, schema/repeatability/capability metadata, upstream presence, sensitive-value classification, and concrete owner issue numbers. The inventory includes Coraza’s recognized SecUnicodeMap form alongside ModSecurity’s SecUnicodeMapFile and SecUnicodeCodePage forms. Verified with the pinned Zig 0.17-dev compiler using focused registry tests and the full zig build test suite.

9 days ago

Implementation slice landed on main in d44fbb1: adds stable WAF-DIRECTIVE-0101–0104 diagnostics, strict scalar/enum/arity schemas, sensitive-value non-echoing diagnostics, reduced-build capability rejection, and mandatory validation in both retained-plan and ownership-transfer Waf.Builder publication paths. Builder.validateCompiledPlan exposes the same source-anchored diagnostic without mutation. Verified with pinned Zig 0.17-dev via zig test src/directives.zig, zig build test, and zig build check.

9 days ago

Corpus gate landed on main in 11cf96e: adds zig build test-directive-corpus, a checked-in smoke fixture, stable source-located failure output, and a hosted CI gate across the pinned CRS 4.28.0, ModSecurity 3.0.16, and Coraza 3.7.0 trees. Local fixture result: 1 file, 11 directives, 1 validated plan, 1 rule; full tests and compile checks pass.

9 days ago

Fixed the first hosted corpus finding in 08a15e5: pinned ModSecurity examples/simple_example_using_c/basic_rules.conf:115 proves SecResponseBodyMimeType accepts one-or-more MIME arguments. The schema and fixture now cover lists. Re-running locally against the exact locked commits validates all 58 files / 925 directives / 58 plans / 761 rules with zero exclusions. Failed evidence run: https://github.com/zig-utils/zig-waf/actions/runs/29947943345.

9 days ago

Hosted CI is green for exact SHA 08a15e5: https://github.com/zig-utils/zig-waf/actions/runs/29948153621. The pinned stable-directive gate passed all 58 configuration files / 925 directives / 58 plans / 761 rules, followed by the complete parser/plan fuzz and benchmark tail.

9 days ago

Typed configuration slice landed on main in 91a86e4: zero-allocation immutable Configuration, normalized typed values, source-ordered occurrence iteration, singular last-wins lookup, secret-safe semantic BLAKE3 fingerprints, and publication-time attachment to Waf. Verified with 59 focused tests, full test/check, and the exact 58-file / 925-directive upstream corpus.

9 days ago

Source-derived compatibility states landed on main in 82b1959, following the exact-union corrections 88afeb4 and eeb0e88, plus inventory gate bb6fe71. The live gate now proves ModSecurity=82 (29 recognized-limited), Coraza=68 (7 recognized-limited), stable union=86, mismatches=0; our runtime state is explicitly schema_only until downstream owners implement semantics.

9 days ago

Ordered semantic fingerprinting landed in ac21927; bounded configuration validation landed in 4a76324. The latter adds stable WAF-DIRECTIVE-0105 limits for directive/argument counts, per-value and aggregate bytes, MIME lists, remote declarations, paths, URLs, and keys; 61 focused tests and the 58-file pinned corpus pass.

9 days ago

Final validation hardening landed in 9c6f774, deterministic directive fuzzing in a06da12, ReleaseFast benchmarking in 1dfaf7e, executable coverage for all 86 rows in 4e48f70, ordered CRS compilation in 5a57405, evidence/docs in 46134e8, and related-span body-limit conflict handling plus failed-generation runtime safety in 8ee46c3. Focused result: 65 tests; inventories 82/29 + 68/7 = 86 with zero drift; 58-file corpus; ordered CRS 30 files / 794 directives / 695 rules; 10,000 deterministic fuzz cases.

9 days ago

Completed on main at 8ee46c32c42e4d9d0730c26cc000f257ef684f45. Exact hosted qualification: Actions run 29950372566 (success).

Acceptance evidence includes the exact 86-directive ModSecurity 3.0.16 / Coraza 3.7.0 stable union, upstream inventory drift gate, executable positive fixture for every schema row, negative schema families, immutable typed configuration and semantic fingerprinting, ordered CRS 4.28 configuration validation, 10,000-case deterministic fuzzing, bounded resource/path/URL/list validation, conflicting body-limit diagnostics, documentation, and benchmark coverage. The request path performs no remote, database, UI, or audit work.

Sign in to comment on this issue.