Skip to content

feat: inject a confined document loader into flatten and schema analysis#220

Merged
fredbi merged 1 commit into
go-openapi:masterfrom
fredbi:feat/confined-ref-loading
Jul 20, 2026
Merged

feat: inject a confined document loader into flatten and schema analysis#220
fredbi merged 1 commit into
go-openapi:masterfrom
fredbi:feat/confined-ref-loading

Conversation

@fredbi

@fredbi fredbi commented Jul 20, 2026

Copy link
Copy Markdown
Member

Flattening and schema analysis resolve remote and relative $ref through the spec package loader, which by default is unsandboxed. A caller processing an untrusted specification had no way to confine that loading, exposing arbitrary file read and SSRF (the same class of issue addressed in go-openapi/spec).

Add an injectable, option-aware loader to the two paths that actually load documents:

  • FlattenOpts.PathLoaderWithOptions, forwarded through ExpandOpts. This covers the whole flatten feature, since ExpandSpec, ResolveRefWithBase and DeepestRef all go through ExpandOpts.
  • SchemaOpts.PathLoaderWithOptions, threaded through AnalyzedSchema and the recursive Schema() calls; inferFromRef now uses spec.ExpandSchemaWithOptions (new in spec v0.22.8) instead of the default-settings ExpandSchema. Flatten's Schema() call sites propagate the loader too.

Set either to a confined loader (e.g. built with loading.WithRoot / loading.WithHTTPClient, or a restricted loader from go-openapi/loads) to safely process untrusted specs. Left nil, behavior is unchanged.

The New() analyzer and the diff package were audited and do not load external documents (in-memory cataloguing and definition-map lookups only), so they need no loader.

Bumps spec to v0.22.8 (for ExpandSchemaWithOptions) and aligns swag to v0.27.3; the testintegration module moves to spec v0.22.8 and loads v0.24.1.

Change type

Please select: 🆕 New feature or enhancement|🔧 Bug fix'|📃 Documentation update

Short description

Fixes

Full description

Checklist

  • I have signed all my commits with my name and email (see DCO. This does not require a PGP-signed commit
  • I have rebased and squashed my work, so only one commit remains
  • I have added tests to cover my changes.
  • I have properly enriched go doc comments in code.
  • I have properly documented any breaking change.

Flattening and schema analysis resolve remote and relative $ref through the spec
package loader, which by default is unsandboxed. A caller processing an untrusted
specification had no way to confine that loading, exposing arbitrary file read
and SSRF (the same class of issue addressed in go-openapi/spec).

Add an injectable, option-aware loader to the two paths that actually load
documents:

  - FlattenOpts.PathLoaderWithOptions, forwarded through ExpandOpts. This covers
    the whole flatten feature, since ExpandSpec, ResolveRefWithBase and
    DeepestRef all go through ExpandOpts.
  - SchemaOpts.PathLoaderWithOptions, threaded through AnalyzedSchema and the
    recursive Schema() calls; inferFromRef now uses spec.ExpandSchemaWithOptions
    (new in spec v0.22.8) instead of the default-settings ExpandSchema. Flatten's
    Schema() call sites propagate the loader too.

Set either to a confined loader (e.g. built with loading.WithRoot /
loading.WithHTTPClient, or a restricted loader from go-openapi/loads) to safely
process untrusted specs. Left nil, behavior is unchanged.

The New() analyzer and the diff package were audited and do not load external
documents (in-memory cataloguing and definition-map lookups only), so they need
no loader.

Bumps spec to v0.22.8 (for ExpandSchemaWithOptions) and aligns swag to v0.27.3;
the testintegration module moves to spec v0.22.8 and loads v0.24.1.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
@fredbi
fredbi merged commit 70fd025 into go-openapi:master Jul 20, 2026
23 checks passed
@fredbi
fredbi deleted the feat/confined-ref-loading branch July 20, 2026 17:49
@codecov

codecov Bot commented Jul 20, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.01%. Comparing base (c194275) to head (5ac7141).
⚠️ Report is 3 commits behind head on master.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #220      +/-   ##
==========================================
- Coverage   92.01%   92.01%   -0.01%     
==========================================
  Files          30       30              
  Lines        3395     3393       -2     
==========================================
- Hits         3124     3122       -2     
  Misses        189      189              
  Partials       82       82              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

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