### Run engine-raw example Source: https://github.com/mjkoo/vitiate/blob/main/examples/engine-raw/README.md Execute the engine-raw example from the repository root after building. ```bash node examples/engine-raw/fuzzme.mjs ``` -------------------------------- ### Install Vitiate Source: https://github.com/mjkoo/vitiate/blob/main/docs/src/content/docs/getting-started/quickstart.md Installs the Vitiate package and its dependencies. Use `@vitiate/core` if only the Vitest plugin is needed. ```bash npm install --save-dev vitiate ``` -------------------------------- ### Verify Migration: Install Dependencies Source: https://github.com/mjkoo/vitiate/blob/main/docs/src/content/docs/guides/migrating-from-jazzerjs.md Ensure all project dependencies are installed correctly after the migration. ```bash npm ci ``` -------------------------------- ### Full Vitiate Plugin Configuration Example Source: https://github.com/mjkoo/vitiate/blob/main/docs/src/content/docs/reference/plugin-options.md An example demonstrating a complete Vite configuration with the vitiatePlugin, including instrument, fuzz, dataDir, and coverageMapSize options. ```typescript import { defineConfig } from "vitest/config"; import { vitiatePlugin } from "@vitiate/core/plugin"; export default defineConfig({ plugins: [ vitiatePlugin({ instrument: { include: ["src/**/*.ts"], exclude: ["**/*.test.ts"], }, fuzz: { maxLen: 8192, timeoutMs: 5000, }, dataDir: ".vitiate", coverageMapSize: 65536, }), ], test: { projects: [ { extends: true, test: { name: "unit", include: ["test/**/*.test.ts"] } }, { extends: true, test: { name: "fuzz", include: ["test/**/*.fuzz.ts"] } }, ], }, }); ``` -------------------------------- ### Vitiate Fuzzer Output Examples Source: https://github.com/mjkoo/vitiate/blob/main/docs/src/content/docs/getting-started/quickstart.md Displays example output during fuzzing, showing execution statistics and crash detection. ```text fuzz: elapsed: 3s, execs: 1024 (3412/sec), corpus: 23 (5 new), edges: 142 fuzz: elapsed: 6s, execs: 2048 (3506/sec), corpus: 31 (8 new), edges: 158 ``` ```text fuzz: CRASH FOUND: TypeError: Cannot read properties of undefined (reading 'length') fuzz: crash artifact written to: .vitiate/testdata/vxr4kpqyb12fza1gv81bjj8k3i64mlqn-parse_does_not_crash/crashes/crash-e5f6... ``` -------------------------------- ### Install FuzzedDataProvider Source: https://github.com/mjkoo/vitiate/blob/main/docs/src/content/docs/guides/structure-aware-fuzzing.md Install the FuzzedDataProvider package as a development dependency using npm. ```bash npm install --save-dev @vitiate/fuzzed-data-provider ``` -------------------------------- ### Vitiate Fuzzer Output Example Source: https://github.com/mjkoo/vitiate/blob/main/docs/src/content/docs/getting-started/tutorial.md Example output from the Vitiate fuzzer showing elapsed time, execution count, corpus size, and edges reached. ```text fuzz: elapsed: 1s, execs: 512 (2841/sec), corpus: 15 (15 new), edges: 89 fuzz: elapsed: 4s, execs: 2048 (3120/sec), corpus: 34 (19 new), edges: 127 fuzz: elapsed: 10s, execs: 8192 (3254/sec), corpus: 41 (7 new), edges: 143 ``` -------------------------------- ### Add Example Seeds for URL Parser Source: https://github.com/mjkoo/vitiate/blob/main/docs/src/content/docs/guides/dictionaries-and-seeds.md Populate the seed directory with various valid and edge-case URL formats. This helps the fuzzer explore different parsing paths. ```bash # Initialize test data directories (creates seed directories for all fuzz tests) npx vitiate init # Find the created directory SEED_DIR=$(ls -d .vitiate/testdata/*parseUrl*/seeds) # Valid URLs of different shapes echo -n 'https://example.com' > "$SEED_DIR/seed-https" echo -n 'http://user:pass@host:8080/path?q=1#frag' > "$SEED_DIR/seed-full" echo -n 'ftp://[::1]:21/' > "$SEED_DIR/seed-ipv6" # Edge cases echo -n '' > "$SEED_DIR/seed-empty" echo -n ':///' > "$SEED_DIR/seed-minimal" ``` -------------------------------- ### CLI SpawnChild Implementation Source: https://github.com/mjkoo/vitiate/blob/main/openspec/specs/parent-supervisor/spec.md Example of the `spawnChild` function implementation for the CLI entry point. It re-executes the current process with specific environment variables. ```typescript spawn(process.execPath, process.argv.slice(1), { env: { VITIATE_SUPERVISOR: "1" } }) ``` -------------------------------- ### Path resolution and matching logic Source: https://github.com/mjkoo/vitiate/blob/main/openspec/specs/path-traversal-detector/spec.md Shows how path arguments are resolved using `path.resolve()` and then matched against configured paths. This example demonstrates the prefix false positive prevention where a path like `/var/www-evil/data.txt` does not match an entry of `/var/www`. ```javascript path.resolve() ``` -------------------------------- ### Hook HTTP Get API Source: https://github.com/mjkoo/vitiate/blob/main/openspec/specs/ssrf-detector/spec.md Installs a hook for the http.get API. This is necessary because http.get calls a local request function, not the module export. ```javascript installHook("http", "get", ...) ``` -------------------------------- ### Instrument Specific Dependency Source: https://github.com/mjkoo/vitiate/blob/main/docs/src/content/docs/reference/plugin-options.md Example of how to instrument a specific dependency like 'some-library' using the packages option. ```typescript vitiatePlugin({ instrument: { packages: ["some-library"], }, }); ``` -------------------------------- ### Use Dictionary for Fuzzer Source: https://github.com/mjkoo/vitiate/blob/main/docs/src/content/docs/guides/cli.md Specifies a dictionary file with domain-specific tokens to guide the fuzzer using the -dict flag. ```bash # Use a dictionary file with domain-specific tokens npx vitiate libfuzzer test/parser.fuzz.ts -dict ./tokens.dict ``` -------------------------------- ### Vitest SpawnChild without Config Source: https://github.com/mjkoo/vitiate/blob/main/openspec/specs/parent-supervisor/spec.md Example of the `spawnChild` function implementation for Vitest when no configuration file is used. The `--config` flag is omitted. ```typescript spawn(process.execPath, [vitestCliPath, "run", testFile, "--test-name-pattern", pattern], { env: { VITIATE_SUPERVISOR: "1", VITIATE_FUZZ: "1" } }) ``` -------------------------------- ### Add Seed Inputs to Vitiate Source: https://github.com/mjkoo/vitiate/blob/main/docs/src/content/docs/getting-started/tutorial.md Populate the generated seed directories with representative examples to mutate from. These seeds help the fuzzer explore different code paths more effectively. ```bash # Initialize test data directories (creates seed directories for all fuzz tests) npx vitiate init # Find the created directory SEED_DIR=$(ls -d .vitiate/testdata/*parseUrl*/seeds) echo -n 'https://example.com' > "$SEED_DIR/seed-basic" echo -n 'http://user:pass@host.com:8080/path?key=value&foo=bar#section' > "$SEED_DIR/seed-full" echo -n 'ftp://[::1]:21/file' > "$SEED_DIR/seed-ipv6" ``` -------------------------------- ### Vitest SpawnChild Implementation Source: https://github.com/mjkoo/vitiate/blob/main/openspec/specs/parent-supervisor/spec.md Example of the `spawnChild` function implementation for Vitest. It spawns a filtered Vitest child process, including configuration flags when available. ```typescript spawn(process.execPath, [vitestCliPath, "run", testFile, "--test-name-pattern", pattern, "--config", configPath], { env: { VITIATE_SUPERVISOR: "1", VITIATE_FUZZ: "1" } }) ``` -------------------------------- ### GitHub Actions CI Configuration Source: https://github.com/mjkoo/vitiate/blob/main/docs/src/content/docs/guides/ci-fuzzing.md Example GitHub Actions workflow demonstrating how to set up regression tests and fuzzing jobs. It includes caching the corpus across runs to build on previous coverage and conditional fuzzing based on the event type (PR or schedule). ```yaml name: Fuzz on: push: branches: [main] pull_request: schedule: - cron: '0 2 * * *' # nightly jobs: regression: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 20 - run: npm ci - run: npx vitiate regression fuzz: runs-on: ubuntu-latest needs: regression steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 20 - run: npm ci # Cache the corpus across runs to build on previous coverage - uses: actions/cache@v4 with: path: .vitiate/corpus key: fuzz-corpus-${{ hashFiles('test/**/*.fuzz.ts') }}-${{ github.run_number }} restore-keys: | fuzz-corpus-${{ hashFiles('test/**/*.fuzz.ts') }}- fuzz-corpus- # Short fuzz on PRs, long fuzz on nightly schedule - name: Fuzz (short) if: github.event_name == 'pull_request' run: npx vitiate fuzz --fuzz-time 300 - name: Fuzz (nightly) if: github.event_name == 'schedule' run: npx vitiate fuzz --fuzz-time 3600 - uses: actions/upload-artifact@v4 if: failure() with: name: crash-artifacts path: .vitiate/testdata/**/crashes/crash-* ``` -------------------------------- ### Dictionary Discovery in Vitest Mode Source: https://github.com/mjkoo/vitiate/blob/main/openspec/specs/user-dictionary/spec.md In Vitest mode, dictionary files are discovered by scanning the testdata directory for '*.dict' files or a file named 'dictionary'. This example shows the discovery of a '.dict' file. ```text .vitiate/testdata//json.dict ``` -------------------------------- ### Handle Missing Dictionary File Source: https://github.com/mjkoo/vitiate/blob/main/openspec/specs/user-dictionary/spec.md If the specified dictionary file does not exist, Vitiate will exit with an error before starting the fuzzer. This prevents unexpected behavior due to missing input data. ```bash npx vitiate libfuzzer ./test.ts -dict=./missing.dict ``` -------------------------------- ### Hook HTTPS Get API Source: https://github.com/mjkoo/vitiate/blob/main/openspec/specs/ssrf-detector/spec.md Installs a hook for the https.get API. Similar to http.get, this ensures interception of secure GET requests. ```javascript installHook("https", "get", ...) ``` -------------------------------- ### Initialize Fuzzer Seeds Source: https://github.com/mjkoo/vitiate/blob/main/docs/src/content/docs/guides/troubleshooting.md If the fuzzer is not finding anything, add representative inputs as seeds in `.vitiate/testdata//seeds/`. Run `npx vitiate init` to create the necessary directories. ```bash npx vitiate init ``` -------------------------------- ### Instrument Specific Packages Source: https://github.com/mjkoo/vitiate/blob/main/docs/src/content/docs/guides/troubleshooting.md To avoid slow startup caused by instrumenting all dependency files, list only the specific packages you need to investigate in `instrument.packages`. ```typescript vitiatePlugin({ instrument: { packages: ["specific-lib"], // only instrument what you need }, }); ``` -------------------------------- ### Get command injection tokens Source: https://github.com/mjkoo/vitiate/blob/main/openspec/specs/command-injection-detector/spec.md The getTokens() function should return the goal string and common shell metacharacters. ```javascript getTokens() ``` -------------------------------- ### Import FuzzedDataProvider Source: https://github.com/mjkoo/vitiate/blob/main/docs/src/content/docs/reference/fuzzed-data-provider.md Import the FuzzedDataProvider class from the library. This is typically the first step before using the provider. ```typescript import { FuzzedDataProvider } from "@vitiate/fuzzed-data-provider"; ``` -------------------------------- ### Hook HTTPS Request API Source: https://github.com/mjkoo/vitiate/blob/main/openspec/specs/ssrf-detector/spec.md Installs a hook for the https.request API. This allows interception of secure outgoing HTTPS requests. ```javascript installHook("https", "request", ...) ``` -------------------------------- ### Hook HTTP Request API Source: https://github.com/mjkoo/vitiate/blob/main/openspec/specs/ssrf-detector/spec.md Installs a hook for the http.request API. This function is used to intercept and analyze outgoing HTTP requests. ```javascript installHook("http", "request", ...) ``` -------------------------------- ### Combined Enable and Option Source: https://github.com/mjkoo/vitiate/blob/main/openspec/specs/standalone-cli/spec.md Enable a detector and configure it with an option simultaneously using the -detectors flag. ```bash npx vitiate libfuzzer ./test.ts -detectors=pathTraversal,pathTraversal.deniedPaths=/etc/passwd ``` -------------------------------- ### Comments and Blank Lines Skipped Source: https://github.com/mjkoo/vitiate/blob/main/openspec/specs/user-dictionary/spec.md Illustrates that comments (lines starting with '#') and blank lines are ignored during parsing. Only the 'value' token is added. ```text # This is a comment keyword="value" ``` -------------------------------- ### Vitiate CLI Usage Source: https://github.com/mjkoo/vitiate/blob/main/docs/src/content/docs/reference/cli-flags.md The general command structure for using the vitiate CLI. Subcommands and options can be appended. ```bash npx vitiate [options] ``` -------------------------------- ### Load Dictionary via CLI Flag Source: https://github.com/mjkoo/vitiate/blob/main/openspec/specs/user-dictionary/spec.md Execute Vitiate with the `-dict` flag to specify a dictionary file. The path is resolved relative to the current directory and passed to the child process. ```bash npx vitiate libfuzzer ./test.ts -dict=./my.dict ``` -------------------------------- ### Detector Option with Dotted Syntax Source: https://github.com/mjkoo/vitiate/blob/main/openspec/specs/standalone-cli/spec.md Configure a detector with specific options using dotted syntax. For example, specifying denied paths for pathTraversal. ```bash npx vitiate libfuzzer ./test.ts -detectors=pathTraversal.deniedPaths=/etc/passwd ``` -------------------------------- ### Execute Vitiate LibFuzzer Subcommand with Test File Source: https://github.com/mjkoo/vitiate/blob/main/openspec/specs/standalone-cli/spec.md Executes the 'libfuzzer' subcommand with a test file, preserving previous behavior and setting up shmem for child process communication. ```bash npx vitiate libfuzzer ./tests/parser.fuzz.ts ``` -------------------------------- ### Interesting Input Persistence: No Disk Write (libfuzzerCompat) Source: https://github.com/mjkoo/vitiate/blob/main/openspec/specs/fuzz-loop/spec.md Describes the scenario where interesting inputs are not written to disk when `libfuzzerCompat` is true and `corpusOutputDir` is not set, relying on in-memory storage. ```text WHEN `reportResult()` returns `Interesting` AND `libfuzzerCompat` is true AND `corpusOutputDir` is not set THEN no file is written to disk AND the input is retained in the in-memory corpus for the remainder of the process ``` -------------------------------- ### Vitiate Fuzzer Status Output Source: https://github.com/mjkoo/vitiate/blob/main/docs/src/content/docs/guides/cli.md This is an example of the periodic status line printed by the Vitiate fuzzer during execution. It provides insights into the fuzzing progress. ```text fuzz: elapsed: 3s, execs: 1024 (3412/sec), corpus: 23 (5 new), edges: 142 ``` -------------------------------- ### Vitest CLI Resolution Logic Source: https://github.com/mjkoo/vitiate/blob/main/openspec/specs/test-fuzz-api/spec.md Illustrates the logic for resolving the Vitest CLI path, ensuring compatibility across different Vitest versions by reading the 'bin' field from 'vitest/package.json'. ```javascript createRequire(import.meta.url).resolve('vitest/package.json') ``` -------------------------------- ### Instantiate FuzzedDataProvider Source: https://github.com/mjkoo/vitiate/blob/main/docs/src/content/docs/reference/fuzzed-data-provider.md Create a new FuzzedDataProvider instance by passing a Uint8Array or a Buffer containing the data to be consumed. This initializes the provider with the fuzzer-generated input. ```typescript new FuzzedDataProvider(data: Uint8Array) ``` -------------------------------- ### CLI Detector Syntax - With Options Source: https://github.com/mjkoo/vitiate/blob/main/docs/src/content/docs/reference/detectors.md Command-line interface syntax for configuring detectors with options. Use dot notation for the detector name and colon-separated values for multiple options. ```bash # With options (dot notation, colon-separated values) -detectors pathTraversal.deniedPaths=/etc/passwd:/etc/shadow -detectors ssrf.blockedHosts=10.0.0.0/8:172.16.0.0/12 -detectors redos.thresholdMs=200 ``` -------------------------------- ### Add a Dictionary for Vitiate Source: https://github.com/mjkoo/vitiate/blob/main/docs/src/content/docs/getting-started/tutorial.md Provide domain-specific tokens in a dictionary file to improve fuzzer performance. This helps the fuzzer generate structurally valid inputs more efficiently. ```text "://" "http" "https" "ftp" "@" ":" "/" "?" "&" "=" "#" "%20" "[::1]" "localhost" ``` -------------------------------- ### Logical Operator Instrumentation Source: https://github.com/mjkoo/vitiate/blob/main/openspec/specs/edge-coverage/spec.md Instruments the right-hand side of logical AND, OR, and nullish coalescing operators to track short-circuit evaluation paths. Each short-circuited path gets a distinct counter. ```javascript a && (__vitiate_cov[ID]++, b) ``` ```javascript a ?? (__vitiate_cov[ID]++, b) ``` ```javascript a && b || c ``` -------------------------------- ### Hooking fs.copyFile with callback Source: https://github.com/mjkoo/vitiate/blob/main/openspec/specs/path-traversal-detector/spec.md Illustrates hooking a dual-path function like `copyFile` from the `fs` module when using a callback. Both the source and destination paths are checked against the configured denied paths. ```javascript fs.copyFile("safe.txt", "/etc/crontab", callback) ``` -------------------------------- ### Custom denied paths in tokens Source: https://github.com/mjkoo/vitiate/blob/main/openspec/specs/path-traversal-detector/spec.md When the detector is configured with custom `deniedPaths`, these paths are included in the tokens returned by `getTokens()`. This example shows `"/etc/passwd"` and `"/proc/self/environ"` being included. ```javascript getTokens() SHALL include "/etc/passwd" and "/proc/self/environ" ``` -------------------------------- ### First Batch Scenario: Minimum Size Source: https://github.com/mjkoo/vitiate/blob/main/openspec/specs/fuzz-loop/spec.md Specifies that the first batch uses the minimum batch size when no prior throughput history is available. ```text WHEN the fuzz loop has no throughput history THEN the first batch uses a batch size of 16 ``` -------------------------------- ### beginStage Source: https://github.com/mjkoo/vitiate/blob/main/openspec/specs/fuzzing-engine/spec.md Initiates a mutational stage for the most recently calibrated corpus entry. The stage type is determined by dispatch logic. Returns a Buffer containing the mutated input if preconditions are met, otherwise returns null. ```APIDOC ## beginStage ### Description Initiates a mutational stage for the most recently calibrated corpus entry. The stage type is determined by dispatch logic: Colorization, REDQUEEN, I2S, Generalization, Grimoire, or Unicode. Returns a Buffer containing the first stage-mutated input if preconditions are met, otherwise returns null. ### Method NAPI ### Parameters None ### Response - **Buffer | null**: A Buffer containing the mutated input, or null if preconditions are not met. ### Request Example ```javascript // JavaScript example assuming NAPI binding const result = fuzzer.beginStage(); ``` ### Response Example ```json // If successful, returns a Buffer (represented as a string for example) "" // If preconditions not met, returns null null ``` ``` -------------------------------- ### Preserving Relational Comparison Semantics Source: https://github.com/mjkoo/vitiate/blob/main/openspec/specs/comparison-tracing/spec.md Ensures that instrumented relational comparisons (e.g., less-than) yield the correct boolean result. This example shows that when `a` is less than `b`, the instrumented expression evaluates to true. ```javascript a < b ``` -------------------------------- ### Preserving Strict Equality Semantics Source: https://github.com/mjkoo/vitiate/blob/main/openspec/specs/comparison-tracing/spec.md Verifies that instrumented strict equality comparisons maintain their original boolean outcome. This example shows that when operands are equal, the instrumented expression correctly evaluates to true. ```javascript a === b ```