Fuzzing Harness Design
trailofbits/skills
Guides writing and improving fuzzing harnesses for C, C++ and Rust so random byte input gets translated into structured, reproducible test cases for the target code.
API fuzz testing expert covering property-based testing with Hypothesis and fast-check, fuzz testing strategies for REST and GraphQL APIs, edge case generation, mutation testing with Stryker and…
$ npx skills add FerroxLabs/wayland --skill api-fuzzer -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install FerroxLabs/wayland api-fuzzer --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/FerroxLabs/wayland.git skills-src && mkdir -p .claude/skills && cp -r skills-src/src/process/resources/skills-library/bodies/skills/testing-quality/api-fuzzer .claude/skills/api-fuzzer && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "api-fuzzer" agent skill from https://github.com/FerroxLabs/wayland/tree/main/src/process/resources/skills-library/bodies/skills/testing-quality/api-fuzzer into .claude/skills/api-fuzzer/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "api-fuzzer", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/FerroxLabs/wayland/tree/main/src/process/resources/skills-library/bodies/skills/testing-quality/api-fuzzerType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add FerroxLabs/wayland --skill api-fuzzer -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install FerroxLabs/wayland api-fuzzer --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/FerroxLabs/wayland.git skills-src && mkdir -p .agents/skills && cp -r skills-src/src/process/resources/skills-library/bodies/skills/testing-quality/api-fuzzer .agents/skills/api-fuzzer && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "api-fuzzer" agent skill from https://github.com/FerroxLabs/wayland/tree/main/src/process/resources/skills-library/bodies/skills/testing-quality/api-fuzzer into .agents/skills/api-fuzzer/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "api-fuzzer", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add FerroxLabs/wayland --skill api-fuzzer -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install FerroxLabs/wayland api-fuzzer --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/FerroxLabs/wayland.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/src/process/resources/skills-library/bodies/skills/testing-quality/api-fuzzer .cursor/skills/api-fuzzer && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "api-fuzzer" agent skill from https://github.com/FerroxLabs/wayland/tree/main/src/process/resources/skills-library/bodies/skills/testing-quality/api-fuzzer into .cursor/skills/api-fuzzer/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "api-fuzzer", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/FerroxLabs/wayland.git --path src/process/resources/skills-library/bodies/skills/testing-quality/api-fuzzer--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add FerroxLabs/wayland --skill api-fuzzer -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install FerroxLabs/wayland api-fuzzer --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/FerroxLabs/wayland.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/src/process/resources/skills-library/bodies/skills/testing-quality/api-fuzzer .gemini/skills/api-fuzzer && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "api-fuzzer" agent skill from https://github.com/FerroxLabs/wayland/tree/main/src/process/resources/skills-library/bodies/skills/testing-quality/api-fuzzer into .gemini/skills/api-fuzzer/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "api-fuzzer", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install FerroxLabs/wayland api-fuzzerInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add FerroxLabs/wayland --skill api-fuzzer -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/FerroxLabs/wayland.git skills-src && mkdir -p .github/skills && cp -r skills-src/src/process/resources/skills-library/bodies/skills/testing-quality/api-fuzzer .github/skills/api-fuzzer && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "api-fuzzer" agent skill from https://github.com/FerroxLabs/wayland/tree/main/src/process/resources/skills-library/bodies/skills/testing-quality/api-fuzzer into .github/skills/api-fuzzer/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "api-fuzzer", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add FerroxLabs/wayland --skill api-fuzzer -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install FerroxLabs/wayland api-fuzzer --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/FerroxLabs/wayland.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/src/process/resources/skills-library/bodies/skills/testing-quality/api-fuzzer .opencode/skills/api-fuzzer && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "api-fuzzer" agent skill from https://github.com/FerroxLabs/wayland/tree/main/src/process/resources/skills-library/bodies/skills/testing-quality/api-fuzzer into .opencode/skills/api-fuzzer/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "api-fuzzer", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
api-fuzzerAPI fuzz testing expert covering property-based testing with Hypothesis and fast-check, fuzz testing strategies for REST and GraphQL APIs, edge case generation, mutation testing with Stryker and…
API Fuzzer is an agent skill from FerroxLabs/wayland. API fuzz testing expert covering property-based testing with Hypothesis and fast-check, fuzz testing strategies for REST and GraphQL APIs, edge case generation, mutation testing with Stryker and mutmut, boundary value analysis, schema-driven fuzzing, and automated discovery of bugs through randomized inputs. Use when the user asks about api fuzzer, api fuzzer best practices, or needs guidance on api fuzzer implementation. Do NOT use when the user needs a different specialized skill or is asking about an unrelated…
Its SKILL.md is about 4.8k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Security, covering Fuzzing. The repository describes itself as: Wayland - The AI Agent That Perceives. Reasons. Acts. Evolves. The licence is Apache-2.0.
Read from SKILL.md and the folder at commit 4c030c7. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
No scripts in the folder and no shell commands in SKILL.md (its code samples are python, bash, typescript and markdown).
From the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
API Fuzzer loads about 4.8k tokens when it runs. Until then it costs about 137 tokens; SKILL.md has 293 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from FerroxLabs/wayland at commit 4c030c7, republished under its Apache-2.0 licence (© FerroxLabs). 293 words, ~4,773 tokens.
.claude/skills/api-fuzzer/SKILL.md (or your agent's skills folder).You are an expert API Fuzzer who finds bugs that traditional example-based tests miss. You use property-based testing to verify invariants across thousands of random inputs, fuzz APIs with schema-driven input generation, apply mutation testing to measure test suite effectiveness, and systematically explore boundary conditions and edge cases that developers overlook.
Traditional testing:
"Given input X, expect output Y" (one example at a time)
Property-based testing:
"For ALL valid inputs, this property ALWAYS holds"
(framework generates hundreds/thousands of random inputs)
Properties to test:
1. Invariants: "The result always satisfies condition C"
2. Idempotency: "Doing it twice gives the same result as once"
3. Round-trip: "encode(decode(x)) == x"
4. Commutativity: "f(a, b) == f(b, a)"
5. Equivalence: "fast_function(x) == reference_function(x)"
6. No-crash: "The function never throws for valid input"from hypothesis import given, strategies as st, assume, settings, example
from hypothesis.stateful import RuleBasedStateMachine, rule, precondition
import pytest
# Strategy basics: generate random data of specific types
@given(st.integers(), st.integers())
def test_addition_commutative(a, b):
assert a + b == b + a
@given(st.lists(st.integers()))
def test_sort_idempotent(xs):
assert sorted(sorted(xs)) == sorted(xs)
@given(st.lists(st.integers(), min_size=1))
def test_sort_preserves_length(xs):
assert len(sorted(xs)) == len(xs)
# Custom strategies for domain objects
user_strategy = st.fixed_dictionaries({
'username': st.text(
alphabet=st.characters(whitelist_categories=('L', 'N')),
min_size=3, max_size=30
),
'email': st.emails(),
'age': st.integers(min_value=0, max_value=150),
'role': st.sampled_from(['admin', 'user', 'viewer']),
})
@given(user=user_strategy)
def test_user_creation_roundtrip(user):
"""Creating and then fetching a user returns equivalent data."""
created = create_user(user)
fetched = get_user(created['id'])
assert fetched['username'] == user['username']
assert fetched['email'] == user['email']
# API endpoint property testing
@given(
title=st.text(min_size=1, max_size=200),
content=st.text(min_size=1, max_size=10000),
)
@settings(max_examples=200, deadline=5000) # 200 test cases, 5s timeout each
def test_create_post_always_returns_valid_id(client, title, content):
"""POST /api/posts always returns a valid UUID for valid input."""
response = client.post('/api/posts', json={
'title': title,
'content': content,
})
assert response.status_code == 201
data = response.json()
assert 'id' in data
assert len(data['id']) == 36 # UUID format
# Explicit edge cases alongside random generation
@given(st.text())
@example('') # Always test empty string
@example(' ') # Whitespace only
@example('a' * 10000) # Very long string
@example('\x00') # Null byte
@example('<script>alert(1)</script>') # XSS attempt
def test_search_never_crashes(client, query):
"""Search endpoint handles any string input without 500 errors."""
response = client.get(f'/api/search', params={'q': query})
assert response.status_code in [200, 400] # OK or validation error, never 500import fc from 'fast-check';
// Basic property test
test('JSON roundtrip', () => {
fc.assert(
fc.property(fc.anything(), (value) => {
// Some values are not JSON-serializable (undefined, functions)
// So we test the roundtrip property for serializable values
const serializable = JSON.parse(JSON.stringify(value));
expect(JSON.parse(JSON.stringify(serializable))).toEqual(serializable);
})
);
});
// API property test
test('POST /users always returns created user with valid input', () => {
fc.assert(
fc.asyncProperty(
fc.record({
username: fc.string({ minLength: 3, maxLength: 30 })
.filter(s => ./^[a-zA-Z0-9_]+$/.test(s)),
email: fc.emailAddress(),
age: fc.integer({ min: 18, max: 120 }),
}),
async (userData) => {
const response = await get('/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(userData),
});
// Property: valid input always produces 201 or 409 (duplicate)
expect([201, 409]).toContain(response.status);
if (response.status === 201) {
const created = await response.json();
// Property: created user has the submitted username
expect(created.username).toBe(userData.username);
// Property: id is always a valid UUID
expect(created.id).toMatch(
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/
);
}
}
),
{ numRuns: 100 }
);
});
// Custom arbitraries for domain-specific data
const orderArbitrary = fc.record({
items: fc.array(
fc.record({
productId: fc.uuid(),
quantity: fc.integer({ min: 1, max: 99 }),
unitPrice: fc.float({ min: 0.01, max: 9999.99, noNaN: true }),
}),
{ minLength: 1, maxLength: 20 }
),
couponCode: fc.option(fc.stringOf(fc.constantFrom(...'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'), { minLength: 5, maxLength: 10 })),
});
test('order total is always sum of (quantity * unitPrice)', () => {
fc.assert(
fc.property(orderArbitrary, (order) => {
const result = calculateOrderTotal(order);
const expectedTotal = order.items.reduce(
(sum, item) => sum + item.quantity * item.unitPrice, 0
);
// Property: total matches calculated sum (within floating point tolerance)
expect(Math.abs(result.total - expectedTotal)).toBeLessThan(0.01);
// Property: total is never negative
expect(result.total).toBeGreaterThanOrEqual(0);
})
);
});# Stateful testing: model-based testing that generates sequences of operations
from hypothesis.stateful import RuleBasedStateMachine, rule, initialize, precondition
from hypothesis import strategies as st
class ShoppingCartStateMachine(RuleBasedStateMachine):
"""Tests that our shopping cart implementation matches a simple model."""
def __init__(self):
super().__init__()
self.model_cart = {} # Our simple reference model: {product_id: quantity}
self.real_cart = None # The real cart API
@initialize()
def create_cart(self):
response = self.client.post('/api/cart')
self.real_cart = response.json()['id']
self.model_cart = {}
@rule(product_id=st.sampled_from(['prod-1', 'prod-2', 'prod-3']),
quantity=st.integers(min_value=1, max_value=10))
def add_item(self, product_id, quantity):
# Apply to model
self.model_cart[product_id] = self.model_cart.get(product_id, 0) + quantity
# Apply to real system
response = self.client.post(
f'/api/cart/{self.real_cart}/items',
json={'product_id': product_id, 'quantity': quantity}
)
assert response.status_code == 200
@precondition(lambda self: len(self.model_cart) > 0)
@rule(data=st.data())
def remove_item(self, data):
product_id = data.draw(st.sampled_from(list(self.model_cart.keys())))
# Apply to model
del self.model_cart[product_id]
# Apply to real system
response = self.client.delete(
f'/api/cart/{self.real_cart}/items/{product_id}'
)
assert response.status_code == 200
@rule()
def check_cart_state(self):
"""Invariant: real cart always matches model cart."""
response = self.client.get(f'/api/cart/{self.real_cart}')
real_items = {item['product_id']: item['quantity']
for item in response.json()['items']}
assert real_items == self.model_cart
# Run the state machine test
TestShoppingCart = ShoppingCartStateMachine.TestCase# Generate fuzz inputs from OpenAPI/JSON Schema
import schemathesis
import hypothesis
# Load API schema and generate test cases
schema = schemathesis.from_url('[reference URL]')
@schema.parametrize()
def test_api_endpoint(case):
"""Every endpoint handles random valid input without 500 errors."""
response = case.call()
# Property: server should never return 500 for valid schema input
assert response.status_code < 500, (
f"Server error on {case.method} {case.path}\n"
f"Input: {case.body}\n"
f"Response: {response.text[:500]}"
)
# Target specific endpoints
@schema.parametrize(endpoint='/api/users', method='POST')
def test_create_user_fuzz(case):
response = case.call()
if response.status_code == 201:
data = response.json()
assert 'id' in data
assert 'email' in data
# Run with: pytest --hypothesis-seed=0 -v
# Schemathesis also has a CLI:
# schemathesis run [reference URL] --checks all# Systematic boundary value generation for API parameters
BOUNDARY_STRINGS = [
'', # Empty
' ', # Whitespace
' \t\n\r ', # Mixed whitespace
'a' * 1, # Minimum length
'a' * 255, # Common VARCHAR limit
'a' * 256, # One past VARCHAR limit
'a' * 65536, # Large string
'\x00', # Null byte
'\x00abc\x00', # Embedded null bytes
'null', # Literal "null"
'undefined', # Literal "undefined"
'true', # Boolean-like string
'0', # Numeric string
'-1', # Negative numeric string
'1.7976931348623157e+308', # Max float as string
'<script>alert(1)</script>',# XSS payload
"'; DROP TABLE users; --", # SQL injection
'{{7*7}}', # Template injection
'../../../etc/passwd', # Path traversal
'[reference URL]', # URL in text field
]
BOUNDARY_INTEGERS = [
0, -1, 1,
-2147483648, 2147483647, # int32 boundaries
-2147483649, 2147483648, # Just past int32
-9223372036854775808, # int64 min
9223372036854775807, # int64 max
]
BOUNDARY_NUMBERS = [
0.0, -0.0,
0.1 + 0.2, # Floating point precision
float('inf'), float('-inf'),
float('nan'),
1e-308, # Smallest positive float
1.7976931348623157e+308, # Largest float
]
def fuzz_endpoint(client, method, path, field_name, values):
"""Test an endpoint with a list of boundary values for a specific field."""
results = []
for value in values:
body = {field_name: value}
response = getattr(client, method)(path, json=body)
results.append({
'input': repr(value),
'status': response.status_code,
'body': response.text[:200],
})
# No endpoint should return 500 for any input
assert response.status_code < 500, (
f"500 error with {field_name}={repr(value)}: {response.text[:500]}"
)
return resultsMutation testing answers: "How good are my tests, really?"
Process:
1. Take your passing test suite
2. Make a small change (mutation) to your source code
3. Run the test suite against the mutated code
4. If tests still pass → SURVIVED MUTANT (tests missed this case)
5. If tests fail → KILLED MUTANT (tests caught this case)
Mutation score = killed mutants / total mutants * 100%
> 80%: Good test suite
> 90%: Excellent test suite
< 60%: Tests have significant gaps
Common mutation operators:
- Arithmetic: + → -, * → /
- Comparison: > → >=, == → !=
- Boolean: true → false, && → ||
- Return values: return x → return 0, return null
- Remove statements: delete a line of code
- Boundary: x > 0 → x >= 0# Install: install via npm: --save-dev @stryker-mutator/core @stryker-mutator/jest-runner
# Run: npx stryker run
# stryker.conf.json key settings:
# mutate: ["src/**/*.ts", "!src/**/*.test.ts"]
# thresholds: { high: 80, low: 60, break: 50 }# Install and run
install via pip: mutmut
mutmut run --paths-to-mutate=src/ --tests-dir=tests/
mutmut results # View surviving mutants
mutmut html # Generate HTML reportTo kill mutations, tests must verify:
- Boundary conditions: f(100) != f(101) when threshold is 100
- Operator correctness: both > and >= cases covered
- Return value exactness: assert exact values, not just truthiness
- Branch coverage: every if/else path has a test with distinct output
- Negation: test both the positive and negative case of each conditionCategory | Values to Test
------------------|--------------------------------------------------
Empty/null | null, undefined, "", [], {}, 0
Type confusion | "123" vs 123, "true" vs true, "null" vs null
Boundaries | min-1, min, min+1, max-1, max, max+1
Unicode | Emoji, RTL text, combining characters, zero-width
Encoding | UTF-8, Latin-1, URL-encoded, HTML entities
Time | Leap years, DST transitions, year 2038, timezones
Precision | 0.1+0.2, very large numbers, very small decimals
Collections | Empty, single item, duplicate items, max size
Concurrency | Simultaneous identical requests, race conditions
State | Expired tokens, deleted references, stale dataimport asyncio
import aiohttp
from hypothesis import given, strategies as st
async def concurrent_requests(url, payloads, concurrency=50):
"""Fire many requests simultaneously to find race conditions."""
async with aiohttp.ClientSession() as session:
tasks = [session.post(url, json=p) for p in payloads]
responses = await asyncio.gather(*tasks, return_exceptions=True)
return responses
@given(st.integers(min_value=1, max_value=100))
def test_no_double_spending(amount):
"""Concurrent withdraw requests should not overdraft."""
# Create account with known balance
account = create_account(balance=100)
# Send identical withdraw requests concurrently
payloads = [{'account_id': account['id'], 'amount': amount}] * 10
responses = asyncio.run(
concurrent_requests('/api/withdraw', payloads)
)
successes = sum(1 for r in responses if r.status == 200)
final_balance = get_balance(account['id'])
# Property: balance should never go negative
assert final_balance >= 0
# Property: total withdrawn should not exceed original balance
assert successes * amount <= 100Property-Based Testing:
[ ] Core business logic has property tests (invariants, round-trips)
[ ] Custom strategies defined for domain objects
[ ] Stateful tests for multi-step workflows (state machines)
[ ] Edge cases explicitly included alongside random generation
[ ] Shrinking produces minimal failing examples for debugging
API Fuzzing:
[ ] Schema-driven fuzzing against OpenAPI/GraphQL schema
[ ] Boundary values tested for all input fields
[ ] No endpoint returns 500 for any valid-schema input
[ ] Security-relevant payloads included (injection, XSS, traversal)
[ ] Concurrent request fuzzing for race conditions
Mutation Testing:
[ ] Mutation score measured and tracked over time
[ ] Surviving mutants reviewed and tests added for gaps
[ ] Mutation testing runs in CI (at least weekly)
[ ] Threshold set: PR fails if mutation score drops below baseline
Integration:
[ ] Fuzz tests run in CI pipeline
[ ] Failures are reproducible (seeded random generation)
[ ] Test database is reset between fuzz runs
[ ] Results tracked over time to detect test quality regressionUse this skill when:
Do NOT use this skill when:
# Api Fuzzer Analysis
## Context Assessment
[Situation summary and constraints]
## Recommended Approach
[Primary recommendation with rationale]
## Implementation Steps
1. [Step with specific details]
2. [Step with specific details]
3. [Step with specific details]
## Trade-offs and Considerations
- [Key trade-off 1]
- [Key trade-off 2]
## Next Steps
- [Immediate action item]
- [Follow-up action item]Input: "Help me implement api fuzzer for a medium-scale production application"
Output: A structured analysis covering current state assessment, recommended api fuzzer approach with specific patterns, implementation roadmap with milestones, and risk mitigation strategies tailored to the application scale and constraints.
© FerroxLabs, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in src/process/resources/skills-library/bodies/skills/testing-quality/api-fuzzer of FerroxLabs/wayland.
Open the folder on GitHubat commit 4c030c7
API Fuzzer next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| API Fuzzer this skillFerroxLabs/wayland | 608 | — | ~4.8k | Automated safety check: Pass | Apache-2.0 | |
| Fuzzing Harness Designtrailofbits/skills | 7.4k | 1 repos | ~5.3k | Automated safety check: Pass | CC-BY-SA-4.0 | |
| cargo-fuzz Rust Fuzzingtrailofbits/skills | 7.4k | — | ~2.9k | Automated safety check: Pass | CC-BY-SA-4.0 | |
| Property Based Testingtrailofbits/skills | 7.4k | — | ~1.1k | Automated safety check: Pass | CC-BY-SA-4.0 | |
| Directed Test Input GeneratorArabelaTso/Skills-4-SE | 253 | — | ~3k | Automated safety check: Pass | Apache-2.0 | |
| Kernel Testingmohitmishra786/low-level-dev-skills | 253 | — | ~1.4k | Automated safety check: Pass | MIT |
trailofbits/skills
Guides writing and improving fuzzing harnesses for C, C++ and Rust so random byte input gets translated into structured, reproducible test cases for the target code.
trailofbits/skills
Sets up cargo-fuzz for a Cargo-based Rust project: nightly toolchain, fuzz targets, structured inputs, sanitizers, coverage and reproducing crashes.
trailofbits/skills
Writes, reviews, and debugs property-based tests — Hypothesis, fast-check, proptest, jqwik, rapid, and Echidna or Medusa for Solidity invariants.
ArabelaTso/Skills-4-SE
Generate targeted test inputs to reach specific code paths and hard-to-reach behaviors in Python code.
mohitmishra786/low-level-dev-skills
Linux kernel testing skill for KUnit, kselftest, syzkaller, and LTP.
pashov/skills
Generate Echidna/Medusa-compatible Solidity fuzz suites from Foundry or Hardhat projects.
FerroxLabs/wayland
Install, start, connect, and troubleshoot visualization companion projects for Aion/OpenClaw, with Star-Office-UI as the default recommendation.
FerroxLabs/wayland
OpenClaw usage expert: Helps you install, deploy, configure, and use OpenClaw personal AI assistant.
FerroxLabs/wayland
Set up TVControl end to end: install the connector, start TradingView Desktop with its control port open, load a watchlist export, add the indicators they use, and leave a working chart.
FerroxLabs/wayland
End-to-end guide for designing, running, and analyzing A/B tests including experiment design, statistical significance, sample size calculation, common pitfalls, and advanced testing patterns.
FerroxLabs/wayland
Complete academic writing guide covering thesis and dissertation structure, journal article format using IMRaD, literature review methodology, citation management, the peer review process, and…
FerroxLabs/wayland
Web accessibility expertise covering WCAG 2.2 conformance, audit methodology, ARIA patterns, keyboard navigation, screen reader testing, focus management, form accessibility, and automated vs manual…
Categories
API fuzz testing expert covering property-based testing with Hypothesis and fast-check, fuzz testing strategies for REST and GraphQL APIs, edge case generation, mutation testing with Stryker and…. API Fuzzer is an agent skill from FerroxLabs/wayland. API fuzz testing expert covering property-based testing with Hypothesis and fast-check, fuzz testing strategies for REST and GraphQL APIs, edge case generation, mutation testing with Stryker and mutmut, boundary value analysis, schema-driven fuzzing, and automated discovery of bugs through randomized inputs.
API Fuzzer fits situations like: the user asks about api fuzzer; api fuzzer best practices; needs guidance on api fuzzer implementation; the user needs a different specialized skill.
Run `npx skills add FerroxLabs/wayland --skill api-fuzzer -a claude-code`. Or copy the skill folder (src/process/resources/skills-library/bodies/skills/testing-quality/api-fuzzer in FerroxLabs/wayland) into .claude/skills/api-fuzzer in your project. Claude Code loads it when a task matches its description.
Run `npx skills add FerroxLabs/wayland --skill api-fuzzer -a codex`. Or copy the skill folder (src/process/resources/skills-library/bodies/skills/testing-quality/api-fuzzer in FerroxLabs/wayland) into .agents/skills/api-fuzzer in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add FerroxLabs/wayland --skill api-fuzzer -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/api-fuzzer, .gemini/skills/api-fuzzer, .github/skills/api-fuzzer and .opencode/skills/api-fuzzer in your project.
SKILL.md names no scripts, command-line tools or credentials: API Fuzzer is instructions for the agent only. Our summary lists: Python 3.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
API Fuzzer is published under the Apache-2.0 licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.
About 4.8k tokens (SKILL.md is roughly 19k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with API Fuzzer: Fuzzing Harness Design (trailofbits/skills, 7.4k stars), cargo-fuzz Rust Fuzzing (trailofbits/skills, 7.4k stars), Property Based Testing (trailofbits/skills, 7.4k stars) and Directed Test Input Generator (ArabelaTso/Skills-4-SE, 253 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
FerroxLabs (a GitHub user) maintains it in FerroxLabs/wayland, which has 608 GitHub stars. The repository holds 1,194 skills in this directory. The repository was last updated on October 6, 2026.
Source: FerroxLabs/wayland on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.