jaku.sh 1.0.3 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -14,9 +14,13 @@ JAKU crawls your entire app, generates test cases, probes for security vulnerabi
14
14
  - [Architecture](#architecture)
15
15
  - [Module 01 — QA & Functional Testing](#module-01--qa--functional-testing)
16
16
  - [Module 02 — Security Vulnerability Scanning](#module-02--security-vulnerability-scanning)
17
+ - [Module 03 — Business Logic Validation](#module-03--business-logic-validation)
17
18
  - [Module 04 — Prompt Injection & AI Abuse Detection](#module-04--prompt-injection--ai-abuse-detection)
19
+ - [Module 05 — API & Auth Flow Verification](#module-05--api--auth-flow-verification)
18
20
  - [Correlation Engine](#correlation-engine)
19
21
  - [CLI Reference](#cli-reference)
22
+ - [Safety Modes](#safety-modes)
23
+ - [LLM Augmentation (optional)](#llm-augmentation-optional)
20
24
  - [Reports](#reports)
21
25
  - [Severity Framework](#severity-framework)
22
26
  - [Configuration](#configuration)
@@ -78,7 +82,7 @@ JAKU is a **multi-agent system** — a central Orchestrator coordinates 6 specia
78
82
  |-------|------|-------------|---------|
79
83
  | **JAKU-CRAWL** | Surface discovery | — | Wave 1 (solo) |
80
84
  | **JAKU-QA** | QA & functional testing (5 sub-modules) | JAKU-CRAWL | Wave 2 (parallel) |
81
- | **JAKU-SEC** | Security vulnerability scanning (8 sub-modules) | JAKU-CRAWL | Wave 2 (parallel) |
85
+ | **JAKU-SEC** | Security vulnerability scanning (15 sub-modules) | JAKU-CRAWL | Wave 2 (parallel) |
82
86
  | **JAKU-AI** | Prompt injection & AI abuse (8 sub-modules) | JAKU-CRAWL | Wave 2 (parallel) |
83
87
  | **JAKU-LOGIC** | Business logic validation (6 sub-modules) | JAKU-CRAWL | Wave 2 (parallel) |
84
88
  | **JAKU-API** | API & auth flow verification (5 sub-modules) | JAKU-CRAWL | Wave 2 (parallel) |
@@ -213,19 +217,34 @@ node src/cli.js qa https://your-app.dev --verbose
213
217
 
214
218
  ## Module 02 — Security Vulnerability Scanning
215
219
 
216
- Probes your app's attack surface with safe, non-destructive payloads.
220
+ Probes your app's attack surface. Under the default `--safe-active` mode these
221
+ checks use detection-only payloads and do not issue state-changing requests
222
+ (see [Safety Modes](#safety-modes)).
217
223
 
218
224
  | Sub-Module | What It Does |
219
225
  |-----------|-------------|
220
226
  | **Header Analyzer** | Checks CSP, HSTS, X-Frame-Options, X-Content-Type-Options, CORS, Referrer-Policy, Permissions-Policy, and technology fingerprinting |
221
227
  | **Secret Detector** | Scans page source, JS, and inline scripts for 19 secret patterns (AWS, Google, Stripe, GitHub, Slack, Firebase, JWT, DB URLs, private keys). Probes 21 sensitive paths (`.env`, `.git/config`, `/debug`, `/actuator`). Checks for source map exposure |
222
- | **XSS Scanner** | Tests URL parameters and form inputs for reflected and stored XSS using 9 detection-only payloads |
223
- | **SQLi Prober** | Tests URL params, form inputs, and API endpoints with 8 SQL and 3 NoSQL payloads. Detects 18 database error signatures |
228
+ | **XSS Scanner** | Tests URL parameters and form inputs for reflected and stored XSS using 9 detection-only payloads (parameters are discovered from forms/links/APIs, with a fallback name list) |
229
+ | **SQLi Prober** | Tests URL params, form inputs, and API endpoints with SQL and NoSQL payloads. Detects 18 database error signatures plus boolean-based and time-based blind injection |
224
230
  | **Dependency Auditor** | Runs `npm audit`, maps CVE advisories to JAKU severity, checks for unpinned dependencies and risky npm scripts |
225
231
  | **TLS Checker** | Validates certificate expiry, detects self-signed certs, checks HTTP→HTTPS redirect, and scans for mixed content |
226
232
  | **Infrastructure Scanner** | Probes 40 admin/debug endpoints, detects directory listing, checks error pages for information disclosure, and tests GraphQL introspection |
227
-
228
- > **Safety:** All security testing uses simulation-only payloads. No destructive operations are ever executed.
233
+ | **File Upload Tester** | Tests upload endpoints for MIME spoofing, dangerous extensions, and path traversal *(active — `safe-active`+)* |
234
+ | **CSRF Detector** | Checks state-changing forms/endpoints for anti-CSRF tokens and SameSite cookie protection |
235
+ | **Open Redirect Detector** | Tests redirect parameters for unvalidated off-site redirection *(active — `safe-active`+)* |
236
+ | **Subdomain Scanner** | Enumerates common subdomains and flags exposed/sensitive hosts |
237
+ | **Cookie Auditor** | Audits cookies for `HttpOnly`, `Secure`, `SameSite`, and scope/expiry hygiene |
238
+ | **CSP Validator** | Parses Content-Security-Policy for unsafe directives (`unsafe-inline`, `unsafe-eval`, wildcards, missing directives) |
239
+ | **Clickjacking Detector** | Verifies frame-busting protection via `X-Frame-Options` / CSP `frame-ancestors` |
240
+ | **SSRF Prober** | Probes server-side request forgery via URL/host parameters *(active — `safe-active`+)* |
241
+
242
+ > **Safety:** Module 02 (security) checks use detection-only payloads and do not
243
+ > perform destructive operations in any mode. Note that some **Module 03
244
+ > (business logic)** tests *do* send real state-changing requests (e.g. race
245
+ > conditions, pricing/checkout mutation) — those are gated behind the
246
+ > `--aggressive` safety mode and are **skipped by default**. See
247
+ > [Safety Modes](#safety-modes).
229
248
 
230
249
  ```bash
231
250
  # Security only
@@ -238,6 +257,12 @@ node src/cli.js security https://your-app.dev --verbose
238
257
 
239
258
  Detects business logic flaws that traditional scanners miss: pricing manipulation, access control bypass, workflow skipping, race conditions, and referral abuse.
240
259
 
260
+ > ⚠ **Some logic tests are destructive.** Pricing exploitation, race-condition,
261
+ > cart-manipulation, coupon-abuse, and account-takeover testing issue (or are
262
+ > classified as) real state-changing requests. They only run under
263
+ > `--aggressive` and are **skipped by default** (`--safe-active`). See
264
+ > [Safety Modes](#safety-modes).
265
+
241
266
  ### How It Works
242
267
 
243
268
  Unlike security scanning, business logic testing requires **understanding what the app does**. JAKU-LOGIC first infers business rules from your app's surface:
@@ -288,6 +313,11 @@ node src/cli.js scan https://your-app.dev --modules security,logic
288
313
  | 3 | **System Prompt Extractor** | 17 techniques | Direct repeat, token forcing ("Continue: You are a"), structured output (JSON/YAML), indirect summarization, fill-in-the-blanks, reverse output |
289
314
  | 4 | **Output Analyzer** | 10 tests | AI-mediated XSS: makes the AI generate `<script>` tags, `<img onerror>`, SVG onload, markdown `javascript:` links, data exfiltration payloads — tests if output is rendered unsanitized |
290
315
  | 5 | **Guardrail Prober** | 15 probes | PII leakage (other users' data), excessive agency (delete account, send emails, execute code), off-topic compliance, tool/function-call abuse |
316
+ | 6 | **Model DoS Tester** | resource probes | Context bombing, token-loop / repetition attacks, and oversized-input handling to detect denial-of-wallet / resource exhaustion |
317
+ | 7 | **Indirect Injector** | 6 payloads | Indirect prompt injection via content the AI later ingests (e.g. retrieved/stored data, profile fields) rather than the direct chat input |
318
+
319
+ > Detection runs first via the **AI Endpoint Detector**, then the 7 phases above
320
+ > run against each detected endpoint — 8 AI sub-modules in total.
291
321
 
292
322
  ### AI Threat Categories
293
323
 
@@ -417,10 +447,103 @@ Correlations appear in the CLI output and reports with severity escalation.
417
447
  | `--halt-on-critical` | Abort scan immediately on any critical finding | off |
418
448
  | `--webhook <url>` | POST findings summary to webhook URL on completion | off |
419
449
  | `--prod-safe` | Confirm authorization to scan production targets | off |
450
+ | `--passive` | Safety mode: recon + static analysis only (no attack probing) | — |
451
+ | `--safe-active` | Safety mode: non-destructive active probing | **default** |
452
+ | `--aggressive` | Safety mode: enable destructive/state-changing tests | — |
453
+ | `--llm` | Enable optional LLM augmentation (key from env) | off |
454
+ | `--llm-provider <name>` | LLM provider: `openai` or `anthropic` | `openai` |
455
+ | `--llm-model <id>` | LLM model id | provider default |
456
+ | `--llm-consent` | Consent to send minimal finding/target data to the provider | off |
420
457
  | `--json` | Output JSON report | off |
421
458
  | `--html` | Output HTML report | off |
422
459
  | `-v, --verbose` | Enable verbose logging | off |
423
460
 
461
+ ### Safety Modes
462
+
463
+ JAKU exposes three explicit safety tiers so you control how invasive a scan is.
464
+ The default is `--safe-active`. You can also set `"safety_mode"` in
465
+ `jaku.config.json`; the CLI flag takes precedence.
466
+
467
+ | Mode | Flag | What runs | What it never does |
468
+ |------|------|-----------|--------------------|
469
+ | **Passive** | `--passive` | Crawl/discovery + read-only/static analysis only (headers, secrets, TLS, cookies, CSP, clickjacking, static form/API analysis) | Sends no attack payloads and no state-changing requests. Active probers (XSS, SQLi, infra, SSRF, file-upload, open-redirect, AI, API/auth, and all logic tests) are skipped. |
470
+ | **Safe-Active** *(default)* | `--safe-active` | Everything in passive **plus** non-destructive active probing: XSS/SQLi probes, AI prompt-injection, API/auth verification, and non-destructive logic checks (access boundary, workflow, abuse patterns, email enumeration, feature flags) | Never issues destructive/state-changing requests. Destructive logic tests are skipped with a clear log line. |
471
+ | **Aggressive** | `--aggressive` | Everything in safe-active **plus** destructive/state-changing tests: pricing exploitation, race conditions, cart manipulation, coupon abuse, account takeover | — (use only against environments you are authorized to mutate) |
472
+
473
+ > JAKU is a security scanner and **intentionally does not honor `robots.txt`** in
474
+ > any mode. The legacy `respect_robots` / `respect_robots_txt` config key has
475
+ > been removed.
476
+
477
+ ### LLM Augmentation (optional)
478
+
479
+ JAKU can optionally use your **own** LLM API key to make scans smarter. This
480
+ feature is **off by default and strictly additive** — with no key, no `--llm`
481
+ flag, no consent, an unreachable API, or an exhausted budget, JAKU behaves
482
+ **exactly** as it does without it. The LLM **never** decides core pass/fail;
483
+ deterministic scanners always own the verdict.
484
+
485
+ **What the LLM adds (all advisory / tagged `source: "llm"`):**
486
+
487
+ | Phase | Augmentation | Where |
488
+ |-------|--------------|-------|
489
+ | 0 | Framework-specific remediation guidance + executive summary | reports |
490
+ | 1 | Context-aware prompt-injection payloads tailored to a leaked system prompt | `JAKU-AI` |
491
+ | 2 | False-positive triage of borderline findings + attack-chain narrative enrichment | synthesis + reports |
492
+ | 3 | Extra business-domain / invariant inference | `JAKU-LOGIC` |
493
+
494
+ **Enabling it:**
495
+
496
+ ```bash
497
+ # Key comes ONLY from the environment — never the config file or CLI
498
+ export OPENAI_API_KEY=sk-... # or ANTHROPIC_API_KEY=sk-ant-...
499
+
500
+ node src/cli.js scan https://myapp.dev --llm --llm-consent --llm-provider openai
501
+ ```
502
+
503
+ Both `--llm` (enablement) **and** `--llm-consent` (or `llm.consent: true`) are
504
+ required before any data leaves your machine. Configure non-secret settings in
505
+ `jaku.config.json`:
506
+
507
+ ```jsonc
508
+ "llm": {
509
+ "enabled": false, // or pass --llm
510
+ "provider": "openai", // openai | anthropic
511
+ "model": null, // null → cheap provider default
512
+ "max_tokens": 1024, // per-call output cap
513
+ "max_calls": 50, // per-scan call budget
514
+ "token_budget": 100000, // per-scan token budget
515
+ "timeout_seconds": 30,
516
+ "consent": false, // or pass --llm-consent
517
+ "base_url": null // optional self-hosted/proxy endpoint
518
+ }
519
+ ```
520
+
521
+ **What data leaves the machine (data minimization):**
522
+
523
+ - *Remediation:* finding title, module, severity, description.
524
+ - *Triage:* title, severity, description, a short evidence snippet — borderline findings only.
525
+ - *Executive summary:* severity counts + finding **titles** (no bodies/evidence).
526
+ - *Payload generation:* a snippet of the **already-leaked** system prompt + the target host.
527
+ - *Business inference:* discovered URL **paths** + form field **names** (no values, no bodies).
528
+
529
+ **Security & safety guarantees:**
530
+
531
+ - **Keys never persist or print.** The API key is read from the environment only,
532
+ is never written to config, logs, reports, `meta`, `finding.evidence`, or PR
533
+ comments. The logger scrubs `sk-…`, `Bearer …`, and `x-api-key` patterns from
534
+ all output. Putting an `api_key` in `jaku.config.json` is rejected with a warning.
535
+ - **Passive mode = no egress.** Third-party calls are auto-disabled in `--passive`.
536
+ - **Safety-tier gating.** LLM-generated **destructive** payloads only fire under
537
+ `--aggressive`; non-destructive generated probes require `--safe-active`.
538
+ - **Budgeted & resilient.** Per-scan call/token budgets, per-call timeout,
539
+ 429 backoff, and a connection-failure circuit breaker — any failure degrades
540
+ silently to deterministic behavior.
541
+ - **No new dependencies.** Uses the built-in `fetch` only.
542
+
543
+ To disable, simply omit `--llm` (or set `"enabled": false`). In CI, set
544
+ `enable-llm: 'true'` on the action and provide `OPENAI_API_KEY` /
545
+ `ANTHROPIC_API_KEY` from repository secrets in the job environment.
546
+
424
547
  ### Report Formats
425
548
 
426
549
  Every scan generates 5 report files:
@@ -467,12 +590,14 @@ node src/cli.js ai https://myapp.dev/api/chat --max-pages 1 -v
467
590
  ```
468
591
  ╦╔═╗╦╔═╦ ╦
469
592
  ║╠═╣╠╩╗║ ║ 呪 Autonomous Security & Quality Intelligence
470
- ╚╝╩ ╩╩ ╩╚═╝ v1.0.3 · Multi-Agent
593
+ ╚╝╩ ╩╩ ╩╚═╝ v1.2.0 · Multi-Agent
471
594
 
472
595
  Target: https://your-app.dev
473
596
  Modules: QA + SECURITY + AI
474
597
  Mode: Multi-Agent Orchestration
598
+ Safety: Safe-Active (non-destructive probing)
475
599
  Severity: ≥ low
600
+ LLM: disabled — not enabled (set llm.enabled or pass --llm)
476
601
 
477
602
  ✔ [JAKU-CRAWL] Complete — 0 findings in 2.1s
478
603
  ✔ [JAKU-QA] Complete — 3 findings in 14.9s ⚡parallel
@@ -505,13 +630,16 @@ node src/cli.js ai https://myapp.dev/api/chat --max-pages 1 -v
505
630
 
506
631
  ## Reports
507
632
 
508
- Every scan generates three report formats, saved to `jaku-reports/<timestamp>/`:
633
+ Every scan generates the following report formats, saved to `jaku-reports/<timestamp>/`:
509
634
 
510
635
  | Format | File | Description |
511
636
  |--------|------|-------------|
512
637
  | **JSON** | `report.json` | Machine-readable findings array for CI/CD integration |
513
638
  | **Markdown** | `report.md` | Human-readable narrative with severity tables and finding details |
514
639
  | **HTML** | `report.html` | Self-contained dark-themed report with severity charts, filters, and embedded evidence |
640
+ | **SARIF** | `report.sarif` | GitHub/GitLab Security Dashboard integration (SARIF v2.1.0) |
641
+ | **Diff** | `diff-report.md` / `diff-report.json` | Regression detection vs. the previous scan run |
642
+ | **OWASP Compliance** | `compliance-owasp.*` | OWASP Top 10 pass/fail report (JSON + MD + HTML) — only with `--compliance owasp` |
515
643
 
516
644
  ### Finding Schema
517
645
 
@@ -536,7 +664,7 @@ Every scan generates three report formats, saved to `jaku-reports/<timestamp>/`:
536
664
  }
537
665
  ```
538
666
 
539
- Modules tag findings as: `qa`, `security`, or `ai`.
667
+ Modules tag findings as: `qa`, `security`, `ai`, `logic`, or `api`.
540
668
 
541
669
  ---
542
670
 
@@ -563,33 +691,48 @@ cp jaku.config.example.json jaku.config.json
563
691
  ```json
564
692
  {
565
693
  "target_url": "https://your-app.dev",
566
- "credentials": {
567
- "username": "",
568
- "password": ""
569
- },
570
- "modules": ["qa", "security", "ai"],
694
+ "modules_enabled": ["qa", "security", "ai", "logic", "api"],
571
695
  "severity_threshold": "low",
696
+ "safety_mode": "safe-active",
572
697
  "halt_on_critical": true,
573
698
  "crawler": {
574
699
  "max_pages": 50,
575
700
  "max_depth": 5,
576
- "respect_robots": true
701
+ "concurrency": 4
702
+ },
703
+ "llm": {
704
+ "enabled": false,
705
+ "provider": "openai",
706
+ "consent": false
577
707
  }
578
708
  }
579
709
  ```
580
710
 
711
+ > The LLM API key is **never** stored in this file — it is read from the
712
+ > `OPENAI_API_KEY` / `ANTHROPIC_API_KEY` environment variable only. See
713
+ > [LLM Augmentation](#llm-augmentation-optional).
714
+
715
+ Unknown, mistyped, or deprecated keys in `jaku.config.json` are reported as
716
+ warnings on load (and ignored) rather than silently honored.
717
+
581
718
  ### Configuration Options
582
719
 
583
720
  | Key | Type | Description |
584
721
  |-----|------|-------------|
585
722
  | `target_url` | string | The application URL to scan |
586
- | `credentials` | object | Login credentials for authenticated scanning |
587
- | `modules` | string[] | Modules to enable: `qa`, `security`, `ai` |
723
+ | `credentials` | object[] | Login credentials for authenticated scanning |
724
+ | `modules_enabled` | string[] | Modules to enable: `qa`, `security`, `ai`, `logic`, `api` |
588
725
  | `severity_threshold` | string | Minimum severity to report: `critical`, `high`, `medium`, `low` |
726
+ | `safety_mode` | string | Safety tier: `passive`, `safe-active` (default), `aggressive` — see [Safety Modes](#safety-modes) |
589
727
  | `halt_on_critical` | boolean | Exit with code 1 if critical findings detected (for CI/CD) |
590
728
  | `crawler.max_pages` | number | Maximum pages to crawl |
591
729
  | `crawler.max_depth` | number | Maximum link depth to follow |
592
- | `crawler.respect_robots` | boolean | Honor robots.txt directives |
730
+ | `crawler.concurrency` | number | Parallel crawl workers |
731
+ | `llm.enabled` | boolean | Enable optional LLM augmentation (default `false`) — see [LLM Augmentation](#llm-augmentation-optional) |
732
+ | `llm.provider` | string | `openai` or `anthropic` |
733
+ | `llm.model` | string | Model id (provider default if omitted) |
734
+ | `llm.consent` | boolean | Required (with enablement) before any data egress |
735
+ | `llm.max_calls` / `llm.token_budget` | number | Per-scan call / token budgets |
593
736
 
594
737
  ### CI/CD Integration
595
738
 
package/action.yml CHANGED
@@ -49,6 +49,18 @@ inputs:
49
49
  description: 'Maximum pages to crawl'
50
50
  required: false
51
51
  default: '50'
52
+ enable-llm:
53
+ description: 'Enable optional LLM augmentation (requires OPENAI_API_KEY or ANTHROPIC_API_KEY in job env and consent)'
54
+ required: false
55
+ default: 'false'
56
+ llm-provider:
57
+ description: 'LLM provider when enabled (openai|anthropic)'
58
+ required: false
59
+ default: 'openai'
60
+ llm-model:
61
+ description: 'LLM model id (provider default if empty)'
62
+ required: false
63
+ default: ''
52
64
  verbose:
53
65
  description: 'Enable verbose logging'
54
66
  required: false
@@ -102,6 +114,14 @@ runs:
102
114
  JAKU_AUTH_STRATEGY: ${{ inputs.auth-strategy }}
103
115
  JAKU_MAX_PAGES: ${{ inputs.max-pages }}
104
116
  JAKU_VERBOSE: ${{ inputs.verbose }}
117
+ JAKU_ENABLE_LLM: ${{ inputs.enable-llm }}
118
+ JAKU_LLM_PROVIDER: ${{ inputs.llm-provider }}
119
+ JAKU_LLM_MODEL: ${{ inputs.llm-model }}
120
+ # API keys are read from the job environment (set these from repo secrets
121
+ # in your workflow, e.g. OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}).
122
+ # They are passed to the scanner process only and never printed.
123
+ OPENAI_API_KEY: ${{ env.OPENAI_API_KEY }}
124
+ ANTHROPIC_API_KEY: ${{ env.ANTHROPIC_API_KEY }}
105
125
  run: |
106
126
  REPORT_DIR="${{ runner.temp }}/jaku-reports"
107
127
 
@@ -124,6 +144,17 @@ runs:
124
144
  if [ "${JAKU_VERBOSE}" = "true" ]; then
125
145
  CMD="${CMD} --verbose"
126
146
  fi
147
+
148
+ # Optional LLM augmentation. Only enabled when explicitly requested AND a
149
+ # key is present in the environment. The key itself is never added to the
150
+ # command line — LLMClient reads it from env. --llm-consent is implied by
151
+ # the operator opting in via enable-llm in CI.
152
+ if [ "${JAKU_ENABLE_LLM}" = "true" ] && { [ -n "${OPENAI_API_KEY}" ] || [ -n "${ANTHROPIC_API_KEY}" ]; }; then
153
+ CMD="${CMD} --llm --llm-consent --llm-provider ${JAKU_LLM_PROVIDER}"
154
+ if [ -n "${JAKU_LLM_MODEL}" ]; then
155
+ CMD="${CMD} --llm-model ${JAKU_LLM_MODEL}"
156
+ fi
157
+ fi
127
158
 
128
159
  # Run scan
129
160
  eval ${CMD} || true
@@ -217,7 +248,7 @@ runs:
217
248
  }
218
249
  }
219
250
 
220
- body += '\n---\n*Scanned by [JAKU](https://github.com/jaku-security/jaku) v1.0.3*';
251
+ body += `\n---\n*Scanned by [JAKU](https://github.com/jaku-security/jaku) v${report.meta?.version || ''}*`;
221
252
  } else {
222
253
  body += '⚠️ Scan completed but no report was generated. Check workflow logs for errors.';
223
254
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jaku.sh",
3
- "version": "1.0.3",
3
+ "version": "1.2.0",
4
4
  "description": "JAKU (呪) — Autonomous Security & Quality Intelligence Agent for vibe-coded apps. XSS, SQLi, prompt injection, QA testing, and attack chain correlation in one command.",
5
5
  "type": "module",
6
6
  "main": "src/cli.js",
@@ -1,4 +1,6 @@
1
1
  import { BaseAgent } from './base-agent.js';
2
+ import { allows, getSafetyMode } from '../utils/safety.js';
3
+ import { generateInjectionPayloads } from '../core/llm/augmentations.js';
2
4
  import { AIEndpointDetector } from '../core/ai/ai-endpoint-detector.js';
3
5
  import { PromptInjector } from '../core/ai/prompt-injector.js';
4
6
  import { JailbreakTester } from '../core/ai/jailbreak-tester.js';
@@ -34,6 +36,14 @@ export class AIAgent extends BaseAgent {
34
36
  throw new Error('No surface inventory available — JAKU-CRAWL must run first');
35
37
  }
36
38
 
39
+ // AI endpoint detection and abuse testing send live requests (benign
40
+ // probes + injection payloads), so they require at least safe-active.
41
+ if (!allows(config, 'safe-active')) {
42
+ this._log(`AI abuse testing skipped — requires active probing (current: ${getSafetyMode(config)} mode)`);
43
+ this.progress('complete', 'AI testing skipped (passive mode)', 100);
44
+ return;
45
+ }
46
+
37
47
  // Phase 1: Detect AI endpoints
38
48
  this.progress('detect', 'Detecting AI-powered endpoints...', 0);
39
49
 
@@ -78,9 +88,10 @@ export class AIAgent extends BaseAgent {
78
88
 
79
89
  // Phase 4: System Prompt Extraction
80
90
  this.progress('extraction', 'Attempting system prompt extraction...', 50);
91
+ let extractionFindings = [];
81
92
  try {
82
93
  const extractor = new SystemPromptExtractor(logger);
83
- const extractionFindings = await extractor.extract(aiSurfaces, sendMessage);
94
+ extractionFindings = await extractor.extract(aiSurfaces, sendMessage);
84
95
  this.addFindings(extractionFindings);
85
96
  this._log(`System prompt extraction: ${extractionFindings.length} leaks`);
86
97
  } catch (err) {
@@ -88,6 +99,41 @@ export class AIAgent extends BaseAgent {
88
99
  }
89
100
  this.progress('extraction', 'System prompt extraction complete', 70);
90
101
 
102
+ // Phase 4.5: LLM-generated, context-aware injection payloads (optional).
103
+ // Only runs when LLM augmentation is active (egress is auto-disabled in
104
+ // passive mode). Generated DESTRUCTIVE payloads require --aggressive;
105
+ // non-destructive generated probes need safe-active (already satisfied).
106
+ const llmClient = context.llmClient;
107
+ if (llmClient?.isEnabled?.()) {
108
+ try {
109
+ // Reuse the (already-leaked) system prompt as generation context.
110
+ const leaked = extractionFindings
111
+ .map(f => {
112
+ const m = /Extracted content:\n([\s\S]*)/.exec(f.evidence || '');
113
+ return m ? m[1].trim() : '';
114
+ })
115
+ .filter(Boolean)[0] || '';
116
+
117
+ if (leaked) {
118
+ const allowDestructive = allows(config, 'aggressive');
119
+ const generated = await generateInjectionPayloads(llmClient, {
120
+ systemPrompt: leaked,
121
+ surfaceUrl: aiSurfaces[0]?.url || config.target_url,
122
+ allowDestructive,
123
+ });
124
+ if (generated?.length) {
125
+ const genFindings = await injector.injectGenerated(aiSurfaces, generated, { allowDestructive });
126
+ this.addFindings(genFindings);
127
+ this._log(`LLM-generated payloads: ${genFindings.length} findings from ${generated.length} tailored payloads`);
128
+ }
129
+ } else {
130
+ this._log('No leaked system prompt — skipping LLM payload generation');
131
+ }
132
+ } catch (err) {
133
+ this._log(`LLM payload generation failed: ${err.message}`, 'error');
134
+ }
135
+ }
136
+
91
137
  // Phase 5: Output Analysis (AI-mediated XSS)
92
138
  this.progress('output', 'Analyzing AI output sanitization...', 70);
93
139
  try {
@@ -1,4 +1,5 @@
1
1
  import { BaseAgent } from './base-agent.js';
2
+ import { allows, getSafetyMode } from '../utils/safety.js';
2
3
  import { AuthFlowTester } from '../core/api/auth-flow-tester.js';
3
4
  import { OAuthProber } from '../core/api/oauth-prober.js';
4
5
  import { APIKeyAuditor } from '../core/api/api-key-auditor.js';
@@ -28,6 +29,14 @@ export class APIAgent extends BaseAgent {
28
29
  throw new Error('No surface inventory available — JAKU-CRAWL must run first');
29
30
  }
30
31
 
32
+ // API/auth flow verification sends live requests, so it requires at
33
+ // least safe-active. In passive mode it is skipped.
34
+ if (!allows(config, 'safe-active')) {
35
+ this._log(`API & auth flow verification skipped — requires active probing (current: ${getSafetyMode(config)} mode)`);
36
+ this.progress('complete', 'API testing skipped (passive mode)', 100);
37
+ return;
38
+ }
39
+
31
40
  // Phase 1: Auth flow testing
32
41
  this.progress('auth', 'Testing authentication flows...', 0);
33
42
  try {