test(handler): add FuzzHandle for the empty-payload invariant#30
Merged
test(handler): add FuzzHandle for the empty-payload invariant#30
Conversation
The handler's only caller-controlled input is the Lambda payload, and its documented contract is "accepts empty or null only — anything else is rejected so callers cannot influence token scope." Adds a native Go fuzz target that asserts this contract across adversarial bytes. Seeds include the six cases from TestHandleAcceptsOnlyEmptyPayloads plus boundary inputs (case variations, length edges, trailing NUL, surrounding whitespace, UTF-8 BOM). The oracle is derived directly from the contract: accept iff the trimmed payload is empty or literally "null". Runs as part of `moon :test` (seed corpus replays as regular subtests). A 30s live fuzz run locally produced 0 findings over 13.7M executions / 16 workers. No CI changes. Clears OpenSSF Scorecard code-scanning alert #6 (FuzzingID, 0/10) on the next Scorecard scan — the check passes when a `Fuzz*` function exists in a Go `_test.go` file. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
github-token-broker | 48b6c14 | Commit Preview URL Branch Preview URL |
Apr 24 2026, 01:33 AM |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a native Go fuzz target (
FuzzHandle) against the Lambda handler's sole caller-controlled entry point. The handler's documented contract — "accepts empty ornullpayloads only; anything else is rejected so callers cannot influence token scope" — is a security invariant. This fuzz target asserts that contract across adversarial byte sequences the unit tests don't cover.The oracle is derived directly from the documented rule: accept iff
bytes.TrimSpace(payload)is empty or literally\"null\". Mismatches between oracle and implementation, panics on weird bytes, or future refactors that break control flow would all surface as a fuzz failure.Changes
internal/handler/handler_fuzz_test.go(new, 61 lines).TestHandleAcceptsOnlyEmptyPayloads+ boundary cases (case variations ofnull, short/long near-misses, trailing NUL byte, surrounding whitespace, UTF-8 BOM, plausible JSON object).fakeBrokerfixture fromhandler_test.go— no new helpers.io.Discardso fuzz iterations stay quiet.No CI changes. Moon's existing
testtask (moon.yml:36-41) runsgo test ./cmd/... ./internal/..., which replays the seed corpus as regular subtests. That's enough for OpenSSF Scorecard's Fuzzing detector (alert #6) to pass on the next scan.Verification
moon run :test— green across all packages; FuzzHandle's 15 seeds all pass as subtests.go test -run=^$ -fuzz=FuzzHandle -fuzztime=30s ./internal/handler/— 13,773,192 executions across 16 workers in 30s, 0 failures, notestdata/fuzz/corpus written.gofmt -l internal/handler/handler_fuzz_test.go— clean.Out of scope
fuzztime=5mjob with crash-corpus artifact upload. Deferred intentionally — the seed-replay integration is enough for the Scorecard check and for catching regressions on known-adversarial inputs.validateEmptyPayloaddirectly. The private validator is an implementation detail; fuzzing the publicHandleboundary catches control-flow regressions too.Test plan
FuzzingID) from score 0 to a non-zero score.🤖 Generated with Claude Code