Commit Graph
146 Commits
Author SHA1 Message Date
エルジー🐧 64efcf6373 Update index.ts 2026-07-11 06:04:11 +07:00
エルジー🐧 7e946ec92e Update setup-api.sh 2026-07-11 05:49:00 +07:00
エルジー🐧 788e90e0ee Update index.ts 2026-07-11 05:48:06 +07:00
エルジー🐧 e1dda33bc4 Update setup-api.sh 2026-07-10 23:06:49 +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
psighoandClaude Opus 4.8 bf50be9971 harden(local-agents): close cmd.exe prompt-injection + POSIX detect fallback
Addresses review feedback on the Windows detection PR.

1. Command injection (the important one). spawnAgent ran .cmd/.bat shims via a
   hand-rolled `spawn('cmd.exe', ['/d','/s','/c', shim, ...args])`. cmd.exe
   re-parses its tail with its own rules and ignores `\"`-escaping, so an
   adversarial prompt (claude `-p <prompt>`, codex `exec <prompt>`) containing
   `"` + `& | > %VAR%` broke out and executed — the BatBadBut / CVE-2024-1874
   class. Verified with a `x" & echo PWNED` payload: it ran.
   Fix: use Node's own safe `.cmd` handling — `spawn(shim, args, {shell:true})`.
   On Node >=18.20.2 / >=20.12.2 / >=21 (CVE-2024-27980) Node escapes each arg
   for cmd, so the whole prompt lands as ONE literal argument and cannot break
   out (verified on Node 24: the same payload arrived intact in %1). .exe/POSIX
   still spawn directly with shell:false.

2. POSIX detection regression. Detection gated on resolveBin() returning a
   value; on a bash-less/busybox image where both `command -v` and `which` are
   absent, an installed agent flipped to "not installed". Fix: on POSIX fall
   back to the bare name (`resolveBin(bin) || (isWindows ? undefined : bin)`) —
   the OS resolves PATH at exec time and the ENOENT branch still catches
   genuinely-absent binaries. Windows keeps resolveBin authoritative.

Typecheck clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 05:03:42 +05:00
psighoandClaude Opus 4.8 a836e61adb fix(local-agents): don't 500 /detect when a version-probe spawn is denied
detectOne() ran the `--version` probe via execFile INSIDE a `new Promise`
executor but only handled the async error path. execFile can throw
SYNCHRONOUSLY (e.g. `spawn EPERM` when child-process creation is restricted),
and a synchronous throw in a Promise executor REJECTS the promise. Because
detectLocalAgents() used Promise.all, one agent's spawn failure rejected the
whole batch → GET /api/agents/local/detect returned 500 → the Settings "Local
Agents" card silently rendered "0/0 installed" even though all CLIs were on PATH.

- detectOne: wrap execFile in try/catch. The binary was already found on PATH
  (resolveBin returned a path) so it IS installed; on a sync throw we resolve
  installed:true with version '?' and filesystem-based auth, never rejecting.
- detectLocalAgents: Promise.allSettled instead of Promise.all, so one agent's
  failure degrades to "not installed" for that agent only, never the batch.

Verified: /detect returns 200 with claude/codex/hermes installed+ready.
Typecheck clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 03:22:46 +05:00
psigho 6ba02ec50d fix(local-agents): Windows CLI detection + Hermes auth path
Detection reported installed npm-global agents (Claude Code, Codex) as
'binary not found on PATH' on Windows, and an authed Hermes desktop as
'NOT AUTHED'. Two root causes:

1. resolvePath() used POSIX-only 'command -v'/'which', and
   execFile/spawn('claude', ...) cannot resolve npm's .cmd shims via
   PATHEXT -> ENOENT -> installed:false. Add resolveBin() (where.exe on
   Windows, preferring .exe > .cmd > .bat) and route detection + both
   spawn call sites through the resolved path.

