Skip to content

Feature/openapi coverage - #72

Merged
cognitivegears merged 9 commits into
mainfrom
feature/openapi-coverage
Jul 4, 2026
Merged

Feature/openapi coverage#72
cognitivegears merged 9 commits into
mainfrom
feature/openapi-coverage

Conversation

@cognitivegears

Copy link
Copy Markdown
Owner

Description

Type of change

  • [ X ] Bug fix
  • [ X ] New feature
  • [ X ] Documentation update
  • [ X ] Code refactoring
  • Other (please describe):

Checklist

  • [ X ] I have performed a self-review of my own code
  • [ X ] I have added tests that prove my fix is effective or that my feature works
  • [ X ] All unit tests pass locally with my changes
  • [ X ] All integration tests pass locally with my changes
  • [ X ] I have updated the documentation accordingly

How to test

Additional context

cognitivegears and others added 9 commits July 4, 2026 14:33
GoldenFileTest compares generated .conf/schema.json for every sample spec
and engine flavor against checked-in goldens (regenerate with
-DupdateGoldenFiles=true). MODSECURITY_INDEX_MAX 30->40 and PROP_INDEX_MAX
6->12 reserve id slots for upcoming rule types so ids stay stable.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…th/regex issues

- Spec-provided patterns are now written back sanitized; previously the
  template and path regex rendered the DefaultCodegen-mangled /.../ form
  with doubled backslashes, rejecting all valid values (and breaking route
  matching for path params with patterns).
- Root-level JSON array request bodies are flattened (element index 0
  generalized to both engines' key forms); previously the ARGS_NAMES
  allowlist was empty and every element key was blocked as unknown.
- Pattern-less string path params now match [^/]+ instead of .+ so values
  cannot cross segment boundaries.
- allowEmptyValue query params accept empty values.
- OAS 3.1 numeric exclusiveMinimum/Maximum verified working (test added).
- Deleted the petstore-specific photoUrls hack in JsonSchemaGenerator and
  fixed the array-of-primitive type clobbering it papered over.
- Numeric enums no longer crash pattern generation (CCE) and are emitted
  as typed JSON values in schema.json instead of strings.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
EngineBehaviorProbeTest (gated behind -DrunEngineProbes=true) probes JSON
null flattening, empty-body signals, multipart ARGS_POST behavior, Coraza
JSON Schema keyword support, and XML validation on both engines. Findings
recorded in docs/engine-behavior.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Media types (items 2,4): each consume entry is classified (json/xml/
form-like/wildcard/other) with its own gate, rule ids, and pass path;
form-urlencoded and multipart operations are no longer unconditionally
blocked, */* skips the content-type gate, and declared-but-uninspectable
types are governed by the new unknownMediaTypePolicy option. Optional
request bodies (the OAS3 default) skip body checks when no Content-Type
is present instead of being blocked.

False positives (items 5-10): map/free-form object properties allowlist
their subtrees (map values validated against the additionalProperties
schema); nullable properties accept the empty value JSON null flattens
to; explode=false arrays validate the joined CSV/space/pipe form;
deepObject bracket keys are allowlisted; matrix/label path styles wrap
their path segments; apiKey-in-query security parameters are allowlisted;
readOnly required properties lose their presence rule; and the servers.url
base path is auto-prefixed onto path regexes (overridable via the new
basePath option). Array parameters now derive per-item patterns from the
item schema instead of the container's flags.

Also adds power-of-10 multipleOf groundwork, raw-body HTTP steps for the
integration harness, and a media-type Cucumber scenario. Existing petstore
scenarios move to /v2 paths per that spec's servers declaration.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…unts (Phase 4)

- Header parameters get REQUEST_HEADERS value rules plus a presence rule
  when required; cookie parameters likewise via REQUEST_COOKIES. Undeclared
  headers and cookies are never blocked.
- Required query and form parameters gain &ARGS @eq 0 presence rules.
- Power-of-10 integer multipleOf becomes a trailing-zeros value pattern on
  both parameters and body properties; other multipleOf values are
  schema.json-only (Coraza).
- Body arrays of primitives enforce maxItems unconditionally and minItems
  when the array is required; absent-vs-empty is indistinguishable per-field
  on ModSecurity3, so optional-array minItems and min/maxProperties are
  schema-only (documented in docs/engine-behavior.md).
- New samples/paramfeatures.yaml with a both-engines Cucumber scenario and
  raw GET header/cookie steps in the integration harness.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ds, nullable (Phase 5)

Maps emit additionalProperties with their value schema, free-form objects
emit additionalProperties true, multipleOf and min/maxProperties are
emitted, exclusive bounds use the numeric exclusiveMinimum/Maximum form,
nullable properties become [type, null] arrays, and required lists drop
readOnly properties (mirroring the per-field rules). Also removes the
postProcessModels override that repeatedly overwrote schema.json with
partial single-model content before the combined write.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
New XsdGenerator emits an XML Schema from the models (elements, attributes,
wrapped arrays, and simple-type facets: pattern, lengths, bounds,
enumerations), validated in tests via JAXP accept/reject round-trips.

The @validateSchema XML rule and schema.xsd are gated behind the new
validateXmlSchema option, DEFAULT FALSE: container probes showed current
libmodsecurity3 cannot load XSDs at request time (its XXE hardening
disables libxml2's entity loader, so the operator fails open and blocks
ALL XML including valid documents) and Coraza rejects XML rules at config
load. Documented in docs/engine-behavior.md; the XSD remains useful for
application-side validation and for engine builds where the loader works.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…equired, content params (Phase 7)

Raw-spec keyword pass: the generator lazily re-parses the original document
(openapi-generator's normalizer strips 3.1 keywords like prefixItems from
the in-memory model) and walks it along flattened body paths.

Per-field rules: const becomes an exact-match value rule (overriding
inferred nullability); dependentRequired at the body root becomes chained
presence rules; patternProperties replaces the free-form wildcard with
name-scoped allowlist entries plus typed value rules; content: parameters
get a bounded length cap (clamped to RE2's repeat-count limit of 1000).

schema.json: const, prefixItems, patternProperties, dependentRequired,
dependentSchemas, if/then/else, contains, propertyNames are copied verbatim
from the raw spec (refs rewritten to #/definitions), staying on draft-07 —
container probes confirmed Coraza enforces all of them under that $schema.

Also fixes chained rules to carry a t:none action (libmodsecurity rejects
actionless chain members — latent bug in the nested-required chain too)
and adds samples/oas31.yaml with a both-engines Cucumber scenario.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…, schema root type

Container-probed and fixed three Coraza behaviors that silently broke
root-array request bodies end-to-end:

- Coraza lists a bare 'json' node in ARGS_NAMES for root-array bodies
  (not for object bodies); root-array allowlists now include it.
- Coraza LOWERCASES arg keys before matching regex collection selectors,
  so any selector containing an uppercase property name (userStatus)
  silently never matched — a latent false NEGATIVE across all generated
  per-field rules for mixed-case properties. All generated selectors now
  carry an inline (?i) flag, accepted by both engines.
- The schema.json root no longer declares type:object, which made
  Coraza's @validateSchema reject every root-array body.

All facts recorded in docs/engine-behavior.md. Adds root-array
valid/invalid steps to the petstore body-validation scenario; both
engines verified live (valid 200 / invalid element 403).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@cognitivegears
cognitivegears merged commit 15dd243 into main Jul 4, 2026
6 checks passed
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