馃帀 Notable changes
This is a security release on top of v2.8.0. It addresses five security findings reported against oapi-codegen:
- Strict servers could bind a different request body than the one the validation middleware checked (runtime behaviour of generated servers)
- Remote
$refs in an untrusted specification could make the generator issue requests to arbitrary hosts (code generation) - An
operationIdcould inject Go code through the Echo per-operation middleware key (code generation) - A request body content type could inject Go code through the webhook and callback initiators (code generation)
- Server
x-go-name, server variables and non-string enum values could inject Go code (code generation)
Four of the five only matter when you generate code from a specification you do not control. The first one affects running servers, so please upgrade the generated code and the oapi-codegen/runtime and validation middleware modules together, as described below.
Allow-listing the remote documents a specification may reference
oapi-codegen resolves external $refs while it loads a specification. Until now it fetched any http(s) URL a document named, so a specification written by someone else could make the generator reach any host the build machine can see.
There is a new top-level configuration option, allow-remote-refs-from. Each entry is the URL of a referenced document exactly as it appears in the $ref, without the #... fragment, or "*" to allow any URL:
allow-remote-refs-from:
- https://raw.githubusercontent.com/example/specs/main/common.yamlFor compatibility, this release defaults the option to "*" when it is omitted, so existing configurations keep working unchanged. The next minor release will default to refusing remote references. If your specification downloads other documents at generation time, tighten this now by listing them, or set the option to [] to refuse them all.
Better still, for reproducible builds, download the specifications you depend on, commit them next to your own, and reference them by relative path. References to local files are always followed, with no allow-listing involved, and your generated code no longer depends on a remote host being up and unchanged.
Strict servers bind the value the validation middleware validated
A validation middleware decodes the JSON request body to validate it, and the generated strict server then decoded it a second time. encoding/json matches member names case-insensitively, so a body such as
{"role": "user", "ROLE": "admin"}validates as role: user but was bound as Role: "admin", bypassing the schema's constraints.
Strict servers for every supported framework now bind the value the middleware already validated, with exact member-name matching, and only fall back to decoding the body themselves when no validated value is present. For the fix to take effect you need all three of:
- code generated with this release;
github.com/oapi-codegen/runtimev1.8.0 or later;- a validation middleware that keeps the validated value, which the following versions do by default:
github.com/oapi-codegen/nethttp-middlewarev1.3.1github.com/oapi-codegen/echo-middlewarev1.2.1github.com/oapi-codegen/echo-v5-middlewarev0.2.1github.com/oapi-codegen/gin-middlewarev1.2.1github.com/oapi-codegen/iris-middlewarev1.2.1github.com/oapi-codegen/fiber-middlewarev1.3.0github.com/oapi-codegen/fiber-v3-middlewarev0.3.0
Without them the generated code behaves as before, so the upgrade is safe to roll out in any order, but the fix is only in effect once all three are updated.
Fewer specification strings reach the generated code unescaped
Every string that the generator copies from a specification into Go source is now either emitted through strconv.Quote or checked before generation: content types in the webhook and callback initiators, the Echo per-operation middleware key, security scopes, non-string enum values (which must now be number or boolean literals), response status keys, component names, response header styles, and, when server-urls is enabled, server names, variables and their enum values. Valid specifications generate byte-for-byte the same code as before; a specification that would have produced code it had no business producing is now rejected with an error that points at the offending value.
馃悰 Bug fixes
- Quote or validate every spec string that reaches generated Go source (2.8.x backport) (#2626) @mromaszewicz
- Apply the allow-remote-refs-from "*" default to the loader used after an overlay (2.8.x) (#2624) @mromaszewicz
- Refuse remote $refs unless their host is in allow-remote-refs-from (2.8.x backport, default "*") (#2623) @mromaszewicz
- Bind the validated request body value in all strict servers (2.8.x backport) (#2621) @mromaszewicz
Sponsors
We would like to thank our sponsors for their support during this release.
We'd also like to thank Greptile for allowing our project to use their code review system.