Commit Graph
63 Commits
Author SHA1 Message Date
Joseph Magly 8e82e1c2ba Merge branch 'pr-74' into pr-delivery-74-94-18-39-41 2026-07-16 00:49:26 -04:00
Fred BlaiseandFred Blaise 26fe8495b9 feat: allow origin-scoped target headers from env (#65)
Enable authenticated scans across the HTTP arsenal while binding configured credentials to an exact target origin.

Includes case-insensitive per-request overrides, cross-origin redirect containment, protected curl configuration, result redaction, documentation, and regression coverage.

Co-authored-by: Fred Blaise <fred.blaise@protonmail.com>
2026-07-15 23:07:08 -04:00
Joseph MaglyandPazificateur69 cf0090adf4 feat(arsenal): add source and supply-chain parsers (#97)
Follow-up to the JSON-scanner parser layer: wire semgrep, gitleaks, trivy and
grype into parseToolOutput so their findings become structured, gate-verifiable
evidence instead of raw text (they were parserStatus:'planned').

- semgrep  (scan --json)          → one finding per rule match; ERROR/WARNING/INFO
                                     mapped to severity; CWE token pulled from
                                     metadata (e.g. "CWE-78: …" → CWE-78); refs → remediation.
- trivy    (fs --format json)     → one finding per package vuln; CVE + CweIDs +
                                     "upgrade <pkg> to <fixed>" remediation.
- grype    (dir:. -o json)        → one finding per match; CVE + package coordinates.
- gitleaks (detect --report json --redact) → one high finding per secret. Defence in
                                     depth: the details are run through redactString()
                                     so a raw secret can NEVER reach a finding / the vault,
                                     even though the adapter already passes --redact.

Broadens the severity map to cover scanner vocabularies (ERROR/WARNING, CRITICAL…
NEGLIGIBLE, moderate) onto the five canonical levels. Flips parserStatus to
'structured' for the four tools. Extends parsers.test.ts + fixtures: field mapping,
the gitleaks redaction guarantee, and the end-to-end gate pass for every new scanner.

Stacked on the parser layer (#42); pairs with the scanner-invocation fix (#40) that
gives these tools the JSON-emitting arg templates. Until #40 lands the parsers simply
degrade to [] (no JSON to parse) — no misbehaviour. Secret scanners beyond gitleaks
and SARIF-style tools remain a follow-up.

Co-authored-by: Pazificateur69 <agagliardi@guardiaschool.fr>
2026-07-15 19:45:58 -04:00
Pazificateur69 f8c283377c feat(arsenal): parse scanner JSON into structured findings (#42)
The generic adapter factory returned raw stdout only (`adapter-tools.ts` success
path), so 35 catalogued scanners with `parserStatus: 'planned'` never populated the
structured `ToolResult.findings` channel — their output was dropped on the floor and
the agent could neither verify nor chain on it. The whole downstream pipe already
exists and is honest-by-construction: the agent loop stamps `provenance:'tool'` + the
raw output, the operator materialises each finding with output-evidence, and the live
gate (`evidence/gate.ts`) marks it verified.

Add `src/arsenal/parsers.ts` — `parseToolOutput(toolId, rawStdout) → ToolFinding[]`
for the five scanners that already emit machine-readable JSON via their existing arg
templates (zero template changes): nuclei (-jsonl), httpx (-json), dalfox (--format
json), ffuf (-of json), katana (-jsonl). Parsers are pure, dependency-free, and NEVER
throw: empty/garbled/unknown input yields `[]`, never a fabricated finding (same
discipline as stub-honesty / no-phantom-tools). The factory attaches parsed findings
while ALWAYS keeping the raw stdout as `output` — the evidence of record the gate checks.

- nuclei/dalfox emit CWE, which the tool channel dropped: add optional `cwe?: string[]`
  to `ToolFinding` and thread it through the operator's finding materialisation.
- flip `parserStatus: 'planned' → 'structured'` for httpx, dalfox, katana (nuclei/ffuf
  were already structured).

Adds `src/__tests__/parsers.test.ts` + fixtures: per-scanner field mapping, the
honesty contract (empty/garbled/adversarial → [], no throw), a factory-wiring check
that a minted adapter returns findings while preserving raw stdout, and an end-to-end
assertion that every parsed finding PASSES `gateLiveFinding` with provenance='tool'.

The minted-adapter path is gated behind T3MP3ST_FULL_ARSENAL, so the benchmarked
default arsenal is untouched. Supply-chain JSON tools (semgrep/gitleaks/trivy/grype)
and secret scanners (need redaction) are a clean follow-up.
2026-07-15 19:43:51 -04:00
adrianwandCodex 089591b18f feat(scan): add live progress and recon bootstrap (#81)
* Add live scan progress view

* Make local-agent recon report real tool progress

* Feed recon bootstrap into local agent ReAct loop

* Remove stale local-agent JSON tool parser

* Label backend-seeded scan progress

---------

Co-authored-by: Codex <codex@openai.com>
2026-07-15 19:42:20 -04:00
Lyubomir Bozhinov 5b4ac700ad fix(agents): detect local CLIs via well-known install dirs (#83)
A T3MP3ST server launched from Finder, the desktop app, or any non-interactive
shell inherits launchd's minimal PATH (/usr/bin:/bin:/usr/sbin:/sbin). The
local-agent detector resolved `claude`/`codex`/`hermes` against that PATH via
execFile, so an installed, authed CLI in ~/.local/bin (Claude Code's native
installer), Homebrew, npm-global, or a version-manager shim (mise/nvm/fnm) threw
ENOENT and was reported installed:false — the Settings "Connect Local Agents"
checkboxes went dead and it read like a UI bug.

Add resolveBin(): pure-fs (no shell) resolution over PATH plus a curated set of
well-known install dirs under the real agent home (agentHome(), so a HOME
redirect can't hide them), with an executable-file access check and fail-open to
the bare name — an unresolved name yields the same ENOENT → installed:false as
before, so true-absence detection is unchanged. Route the detector and both spawn
sites (runLocalAgent, localAgentChat) through it, so a CLI detected under a
minimal PATH also actually spawns. Bound the keychain auth-probe with a 2s
timeout so a locked/headless keychain (the same non-interactive launch context)
can't hang detection.

POSIX/macOS-scoped: resolveBin short-circuits on win32 — Windows resolution
(where.exe / .cmd shims) is handled by the complementary open PR #18.

Verified on macOS: RED->GREEN unit + integration tests (resolver, detector
wiring, and both spawn sites), and manual QA driving the real Web UI under a
reproduced minimal PATH (Claude Code flips from "Not installed" to detected).

Refs #78 — fixes the macOS/POSIX variant. The original report was a Windows
Sandbox environment (PR #18's domain), so this intentionally does not auto-close
that issue.
2026-07-15 19:39:59 -04:00
Joseph Magly db2d270af5 fix(server): avoid caller cwd dotenv loading (#96) 2026-07-15 19:39:12 -04:00
Joseph Magly 51f610f3a5 fix(local-agents): support current Codex exec CLI (#95) 2026-07-15 19:09:34 -04:00
Joseph Magly 4b81bf6436 fix(local): honor server LLM for keyless missions 2026-07-15 18:13:27 -04:00
Joseph Magly 600f43b8b1 fix(local): merge system prompts for vLLM 2026-07-15 18:13:00 -04:00
Eddy 25f86b0c66 fix: reject curl destination override flags
* fix: reject curl destination override flags

* fix: block additional curl target bypass forms
2026-07-15 18:12:35 -04:00
Joseph Magly 84fcef5428 fix: clarify local LLM setup 2026-07-15 18:12:12 -04:00
エルジー🐧 64efcf6373 Update index.ts 2026-07-11 06:04:11 +07:00
エルジー🐧 788e90e0ee Update index.ts 2026-07-11 05:48:06 +07:00
エルジー🐧 971a452eac Update index.ts 2026-07-10 22:56:13 +07:00
エルジー🐧 13fe0f2e56 Update index.ts 2026-07-10 22:30:20 +07:00
pliny ae32cf5051 Merge pull request #54 from Pazificateur69/feat/arsenal-re-analysis-invocations
feat(arsenal): real invocations for the reverse-engineering / mobile / smart-contract analysis loadout
2026-07-09 08:51:34 -04:00
Joseph Magly 5e40e60f47 feat(llm): native Google Gemini provider via OpenAI-compatible endpoint
Add a first-class `gemini` provider so operators can drive missions with a
direct GEMINI_API_KEY, instead of only reaching Gemini through OpenRouter.

Gemini is wired exactly like xAI: dispatched through OpenAIAdapter against
Google's OpenAI-compatible surface. The base URL is
https://generativelanguage.googleapis.com/v1beta/openai — the `/openai`
segment is required because OpenAIAdapter posts to `${baseUrl}/chat/completions`;
without it requests hit `/v1beta/chat/completions`, which Google does not serve.

Wires the provider through the type union, adapter factory, config
(interface, defaults, model catalog, key env map, getLLMConfig, fallback
chain, redaction, .env template), and adds regression tests pinning the
`/openai` base-URL segment.
2026-07-08 11:59:18 -04:00
Pazificateur69 353ea33a23 feat(arsenal): real invocations for the reverse-engineering / mobile / smart-contract analysis loadout
The Kali+ adapter factory only carries bespoke ARG_TEMPLATES for the network
and source/supply-chain scanners. The reverse-engineering, mobile and
smart-contract analysers catalogued by the cloud/mobile/binary-RE loadouts fall
through to DEFAULT_TEMPLATE and spawn a bare `<binary> <file>` — a broken
invocation for a subcommand/flag-driven tool, and for radare2 one that drops
into an INTERACTIVE prompt and hangs the agent loop until the timeout burns out.

Add conservative, read-only ARG_TEMPLATES (mirroring each catalog commandHint)
for objdump, readelf, checksec, r2, exiftool, myth (mythril), apkleaks, slither
and mobsfscan. File-oriented tools resolve their artifact through a new
`artifactPath` helper that refuses an absent path or an inherited http(s) URL by
throwing, which the handler turns into a clean {success:false} result (never a
bare `objdump ''`). No intrusive or code-executing flag is added — risk stays
where the catalog put it, and the existing option-looking-target / scope gates
still apply.

Add an invocation-honesty guard test (sibling of the tool-count honesty test):
every mintable adapter must be either templated or explicitly filed under one
fall-through reason — POSITIONAL_TARGET_OK, OPERATOR_DRIVEN, or KNOWN_DEBT — so a
newly catalogued subcommand tool can never silently ship a broken positional
invocation, and the remaining debt (feroxbuster, osv-scanner, hashcat, apktool,
yara) is tracked in the open rather than hidden.

All offline gate checks pass (lint typecheck test doctor verify-claims
test:no-fitting test:no-self-fitting test:gate prompt:audit smoke
test:arsenal-tools arsenal:smoke).
2026-07-08 10:28:23 +02:00
Codex 23713fa177 Document local agent timeout tuning 2026-07-07 16:05:20 -04:00
Codex 75b7ca02ef Honor local agent timeout defaults 2026-07-07 16:05:20 -04:00
Codex e53c61e712 Increase local agent timeouts 2026-07-07 16:05:20 -04:00
Codex 73d888f4a1 Expose stalled local agent failures 2026-07-07 16:04:40 -04:00
Codex 49d0827650 Block phase progress without live backend 2026-07-07 16:04:40 -04:00
Codex f502bfbd42 Treat local agent API failures as unhealthy 2026-07-07 16:04:40 -04:00
Codex fb0feb0028 Report stale local agent backends 2026-07-07 16:04:40 -04:00
pliny a122c567f1 Merge pull request #46 from alameya/local-openai-compatible-wire
fix(llm): support versioned OpenAI-compatible endpoints + optional bearer for local provider
2026-07-07 12:59:36 -04:00
pliny a1d1b615c3 Merge pull request #49 from kaimi-/patch-1
Update auth detection for Hermes agent
2026-07-07 11:56:06 -04:00
pliny d2bafe97d0 Merge pull request #27 from mane/fix/redact-report-secrets
fix: redact secrets in markdown reports
2026-07-07 11:33:13 -04:00
pliny b3fcdcc7b4 Merge pull request #40 from Pazificateur69/fix/arsenal-scanner-invocation
fix(arsenal): run real scanner invocations for source/supply-chain tools
2026-07-07 11:32:49 -04:00
Sergey Belov 4a0103f9f7 Update auth detection for Hermes agent 2026-07-07 13:00:26 +03:00
yaraul 2613daef49 fix(llm): support versioned OpenAI-compatible endpoints + optional bearer for local provider
Two issues blocked OpenAI-compatible servers that aren't Ollama-on-/v1:

1. LocalAdapter.isOpenAIWire matched only a literal /v1 path, so versioned
   endpoints like Zhipu/z.ai's /api/paas/v4 silently fell through to Ollama's
   native /api/chat wire format and failed. Match any /vN instead of literally /v1.

2. The `local` provider was treated as always-keyless, so servers that require
   a bearer (Zhipu/z.ai, Together, ...) could never authenticate. Read an
   optional key from TEMPEST_LOCAL_API_KEY (ZAI_API_KEY / ZHIPUAI_API_KEY as
   aliases), wire it through getApiKey/hasApiKey so `tempest test` and the
   mission engine accept a configured local provider, and document the options
   in the env template.

The key is read from env in-memory and never persisted into the store, matching
the existing env-key hardening invariant (api-key-env-static).

Adds src/__tests__/local-openai-wire-static.test.ts pinning both fixes.
Verified end-to-end against z.ai's GLM models (glm-4.5-air / 4.6 / 5.2).
2026-07-06 19:51:18 +03:00
pliny c040afd977 Merge pull request #30 from younger-plinius/feat/cloud-mobile-binary-loadouts
feat: cloud / mobile / binary-RE offensive loadouts (arsenal + detection benchmarks)
2026-07-06 12:35:07 -04:00
pliny 2f20ee5820 Merge pull request #33 from M3NT8L-One/codex/mission-stop-completion-20260706
fix(mission): stop command loop on terminal state
2026-07-06 11:48:23 -04:00
pliny 4ccf9952c8 Merge pull request #26 from mane/fix/redact-whitebox-source-context
fix: redact secrets from whitebox source context
2026-07-06 11:35:36 -04:00
pliny 56bfd29e33 Merge pull request #25 from mane/fix/config-env-export-consistency
fix: keep API key setup and export in sync
2026-07-06 11:35:13 -04:00
Pazificateur69 8522a60fec fix(arsenal): run real scanner invocations for source/supply-chain tools
The opt-in code/supply-chain scanners (semgrep, gitleaks, trufflehog, trivy,
syft, grype, checkov) are subcommand-driven and non-networked, but had no
bespoke arg template — so adapterToCustomTool fell through to DEFAULT_TEMPLATE
and spawned `<binary> <target>`. For these that is a broken invocation:
`semgrep <host>` never runs a scan, and with no target it is `semgrep ''`.
semgrep in particular is advertised on the arsenal's headline tool list.

Add per-binary templates that mirror each tool's catalog commandHint and
operate on a filesystem PATH (default: the working dir "."):
  semgrep    → scan --config auto --json <path>
  gitleaks   → detect --source <path> --report-format json --redact --no-banner
  trufflehog → filesystem <path> --json --no-update
  trivy      → fs --format json <path>
  syft       → dir:<path> -o cyclonedx-json
  grype      → dir:<path> -o json
  checkov    → -d <path> -o json

Subcommand + output flags are hardcoded (never taken from an LLM string),
matching the conservative pattern of the existing templates. The path is the
only tunable and is sanitised by scanPath(): a leading '-' (flag injection) or
an inherited http(s) mission target is rejected in favour of ".". Option-looking
targets are still refused up front by the factory's existing guard (no spawn).

Adds table-driven tests asserting the exact argv for each scanner, the "."
default, http(s)-target rejection, and the option-looking-path refusal.
2026-07-06 10:50:43 +02:00
Tyson Rudd 58b66b1e60 fix(mission): stop command loop on terminal state 2026-07-05 21:19:59 -06:00
t3mp3st contributors 537d5345dc feat: cloud / mobile / binary-RE offensive loadouts (arsenal + detection benchmarks)
Three new category loadouts, each = arsenal + an offline-scorable benchmark, opt-in and
honestly scoped (roster marks all 🚧; pacu/frida stay catalog_only, unit-tested non-mintable):
- cloud: aws/az/gcloud + scoutsuite/cloudfox/pmapper; cloud:bench IaC-misconfig detection
- mobile: apkleaks/mobsfscan/drozer/objection/class-dump; mobile:bench static ruleset
- binary/RE: ghidra/objdump/checksec/strings/readelf/gdb; binary:bench decompiled-sink detector

Mobile/binary benches are DETECTOR REGRESSION CHECKS (rules+fixtures co-authored — a pass is a
floor, not a detection rate). No new headline numbers; verify-claims 24/24.

tsc clean; 337 tests; lint 0 errors.
2026-07-05 21:49:19 -04:00
Eddy a4ccbc6432 fix: redact secrets in markdown reports 2026-07-06 01:07:16 +02:00
Eddy 25d482efb2 fix: redact secrets from whitebox source context 2026-07-06 01:04:13 +02:00
Eddy ba1179d469 fix: keep API key setup and export in sync 2026-07-06 01:00:56 +02:00
Eddy 78cac9f8cb fix: report processed files after ingest byte cap 2026-07-06 00:56:18 +02:00
pliny a5667374bf Merge pull request #21 from stefanoamorelli/fix/code-ingest-substring-exclude
fix: stop dropping source files whose name contains an exclude fragment
2026-07-05 18:31:58 -04:00
t3mp3st contributors fe5bc2c3cb feat(xai): verified grok-4.3 option + model-list receipt
Model IDs confirmed against xAI's published list (docs.x.ai/docs/models, 2026-07-05):
grok-build-0.1 (coding, 256K) and grok-4.3 (general, 1M). Addresses PR review P2.
2026-07-05 17:31:11 -04:00
t3mp3st contributors 0cb1642543 feat(xai): Grok Build as a first-class provider (grok-build-0.1) via xAI OpenAI-compatible API 2026-07-05 17:27:41 -04:00
Stefano Amorelli 6ef4c8059e fix: match path-exclude fragments as segments, not substrings 2026-07-06 00:27:16 +03:00
t3mp3st contributors eac30e4ee3 feat(local-models): self-hosted backbone runs the Arsenal (Ollama + OpenAI-compatible) 2026-07-05 17:25:50 -04:00
pliny 1e20ce1c03 Merge pull request #19 from younger-plinius/keyless-and-readme-v1
fix(keyless): local-agent tool-calling + README readability + 2 review fixes
2026-07-05 14:48:53 -04:00
t3mp3st contributors 921ccc2fa6 fix(keyless): text-CLI tool-calling (hardened per audit) + 2 review fixes 2026-07-05 14:09:50 -04:00