Skip to content
duriantacoPublic

About

AI powered web security testing for authorized targets

Topics

Resources

Contributing

Security policy

Stars

50 stars

Watchers

1 watching

Forks

Repository files navigation

Ravage logo

Ravage

Ravage is an evidence-first CLI for assessing a running web application that you own or are explicitly authorized to test. It combines deterministic reconnaissance and validation with an optional model-driven attack loop, while keeping scope, authentication, traffic accounting, and evidence in code-owned boundaries.

Ravage running an authorized local XBEN benchmark
Illustrative local XBEN run; paths and lifecycle options vary by preset.

Ravage is a pre-1.0 research alpha. Use disposable environments and a written rules of engagement. Security testing can change application state; Ravage does not remediate findings or deploy fixes.

Quickstart · Live demo · Authentication · Results · Capabilities · Documentation

Requirements

  • Python 3.12
  • Git
  • macOS, Linux, or WSL
  • Docker for process-capable model-driven attacks, containerized tools, XBEN, and integration tests
  • A provider API key only for model-driven commands

The normal first scan needs no model key, browser, Docker daemon, or external scanner.

Install from source

git clone https://github.com/duriantaco/ravage.git
cd ravage
scripts/bootstrap.sh
source .venv/bin/activate
ravage doctor

The bootstrap creates .venv and installs the workspace. Use scripts/bootstrap.sh --dev for development dependencies, --browser for browser support, or --install-browser to install Chromium as well.

Five-minute local quickstart

Start your application first. This example assumes it is listening on http://127.0.0.1:3000.

  1. Create a scoped engagement brief and private environment file:

    ravage init http://127.0.0.1:3000 \
      --brief ravage-brief.yaml \
      --env-file .env.ravage \
      --description "Authorized assessment of my local development app."
  2. Review ravage-brief.yaml. Check the target, in-scope routes, exclusions, request budget, rate limit, objectives, and success criteria.

  3. Run a no-model surface scan:

    ravage doctor --workflow scan --brief ravage-brief.yaml
    ravage scan ravage-brief.yaml --probe surface_map --report

The command prints the run directory. Copy that path and use it as RUN_DIR in the inspection commands below.

Run the model-driven agent

Add a supported provider key, such as OPENAI_API_KEY, to .env.ravage. Ravage reads this file directly; do not shell-source it.

ravage doctor --workflow attack --brief ravage-brief.yaml
ravage attack ravage-brief.yaml --allow-paid-models --report

For an application checkout you are authorized to test, opt into source-guided validation with a local Python source directory:

ravage attack ravage-brief.yaml \
  --source-root /path/to/application \
  --allow-paid-models \
  --report

This mode maps bounded Flask and FastAPI route-to-sink flows locally, adds only structural metadata to the attack surface, and automatically validates only statically bound, non-mutating GET/query SQL-injection hypotheses whose complete scalar query shape is known. POST, body, form, path, dynamic, and relatively bound candidates remain prioritization hints. Traversal is capped by files, bytes, directories, and directory entries; included source that exceeds a cap fails closed. Hidden, temporary, version-control, virtual-environment, dependency, cache, and build directories are excluded and reported. These exclusions and static matches are not live proof: Ravage still requires differential runtime evidence. The private source map contains structural identifiers such as route and input names, relative file paths, and line numbers; a bounded subset is sent to the configured model. Source snippets, function bodies, unrelated constant values, and absolute source paths are not stored or sent. Dynamic routes, unsupported route or direct-flow patterns, skipped symlinks, and files that cannot be parsed can reduce coverage; the run records that coverage as incomplete instead of claiming a clean result. Here, analysis_complete means every included file parsed and every recognized bounded pattern was handled. It is not a claim of whole-program coverage. Resume requires the same source snapshot, analyzer contract, and candidate map.

For read-only review across UTF-8 source, configuration, and documentation files, use the separate repository-review agent:

ravage review /path/to/application

