AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Fuzz Testing

skill-jeremykuhne-agent-skills-fuzz-testing · by JeremyKuhne

Author and run SharpFuzz coverage-guided fuzz targets for a .NET library. Use when adding a new fuzz target, running the fuzzer locally, installing the fuzzing prerequisites, or promoting a crashing input into a regression test. Covers the cross-TFM harness, the libFuzzer driver workflow, and the crash-to-regression loop.

No reviews yet
0 installs
20 views
0.0% view→install

Install

$ agentstack add skill-jeremykuhne-agent-skills-fuzz-testing

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-jeremykuhne-agent-skills-fuzz-testing)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
27d ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Fuzz Testing? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Fuzz testing

If overlay.md exists beside this file, read it before acting; it contains repository-specific bindings. This core remains usable without it.

A coverage-guided fuzzing harness built on SharpFuzz finds defects that hand-written cases miss: it mutates a byte stream, watches which branches the code under test takes, and steers toward inputs that reach new code. The harness is a stand-alone executable, not a test project - the normal dotnet test run never executes it. A cross-targeted harness can run the same targets against both a modern .NET runtime and .NET Framework.

This skill covers when and how to extend a fuzz harness. The exact instrument-and-run commands, prerequisites, and corpus mechanics live in [references/running.md](references/running.md).

Related skills: a security-review of a parser, codec, or buffer primitive is what motivates most fuzz targets - when that review flags untrusted-input handling, add or extend a fuzz target instead of relying on a single hand-written case. A pre-pr-self-review should treat new public parser / codec / buffer surface as needing a fuzz target (or an explicit "not fuzzed" note). On Windows the prebuilt driver runs natively, so a Linux / WSL path is optional rather than required. A consuming repository wires the concrete harness- and regression-project names, the prerequisites script, and the target list in its overlay.

Installing prerequisites

The harness needs the SharpFuzz instrumentation tool and a libfuzzer-dotnet driver binary. Both install per-user with no elevation; the driver is a prebuilt, per-platform download (coverage-guided fuzzing runs natively on Windows). See [references/running.md](references/running.md) for the one-shot script, the manual path, and the per-prerequisite rationale.

Authoring a fuzz target

  • One target per file, named Target.cs, in the harness namespace.
  • Expose a single internal static void Run(ReadOnlySpan data) entry

point and register it in the target-selection switch in the harness entry point.

  • Treat the fuzz input as an opcode stream: decode operations from the

bytes and drive the type under test. Compute every length / count / position argument in range so that any thrown exception is a genuine defect, not a fuzzer-supplied out-of-range argument.

  • Drive the loop from an opcode cursor that the operations cannot move. When

the type under test is itself a cursor (a reader or writer with a movable position), use a separate reader to pull opcodes and a separate subject instance for the operations. Sharing one reader lets a Reset / Rewind / position-set operation rewind the opcode cursor, so the driving loop re-reads the same bytes forever (a hang, not a crash). An in-process sweep with a watchdog catches this and reports the offending input; libFuzzer just appears to stall.

  • Re-check structural invariants after every operation and throw a dedicated

invariant-exception type on violation (SharpFuzz reports any unhandled exception as a crash; a dedicated type makes invariant failures easy to spot during triage).

  • Follow the repo coding style.
  • Add at least one seed input under the target's corpus directory.

Cross-TFM gotchas

  • A cross-targeted harness may build the library under an older TFM than the

runtime it ships on, so targets must compile on every TFM the library supports. On .NET Framework ReadOnlySpan comes from the System.Memory package.

  • A stackalloc or collection-expression span cannot be passed to a

ref-struct method whose span parameter is not scoped. Pass a slice of the caller-scoped input span instead.

  • A .NET Framework pass exists specifically to catch Release-mode JIT

divergences (for example the [MethodImpl(AggressiveInlining)] plus Unsafe.As sign-extension foot-gun, which only misbehaves in optimized .NET Framework codegen). Always publish in Release for the .NET Framework run.

Crash-to-regression loop

A finding is only useful once it is pinned deterministically:

  1. Verify the crash reproduces before doing anything else. Replay the

crash- input on its own. If it does not reproduce, it is a kill-artifact - the slow in-flight unit the driver dumps when it is interrupted mid-run (Ctrl+C, a killed process, or a --max_total_time expiry). Delete it; do not move it into the crashes directory or commit it.

  1. Once reproduction is confirmed, move the input under the crashes directory.
  2. Minimize it.
  3. Promote a deterministic reproduction (the input bytes plus the asserted

invariant) into the regression test project, running on every supported TFM, so it is enforced on every PR.

What to commit of the fuzzer's output

The fuzzer produces files in several places; only curated artifacts belong in git. .gitignore files should enforce this, but know the intent:

  • corpus//seed-* - commit. Hand-authored seeds that bootstrap

coverage. A seed-* prefix is a clean allowlist.

  • corpus// - do not commit. Machine-generated entries churn

on every run; gitignore them. Never delete them locally - they preserve coverage.

  • crashes/crash-* - commit only genuine, reproduced, minimized inputs

(step 1 above). An un-triaged or non-reproducing crash- is noise.

  • Downloaded driver binaries - do not commit.
  • Stray driver output in the working directory (crash-*, leak-*,

timeout-*, oom-*, slow-unit-*) - do not commit. Root-anchored patterns in the top-level .gitignore keep these from being staged; delete them once triaged.

The rule of thumb: nothing the fuzzer emits autonomously lands in git until a human has decided it carries lasting value - seeds you wrote, or crashes you have reproduced and reduced to a regression test.

References

The mechanics, artifact names, and corpus model trace back to upstream documentation, collected in [references/running.md](references/running.md):

corpus model, and the failing-input artifact names (crash-, leak-, timeout-, oom-, slow-unit). Passing a single file re-runs it as a regression test without fuzzing - the deterministic replay used to confirm a crash reproduces.

the libfuzzer-dotnet driver and Fuzzer.LibFuzzer.Run entry point.

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.