ruzzy
Ruzzy is a coverage-guided fuzzer for Ruby built on libFuzzer that enables fuzzing pure Ruby code and Ruby C extensions with sanitizer support for detecting memory corruption and undefined behavior. Use Ruzzy when testing Ruby applications, libraries, or gems with native extensions for memory safety issues on Linux x86-64 and AArch64/ARM64 systems.
git clone --depth 1 https://github.com/trailofbits/skills /tmp/ruzzy && cp -r /tmp/ruzzy/plugins/testing-handbook-skills/skills/ruzzy ~/.claude/skills/ruzzySKILL.md
# Ruzzy
Ruzzy is a coverage-guided fuzzer for Ruby built on libFuzzer. It enables fuzzing both pure Ruby code and Ruby C extensions with sanitizer support for detecting memory corruption and undefined behavior.
## When to Use
Ruzzy is currently the only production-ready coverage-guided fuzzer for Ruby.
**Choose Ruzzy when:**
- Fuzzing Ruby applications or libraries
- Testing Ruby C extensions for memory safety issues
- You need coverage-guided fuzzing for Ruby code
- Working with Ruby gems that have native extensions
## Quick Start
Set up environment:
```bash
export ASAN_OPTIONS="allocator_may_return_null=1:detect_leaks=0:use_sigaltstack=0"
```
Test with the included toy example:
```bash
LD_PRELOAD=$(ruby -e 'require "ruzzy"; print Ruzzy::ASAN_PATH') \
ruby -e 'require "ruzzy"; Ruzzy.dummy'
```
This should quickly find a crash demonstrating that Ruzzy is working correctly.
## Installation
### Platform Support
Ruzzy supports Linux x86-64 and AArch64/ARM64. For macOS or Windows, use the [Dockerfile](https://github.com/trailofbits/ruzzy/blob/main/Dockerfile) or [development environment](https://github.com/trailofbits/ruzzy#developing).
### Prerequisites
- Linux x86-64 or AArch64/ARM64
- Recent version of clang (tested back to 14.0.0, latest release recommended)
- Ruby with gem installed
### Installation Command
Install Ruzzy with clang compiler flags:
```bash
MAKE="make --environment-overrides V=1" \
CC="/path/to/clang" \
CXX="/path/to/clang++" \
LDSHARED="/path/to/clang -shared" \
LDSHAREDXX="/path/to/clang++ -shared" \
gem install ruzzy
```
**Environment variables explained:**
- `MAKE`: Overrides make to respect subsequent environment variables
- `CC`, `CXX`, `LDSHARED`, `LDSHAREDXX`: Ensure proper clang binaries are used for latest features
### Troubleshooting Installation
If installation fails, enable debug output:
```bash
RUZZY_DEBUG=1 gem install --verbose ruzzy
```
### Verification
Verify installation by running the toy example (see Quick Start section).
## Writing a Harness
### Fuzzing Pure Ruby Code
Pure Ruby fuzzing requires two scripts due to Ruby interpreter implementation details.
**Tracer script (`test_tracer.rb`):**
```ruby
# frozen_string_literal: true
require 'ruzzy'
Ruzzy.trace('test_harness.rb')
```
**Harness script (`test_harness.rb`):**
```ruby
# frozen_string_literal: true
require 'ruzzy'
def fuzzing_target(input)
# Your code to fuzz here
if input.length == 4
if input[0] == 'F'
if input[1] == 'U'
if input[2] == 'Z'
if input[3] == 'Z'
raise
end
end
end
end
end
end
test_one_input = lambda do |data|
fuzzing_target(data)
return 0
end
Ruzzy.fuzz(test_one_input)
```
Run with:
```bash
LD_PRELOAD=$(ruby -e 'require "ruzzy"; print Ruzzy::ASAN_PATH') \
ruby test_tracer.rb
```
### Fuzzing Ruby C Extensions
C extensions can be fuzzed with a single harness file, no tracer needed.
**Example harness for msgpack (`fuzz_msgpack.rb`):**
```ruby
# frozen_string_literal: true
require 'msgpack'
require 'ruzzy'
test_one_input = lambda do |data|
begin
MessagePack.unpack(data)
rescue Exception
# We're looking for memory corruption, not Ruby exceptions
end
return 0
end
Ruzzy.fuzz(test_one_input)
```
Run with:
```bash
LD_PRELOAD=$(ruby -e 'require "ruzzy"; print Ruzzy::ASAN_PATH') \
ruby fuzz_msgpack.rb
```
### Harness Rules
| Do | Don't |
|----|-------|
| Catch Ruby exceptions if testing C extensions | Let Ruby exceptions crash the fuzzer |
| Return 0 from test_one_input lambda | Return other values |
| Keep harness deterministic | Use randomness or time-based logic |
| Use tracer script for pure Ruby | Skip tracer for pure Ruby code |
> **See Also:** For detailed harness writing techniques, patterns for handling complex inputs,
> and advanced strategies, see the **fuzz-harness-writing** technique skill.
## Compilation
### Installing Gems with Sanitizers
When installing Ruby gems with C extensions for fuzzing, compile with sanitizer flags:
```bash
MAKE="make --environment-overrides V=1" \
CC="/path/to/clang" \
CXX="/path/to/clang++" \
LDSHARED="/path/to/clang -shared" \
LDSHAREDXX="/path/to/clang++ -shared" \
CFLAGS="-fsanitize=address,fuzzer-no-link -fno-omit-frame-pointer -fno-common -fPIC -g" \
CXXFLAGS="-fsanitize=address,fuzzer-no-link -fno-omit-frame-pointer -fno-common -fPIC -g" \
gem install <gem-name>
```
### Build Flags
| Flag | Purpose |
|------|---------|
| `-fsanitize=address,fuzzer-no-link` | Enable AddressSanitizer and fuzzer instrumentation |
| `-fno-omit-frame-pointer` | Improve stack trace quality |
| `-fno-common` | Better compatibility with sanitizers |
| `-fPIC` | Position-independent code for shared libraries |
| `-g` | Include debug symbols |
## Running Campaigns
### Environment Setup
Before running any fuzzing campaign, set ASAN_OPTIONS:
```bash
export ASAN_OPTIONS="allocator_may_return_null=1:detect_leaks=0:use_sigaltstack=0"
```
**Options explained:**
1. `allocator_may_return_null=1`: Skip common low-impact allocation failures (DoS)
2. `detect_leaks=0`: Ruby interpreter leaks data, ignore these for now
3. `use_sigaltstack=0`: Ruby recommends disabling sigaltstack with ASan
### Basic Run
```bash
LD_PRELOAD=$(ruby -e 'require "ruzzy"; print Ruzzy::ASAN_PATH') \
ruby harness.rb
```
**Note:** `LD_PRELOAD` is required for sanitizer injection. Unlike `ASAN_OPTIONS`, do not export it as it may interfere with other programs.
### With Corpus
```bash
LD_PRELOAD=$(ruby -e 'require "ruzzy"; print Ruzzy::ASAN_PATH') \
ruby harness.rb /path/to/corpus
```
### Passing libFuzzer Options
All libFuzzer options can be passed as arguments:
```bash
LD_PRELOAD=$(ruby -e 'require "ruzzy"; print Ruzzy::ASAN_PATH') \
ruby harness.rb /path/to/corpus -max_len=1024 -timeout=10
```
See [libFuzzer options](https://llvm.org/docs/LibFuzzer.html#options) for full reference.
### Reproducing Crashes
Re-run aAudits GitHub Actions workflows for security vulnerabilities in AI agent integrations including Claude Code Action, Gemini CLI, OpenAI Codex, and GitHub AI Inference. Detects attack vectors where attacker-controlled input reaches AI agents running in CI/CD pipelines, including env var intermediary patterns, direct expression injection, dangerous sandbox configurations, and wildcard user allowlists. Use when reviewing workflow files that invoke AI coding agents, auditing CI/CD pipeline security for prompt injection risks, or evaluating agentic action configurations.
Clarify requirements before implementing. Use when serious doubts arise.
Enables ultra-granular, line-by-line code analysis to build deep architectural context before vulnerability or bug finding.
Scans Algorand smart contracts for 11 common vulnerabilities including rekeying attacks, unchecked transaction fees, missing field validations, and access control issues. Use when auditing Algorand projects (TEAL/PyTeal).
Prepares codebases for security review using Trail of Bits' checklist. Helps set review goals, runs static analysis tools, increases test coverage, removes dead code, ensures accessibility, and generates documentation (flowcharts, user stories, inline comments).
Scans Cairo/StarkNet smart contracts for 6 critical vulnerabilities including felt252 arithmetic overflow, L1-L2 messaging issues, address conversion problems, and signature replay. Use when auditing StarkNet projects.
Systematic code maturity assessment using Trail of Bits' 9-category framework. Analyzes codebase for arithmetic safety, auditing practices, access controls, complexity, decentralization, documentation, MEV risks, low-level code, and testing. Produces professional scorecard with evidence-based ratings and actionable recommendations.
Scans Cosmos SDK blockchain modules and CosmWasm contracts for consensus-critical vulnerabilities — chain halts, fund loss, state divergence. 25 core + 16 IBC + 10 EVM + 3 CosmWasm patterns. Use when auditing custom x/ modules, reviewing IBC integrations, or assessing pre-launch chain security. Updated for SDK v0.53.x.