It can autonomously list files and omissions, search text, and request bounded excerpts from one frozen snapshot. It has no target, shell, browser, probe, or project-execution tools. Results are model-authored source-review candidates with references generated from exact captured excerpts. The JSON keeps paths, lines, excerpt and file digests, and the snapshot identity; it does not persist the raw snapshot. The default model profile is local; selecting a hosted profile requires --allow-paid-models and sends requested source context to that provider. See Offline Repository Context.

--allow-paid-models is an explicit acknowledgement that the run can incur provider charges. Model selection, local providers, and reproducible profiles are documented in Model providers.

Unauthenticated process-capable attacks use Docker by default. Ravage never silently falls back to host execution. The explicit --tool-runtime host option runs model-selected shell and Python on your machine; use it only in a disposable localhost environment. Child processes receive a minimal environment without provider keys, but explicit host execution can still read files available to your user account.

Hosted models receive the engagement brief, selected discovered state, prior findings, and tool observations that may include target response data. That information leaves your machine and is handled under the provider's terms and retention controls. Do not use a hosted route for sensitive customer or production data unless the engagement permits that disclosure. Use a local model route when target evidence must remain local.

Live demos

Local XBEN

For a short live demo, set XBEN_ROOT to the benchmarks directory in an XBEN checkout, start Docker, and export OPENAI_API_KEY. Then run:

ravage demo xben

Ravage builds a fresh local XBEN-009 target, attacks it with the pinned GPT-5.4 high profile, scores the result, saves the evidence under runs/demo, and removes the target and its local image. The preset limits the run to ten model requests, ten turns, ten minutes, and $1.50.

Authorized TestFire website

For a live domain-name demo, Ravage can assess HCL AppScan's deliberately vulnerable TestFire banking site. HCL publishes demo.testfire.net as a dynamic scanning sample. Review that authorization, export OPENAI_API_KEY, and explicitly acknowledge the remote target:

ravage demo testfire --authorized-remote-target

This command cannot accept another hostname. It permits only the curated login routes, GET/HEAD plus the login POST, and a code-owned set of harmless login values; stacked, destructive, and time-delay payloads are rejected before dispatch. It also disables process, scanner, recovery, and autonomous lanes, caps the whole run at 24 physical requests and 0.5 RPS, and stops after one non-destructive, evidence-backed finding. The target is a shared public demo and may occasionally be unavailable or reset by its operator.

Authenticated testing

Add a dedicated test identity to the brief:

ravage auth add ravage-brief.yaml \
  --identity user \
  --type form \
  --login /login \
  --health /account \
  --marker Logout \
  --env-file .env.ravage

Fill in the generated secret references, verify the session, then attack with the selected identity:

ravage auth check ravage-brief.yaml --identity user
ravage attack ravage-brief.yaml \
  --identity user \
  --allow-paid-models \
  --report

Form login, bearer tokens, and fixed static headers are supported. Managed credentials stay inside the authenticated HTTP owner; process, Python, and command lanes are blocked when an identity is selected. See Authentication for setup and limitations.

With at least two configured identities, first map which read-only routes each role can see:

ravage auth map ravage-brief.yaml \
  --identity alice \
  --identity bob \
  --include-anonymous

The map follows a small, deterministic GET-only frontier across every selected identity. It records conservatively shaped routes and parameter names, not exact URLs, response bodies, or query values. Recognized IDs and ambiguous path segments become placeholders. A difference is only a review candidate; it is not a vulnerability claim.

Confirm a reviewed, operator-supplied resource with the authorization matrix:

ravage auth matrix ravage-brief.yaml authorization-matrix.yaml

The plan names each explicit GET URL, its allowed and denied actors (including anonymous), and a secret-backed response marker. Ravage does not discover or guess resource IDs. See the authentication guide for map safety limits, the matrix plan format, receipt boundaries, and limitations.

Authorized remote targets

Remote execution is fail-closed and requires an explicit flag. Start with a low-impact surface scan:

ravage init https://staging.example.test \
  --brief ravage-brief.yaml \
  --env-file .env.ravage \
  --description "Authorized assessment of my staging application."

