[codex] fix runtime hardening gaps#599
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b31d06e866
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if endpointDeniedByOmission(exposure.Guards) { | ||
| continue | ||
| } |
There was a problem hiding this comment.
Keep form imports for denied contract decoders
When the only form usage is a guardless bound command/query contract with input fields, this continue suppresses the gowdkform import, but contractDecoderDecls still emits decodeContract... functions for executable exposures and those declarations reference gowdkform.DecodeExpected. The generated app then fails to compile even though the handler now returns 403; either skip those decoder declarations too or keep the import whenever a decoder is emitted.
Useful? React with 👍 / 👎.
| if endpointDeniedByOmission(exposure.Guards) { | ||
| return denyByOmissionJSONStmts() |
There was a problem hiding this comment.
Deny guardless fallback contract handlers too
This default-deny check only runs for executable contract exposures. A guardless routable contract whose binding falls back to fallbackContractHandlerDecl (for example, missing backend registration or unsupported signature) still returns the fallback JSON instead of the new 403, leaving stale or partially generated contract endpoints reachable by omission while actions/APIs/fragments fail closed. Apply the same guard omission check before emitting the fallback handler.
Useful? React with 👍 / 👎.
| go func() { | ||
| ctx, cancel := context.WithTimeout(context.Background(), defaultSinkTimeout) | ||
| defer cancel() | ||
| if err := sink.RecordSpan(ctx, snapshot); err != nil { | ||
| logSinkFailure(err) |
There was a problem hiding this comment.
Recover panicking trace sinks in the async exporter
Now that span export runs in its own goroutine, any panic from a custom Sink.RecordSpan or ExporterSink implementation is no longer contained by the request handler or net/http recovery; an unrecovered panic in this goroutine terminates the entire generated app. Wrap the sink call with a defer recover path before logging/reporting the sink failure.
Useful? React with 👍 / 👎.
| if err == nil || SinkLogger == nil { | ||
| return | ||
| } | ||
| SinkLogger("gowdk trace: sink failed: " + err.Error()) |
There was a problem hiding this comment.
Redact trace sink errors before logging
When an exporter fails with an error that includes connection strings, tokens, or authorization headers, the new default SinkLogger writes err.Error() verbatim. That creates a new credential-leak path specifically on tracing backend failures, while the other hardened runtime logs redact secrets first; redact the error string before passing it to SinkLogger.
Useful? React with 👍 / 👎.
| if endpointDeniedByOmission(fragment.Guards) { | ||
| return denyByOmissionStmts() |
There was a problem hiding this comment.
Avoid stale imports for denied fragments
For a guardless fragment that would otherwise use the static fallback, this new early return removes the only generated gowdkpartial.Fragment reference, but fragmentsUseStaticFallback still causes gowdkpartial to be imported. The same pattern can leave a bound fragment's backend import unused, so generated apps with only such denied fragments fail to compile; skip denied fragments in the import predicates or avoid emitting their unused dependencies.
Useful? React with 👍 / 👎.
Summary
Why
The runtime/generated-output audit found several gaps where stale or malformed generated state could bypass intended defaults, leak internal details, or wedge runtime workers/exporters. This change makes those paths fail closed and adds focused regression coverage.
Validation
go test ./internal/appgen ./runtime/app ./runtime/guard ./runtime/response ./runtime/ratelimit ./runtime/trace ./runtime/contracts ./runtime/contracts/fileoutbox ./addons/authgo test ./...scripts/test-go-modules.shgo build ./cmd/gowdk