2. Hermes desktop on Windows stores its login under %LOCALAPPDATA%\hermes   not ~/.hermes/. Add localAppData() and check both (presence-only).

Windows .cmd shims are launched via a new spawnAgent() helper that invokes
cmd.exe with an argv ARRAY (shell:false) instead of shell:true, so the
untrusted prompt is never re-parsed by cmd.exe -> no command-injection surface.

No new deps; typecheck clean.
2026-07-10 03:22:46 +05:00
Joseph Magly df37e7c423 Address upstream issues 60 and 62 2026-07-09 11:50:16 -04:00
Joseph Magly 0b2c4f545a fix: clarify local LLM setup 2026-07-09 10:48:06 -04: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
pliny 30aa72d98c Merge pull request #58 from jmagly/fix/readme-tempest-config-command
docs(readme): fix local-LLM setup command (npx tempest config → npx tempest)
2026-07-09 08:50:54 -04:00
pliny 808ce114fc Merge pull request #57 from jmagly/fix/gemini-native-provider
feat(llm): native Google Gemini provider via OpenAI-compatible endpoint
2026-07-09 08:50:39 -04:00
Nicolas Pastorello ef5c7c3f51 fix: address Docker security and stability issues from PR review
Fixes all issues raised in PR #47 review:

1. Add .dockerignore to prevent:
   - Real .env secrets baked into image layers
   - Host node_modules (glibc) overwriting alpine (musl) → ABI mismatch
   - .git, reports/, evidence/ bloating the image

2. Fix compose host-binding:
   - Remove T3MP3ST_HOST=127.0.0.1 override (was breaking port forwarding)
   - Server now binds to 0.0.0.0 in-container (DOCKER=true from Dockerfile)
   - Host mapping stays 127.0.0.1:3333:3333 for security

3. Add critical security warning in DOCKER.md:
   - Explain exposure risk of 0.0.0.0 binding + disabled Host-header guard
   - Document safe vs unsafe deployment patterns
   - Warn against network_mode: host and -p 3333:3333 without 127.0.0.1

4. Update base image:
   - node:18-alpine → node:22-alpine (Node 18 EOL)
   - Pin by digest @sha256:16e22a550... (prevent floating tag drift)

5. Fix healthcheck in compose:
   - Was always returning success (process.exit(0))
   - Now actually tests /api/health endpoint
   - Add start_period: 40s to align with Dockerfile

6. Fix port typos in DOCKER.md:
   - 3000 → 3333 in troubleshooting examples
   - Update all example snippets to node:22-alpine with digest
2026-07-08 20:34:34 -03:00
Joseph Magly 267eefcc46 docs(readme): fix local-LLM setup command (npx tempest config → npx tempest)
The quickstart tells users to run `npx tempest config` to switch to the local
provider, but there is no `config` subcommand — the CLI exposes `interactive`
(default), `setup`, `status`, `test`, and `models`. The "Change default
provider" flow lives in the default `interactive` command, so the correct
invocation is `npx tempest`.
2026-07-08 13:19:03 -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
pliny f94ca45b1c Merge pull request #1 from 5stars217/codex/local-agent-home
[codex] Respect real home for local agent auth
2026-07-08 10:25:45 -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 d9a4c47241 Show backend failure reason in UI refusal 2026-07-07 16:04:40 -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 5a5700cb9d Merge pull request #36 from M3NT8L-One/codex/provenance-docs-20260706
docs: explain verified provenance setup
2026-07-07 11:34:25 -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
pliny e59e5debab Update README.md 2026-07-07 11:32:21 -04:00
Sergey Belov 4a0103f9f7 Update auth detection for Hermes agent 2026-07-07 13:00:26 +03:00
Nicolas Pastorello 48b27bd6f5 fix: Docker healthcheck connection refused
- Bind to 0.0.0.0 inside containers (DOCKER=true env marker)
- Healthcheck was failing because localhost resolved to IPv6 ::1
  but server was bound to IPv4 127.0.0.1