ravage doctor --workflow scan \
  --brief ravage-brief.yaml \
  --authorized-remote-target

ravage scan ravage-brief.yaml \
  --probe surface_map \
  --authorized-remote-target \
  --report

For a model-driven remote run:

ravage attack ravage-brief.yaml \
  --authorized-remote-target \
  --allow-paid-models \
  --report

Authorized remote attacks default to the whole-run low-noise policy: native metered HTTP only, sub-1-RPS pacing, a physical-request ceiling, conservative GET/HEAD caching and deduplication, adaptive backoff, bounded retries, and circuit breaking. The durable ledger survives resume. Details are in Architecture.

Understand the results

Ravage distinguishes observations, candidate findings, and confirmed vulnerabilities. A CTF flag is one possible proof, not a requirement. On an ordinary application, a run can be useful and successful without finding any flag; confirmed vulnerabilities are still written to the report.

Once an attack run starts, its canonical private machine-readable artifact is RUN_DIR/report.json, including incomplete runs. --report also writes RUN_DIR/report.md.

ravage observe RUN_DIR
ravage audit verify RUN_DIR
ravage report RUN_DIR --brief ravage-brief.yaml

For structured HTTP captured by the agent graph:

ravage traffic list RUN_DIR
ravage traffic show RUN_DIR REQUEST_ID

The report includes evidence references, request-accounting quality, completion status, and the reason an incomplete run stopped. Missing or unreadable expected evidence makes the report incomplete; an empty incomplete report has Unknown risk. Never treat an unvalidated model assertion as a confirmed finding.

ravage observe prints a private, temporary access link. The observer requires authenticated requests for run data and actions and binds to loopback by default.

Capabilities

Capability Entry point Notes
Deterministic recon and probes ravage scan No model required
Model-driven assessment ravage attack Evidence-gated and scoped
Source-guided validation ravage attack --source-root Local Flask/FastAPI mapping; live proof required
Read-only repository review ravage review Frozen multi-language text context; source-backed candidates
Managed authentication ravage auth Sessions, role-aware map, authorization matrix
Traffic inspection and replay ravage traffic Scoped artifacts
Knowledge skills ravage skills, ravage code-bug Advisory
Passive SATCOM inspection ravage satcom inspect No transmit
Curated live demos ravage demo xben, ravage demo testfire Local XBEN or scope-locked HCL TestFire target
XBEN evaluation ravage xben Docker-based research harness
Improvement Lab scripts/improvement_lab.py Isolated archive

Knowledge skills can guide prioritization, but cannot add tools, expand scope, or confirm findings. Start with:

ravage skills list builtin
ravage skills validate builtin

The Improvement Lab ingests sanitized prior-run structure, evaluates candidate patches in independent workspaces, archives accepted and rejected versions, and requires matched no-regression evidence before promotion. Promotable receipts must trace back to separately signed, archived execution evidence. It is a sidecar: it does not mutate the source checkout or silently promote itself.

Passive orbital and packet artifacts can be inspected separately:

ravage satcom inspect orbit.tle --format tle --output orbit-report.json
ravage satcom inspect capture.bin \
  --format ccsds-space-packets \
  --direction auto \
  --output packet-report.json

SATCOM support is passive parsing and analysis, not a radio transmitter or spacecraft-control system.

Development

scripts/bootstrap.sh --dev
source .venv/bin/activate
python -m pytest -m "not integration" -q
python -m ruff check --select E9,F .
python scripts/qa/check_docs.py
python scripts/qa/check_release.py

Docker-backed integration tests and frozen XBEN comparisons are separate release gates. Read Benchmarking before interpreting case results; one lucky flag is not evidence of a reliable improvement.

Documentation

Use ravage --help and ravage COMMAND --help for the exact options in your checkout.

License

Apache License 2.0. See LICENSE, DISCLAIMER, and SECURITY.md.

About

AI powered web security testing for authorized targets

Topics

Resources

Contributing

Security policy

Stars

50 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages