mech.app

The mech.app newsletter

Agentic AI, minus the noise.

Get practical field notes on AI agents, automation, developer tools and security delivered to your inbox.

No spam. Unsubscribe anytime.

Security

Shannon's Autonomous Pentesting Pipeline: How AI Agents Turn Source Code into Exploit Chains

Shannon orchestrates static analysis, attack-path discovery, browser automation, and live exploitation in a single autonomous security workflow.

Source: github.com
Shannon's Autonomous Pentesting Pipeline: How AI Agents Turn Source Code into Exploit Chains

Shannon is an autonomous pentester that reads your web application’s source code, identifies attack vectors, and executes live exploits to prove vulnerabilities. It’s a multi-stage agent pipeline that combines static analysis, attack-path reasoning, browser automation, and command-line tooling into a single workflow. The 2.0 release (46,781 stars, trending #7 on GitHub TypeScript) exposes the orchestration plumbing that makes this work: how agents hand off state, how exploit chains are prioritized, and what happens when a browser automation step fails mid-attack.

This is not a scanner that flags potential issues. Shannon only reports vulnerabilities it can prove by executing a working exploit. That constraint shapes the entire architecture.

Pipeline Stages and Agent Handoffs

Shannon’s workflow is a directed acyclic graph with four primary stages:

  1. Source code analysis: Parse the application codebase to build a control-flow graph and identify entry points (routes, API endpoints, form handlers).
  2. Attack-path identification: Reason over the control-flow graph to find sequences of operations that could lead to exploitable states (SQL injection, XSS, authentication bypass).
  3. Exploit generation: Synthesize proof-of-concept payloads for each identified attack path.
  4. Live exploitation: Use browser automation (Playwright) and CLI tools (curl, custom scripts) to execute the exploit against the running application.

Each stage is an independent agent with a specific tool set. The source-code agent uses tree-sitter parsers and static-analysis libraries. The attack-path agent uses an LLM to reason over the control-flow graph. The exploit-generation agent templates payloads based on vulnerability type. The live-exploitation agent orchestrates Playwright and shell commands.

State flows between stages as structured JSON. The source-code agent outputs a list of entry points and data-flow paths. The attack-path agent consumes that list and outputs a ranked set of attack vectors. The exploit-generation agent consumes attack vectors and outputs payloads. The live-exploitation agent consumes payloads and outputs success/failure results.

Exploit Prioritization and Backtracking

When multiple attack vectors exist, Shannon uses a scoring function to decide which exploit to attempt first. The score combines:

  • Severity: CVSS-like rating based on vulnerability type (RCE > SQLi > XSS).
  • Confidence: How certain the static analysis is that the attack path is reachable.
  • Complexity: Number of steps required to trigger the vulnerability.

The exploit-generation agent sorts attack vectors by score and attempts them sequentially. If a high-confidence SQL injection fails (the payload doesn’t trigger an error or extract data), Shannon does not automatically retry with a different payload. It logs the failure and moves to the next attack vector.

Backtracking happens only when the live-exploitation agent encounters a non-deterministic failure (network timeout, rate limit, browser crash). In that case, Shannon retries the same exploit up to three times with exponential backoff. If all retries fail, it marks the exploit as inconclusive and continues.

There is no global planner that re-evaluates the entire attack graph after a failure. Each stage runs once, and the pipeline is linear. This keeps the orchestration simple but means Shannon can miss vulnerabilities that require adaptive probing.

Isolation Between Analysis and Exploitation

The source-code agent and the live-exploitation agent run in separate processes with no shared memory. The source-code agent reads files from disk but never makes network requests. The live-exploitation agent makes network requests and spawns browser instances but never reads source code directly.

This isolation prevents a class of bugs where a malformed source file (crafted to exploit a parser vulnerability) could trick the agent into executing unintended commands. The attack-path agent, which uses an LLM to reason over the control-flow graph, runs in a sandboxed environment with no file-system or network access. It can only read the JSON output from the source-code agent and write JSON output for the exploit-generation agent.

The exploit-generation agent has limited file-system access (read-only access to a payload template directory). The live-exploitation agent has full network access but runs inside a Docker container with resource limits (CPU, memory, network bandwidth).

Observability and Debugging

Shannon outputs structured logs at each stage. Every agent emits:

  • Input snapshot: The JSON it received from the previous stage.
  • Decision trace: Why it chose a particular attack vector or payload.
  • Tool calls: Every external command (Playwright action, curl invocation) with arguments and return codes.
  • Output snapshot: The JSON it passes to the next stage.

Logs are written to stdout in JSON Lines format. You can pipe them to jq for filtering or send them to a log aggregator.

Shannon also generates a SARIF report (Static Analysis Results Interchange Format) that maps each successful exploit back to the source-code location where the vulnerability exists. The SARIF file includes:

  • File path and line number.
  • Vulnerability type (CWE identifier).
  • Proof-of-concept payload.
  • HTTP request/response pair showing the exploit in action.

If an exploit fails, the SARIF report includes a suppressions section explaining why Shannon couldn’t prove the vulnerability (e.g., “Payload blocked by WAF” or “Endpoint returned 404”).

State Management Between Phases

Shannon does not use a message queue or database to pass state between agents. Each agent writes its output to a temporary JSON file, and the next agent reads that file. The orchestrator (a TypeScript script) manages file paths and ensures agents run in the correct order.

This approach is simple but has limitations:

  • No parallelism: Agents run sequentially. You can’t analyze multiple attack vectors in parallel.
  • No incremental updates: If the exploit-generation agent crashes, you lose all progress and must re-run the entire pipeline.
  • Large intermediate files: For a complex application with hundreds of entry points, the JSON file from the source-code agent can be several megabytes.

Shannon 2.0 added a --resume flag that lets you restart the pipeline from a specific stage by pointing it to an existing intermediate file. This helps during development but doesn’t solve the parallelism problem.

Failure Modes and Error Handling

Shannon’s most common failure mode is browser automation timing out. Playwright waits up to 30 seconds for a page to load or an element to appear. If the target application is slow or the network is flaky, the exploit fails.

Shannon does not distinguish between “exploit failed because the vulnerability doesn’t exist” and “exploit failed because the browser timed out.” Both are logged as failures. You must inspect the logs to determine the root cause.

Another failure mode is payload encoding mismatches. The exploit-generation agent templates payloads as raw strings. If the target application expects URL-encoded input but Shannon sends a raw payload, the exploit fails. Shannon does not automatically retry with different encodings.

Shannon also assumes the target application is stateless. If an exploit requires logging in first, you must manually configure session cookies or authentication headers. Shannon does not have a built-in credential manager or session-handling agent.

Deployment Shape

Shannon runs as a CLI tool. You point it at a source-code directory and a running application URL:

shannon scan \
  --source ./my-app \
  --target http://localhost:3000 \
  --output report.sarif

The orchestrator spawns Docker containers for each agent. The source-code agent runs in a container with tree-sitter and language-specific parsers. The live-exploitation agent runs in a container with Playwright and curl.

You can run Shannon in CI/CD by adding it as a step in your pipeline:

- name: Run Shannon
  run: |
    docker run --rm \
      -v $(pwd):/workspace \
      keygraph/shannon:latest scan \
        --source /workspace \
        --target ${{ secrets.STAGING_URL }} \
        --output /workspace/shannon.sarif

Shannon does not have a web UI or dashboard. It’s a batch process that outputs a SARIF file. You can upload the SARIF file to GitHub Code Scanning or another SARIF-compatible platform.

Security Boundaries and Blast Radius

Shannon executes real exploits against a live application. If you point it at a production URL, it will attempt SQL injections, XSS attacks, and authentication bypasses. The README warns against this, but there is no technical safeguard.

Shannon does not rate-limit its requests. If it identifies 50 SQL injection vectors, it will fire 50 exploit attempts as fast as the target application can respond. This can trigger rate limiters, WAFs, or DDoS protection.

The live-exploitation agent runs inside a Docker container, but the container has network access to the target URL. If the target application is on the same network as other internal services, Shannon could inadvertently probe those services if the application has SSRF vulnerabilities.

Shannon does not have a “dry run” mode that simulates exploits without executing them. The only way to see what Shannon would do is to run it and inspect the logs.

Trade-offs and Design Choices

AspectShannon’s ChoiceAlternativeTrade-off
State managementTemporary JSON filesMessage queue (RabbitMQ, Redis)Simple but no parallelism or fault tolerance
Agent isolationSeparate Docker containersSingle process with sandboxed modulesStrong isolation but higher resource overhead
Exploit prioritizationStatic scoring functionAdaptive planner that re-evaluates after each failurePredictable but misses vulnerabilities requiring adaptive probing
ObservabilityJSON Lines logs + SARIFDistributed tracing (OpenTelemetry)Easy to parse but no built-in visualization
DeploymentCLI toolWeb service with APIFits CI/CD but no multi-user support

When to Use Shannon

Shannon is useful when:

  • You want proof-of-concept exploits, not just vulnerability flags.
  • You can run it against a staging environment or local instance.
  • You need SARIF output for integration with GitHub Code Scanning or similar tools.
  • You’re comfortable debugging agent failures by reading JSON logs.

Avoid Shannon when:

  • You need to scan production applications (no safety guardrails).
  • You require parallel exploit execution (sequential pipeline only).
  • You need adaptive exploit generation (no backtracking or re-planning).
  • You want a web UI or dashboard (CLI only).

Technical Verdict

Shannon is a rare open-source example of multi-stage agent orchestration in a high-stakes domain. The pipeline is linear and stateless, which keeps the orchestration simple but limits fault tolerance and parallelism. The isolation between analysis and exploitation is strong, but the lack of rate limiting and dry-run mode makes it risky to point at anything other than a local or staging environment.

The observability story is solid: structured logs and SARIF output make it easy to trace why an exploit succeeded or failed. The lack of a global planner means Shannon can miss vulnerabilities that require adaptive probing, but the static scoring function is predictable and debuggable.

If you’re building security automation for CI/CD and need proof-of-concept exploits, Shannon’s architecture is a good reference. If you need adaptive exploit generation or multi-user support, you’ll need to extend or replace the orchestrator.