- External exposure still protected via Coolify port mapping to 127.0.0.1
2026-07-06 19:35:02 -03:00
Nicolas Pastorello aaf2b7fe60 security: bind Docker to localhost only (127.0.0.1) 2026-07-06 18:31:34 -03:00
Nicolas Pastorello a92baca134 feat: add healthcheck to Dockerfile 2026-07-06 18:06:01 -03:00
Nicolas Pastorello 3aa4023c8f feat: add Docker deployment support
- Add Dockerfile with Node.js 18 alpine build
- Add docker-compose.yml with environment configuration
- Add docs/DOCKER.md deployment guide
- Update README.md with Docker quick start section
- Server binds to 0.0.0.0:3333 for external access
- UI available at http://localhost:3333/ui/
- Volumes mounted for reports and evidence persistence
2026-07-06 17:44:20 -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
RheagalFire 26217cbe33 feat: add LiteLLM as AI gateway provider 2026-07-06 21:46:48 +05:30
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
pliny 5a4533d77d Merge pull request #24 from mane/fix/ingest-byte-limit-stats
fix: report processed files after ingest byte cap
2026-07-06 11:19:10 -04:00
Pazificateur69 ce5f5b974a test(arsenal): lock the advertised tool count to the real callable surface
The arsenal advertises "83 tools" and verify-claims defends it by counting
`id:`/`name:` source lines — a source-line count that would keep passing even
if an entry became uncallable. Add a guard that ties the number to the real
registered arrays (TOOL_ADAPTERS + BUILTIN_TOOLS + EXTERNAL_TOOLS === 83) and
pins the invariant that makes the count honest:

  an adapter is off the generic callable surface (adapterToCustomTool → null)
  IFF it is explicitly gated by execution mode (catalog_only / import_only).

So a tool can be counted-but-not-generically-callable only on purpose —
metasploit / hydra (catalog_only, reachable solely via the approval-gated
post-ex drivers) and bloodhound (import_only) — never through a silent DEFAULT
or mint slip. Also asserts isMintable agrees with actual callability, the gated
set is exactly {metasploit, hydra, bloodhound}, and every minted adapter has a
real handler and a unique name. Sibling of no-phantom-tools / stub-honesty.
2026-07-06 10:53:31 +02: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
Pazificateur69 47fc8e9f77 feat(verify-claims): gate every committed solve as oracle-backed (no phantom pass)
verify-claims credits a solve straight from the committed `verdict`
(detected / score===1). Nothing asserted that a scored solve actually
agrees with its own committed flag oracle, so a hand-edited `detected:true`
(or a merge slip / fabricated placeholder flag) would pass verification
silently. The case-insensitive oracle comparator `ciMatch` was defined but
never called — this is exactly the check it was meant for.

Add an INTEGRITY GATE that re-derives, for every scored solve across the
pinned golden + white-box XBEN sweeps and the Cybench per-run artifacts,
that it is oracle-grounded: EITHER the self-reported flag matches the
committed `expected` (ciMatch), OR the harness auto-detected `expected`
verbatim in tool output (auto_detected, reported may be "UNKNOWN").
Anything scored that is neither is a phantom pass and fails the build.
Also rejects a fabricated placeholder credited via the self-report path,
and reports how much of the Cybench headline is backed by an oracle-bearing
per-run artifact vs. counted only in the hand-editable aggregate.

Adds src/__tests__/oracle-consistency.test.ts in the same spirit as
no-phantom-tools / stub-honesty: audits the committed artifacts AND proves
the gate has teeth against synthetic tampered/fabricated verdicts.

Current receipts pass clean: 0 phantom / 606 scored solves, 0 fabricated.
2026-07-06 10:42:46 +02:00
Tyson Rudd 24d0c3ad5b docs: explain verified provenance setup 2026-07-05 21:23:03 -06:00
Tyson Rudd 58b66b1e60 fix(mission): stop command loop on terminal state 2026-07-05 21:19:59 -06:00