jaku.sh 1.0.2 → 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 +161 -18
- package/action.yml +32 -1
- package/package.json +2 -1
- package/src/agents/ai-agent.js +47 -1
- package/src/agents/api-agent.js +9 -0
- package/src/agents/logic-agent.js +158 -90
- package/src/agents/orchestrator.js +56 -1
- package/src/agents/security-agent.js +86 -54
- package/src/cli.js +68 -6
- package/src/core/ai/ai-endpoint-detector.js +28 -4
- package/src/core/ai/prompt-injector.js +34 -0
- package/src/core/api/api-key-auditor.js +1 -1
- package/src/core/api/cors-ws-tester.js +1 -1
- package/src/core/crawler.js +22 -1
- package/src/core/llm/augmentations.js +210 -0
- package/src/core/llm/llm-client.js +184 -0
- package/src/core/llm/providers/anthropic-provider.js +46 -0
- package/src/core/llm/providers/base-provider.js +44 -0
- package/src/core/llm/providers/null-provider.js +21 -0
- package/src/core/llm/providers/openai-provider.js +47 -0
- package/src/core/logic/access-boundary-tester.js +1 -1
- package/src/core/logic/business-rule-inferrer.js +50 -1
- package/src/core/security/sqli-prober.js +312 -43
- package/src/core/security/xss-scanner.js +26 -2
- package/src/reporting/report-generator.js +96 -9
- package/src/reporting/sarif-generator.js +81 -5
- package/src/utils/config.js +196 -2
- package/src/utils/finding.js +3 -0
- package/src/utils/logger.js +33 -0
- package/src/utils/param-discovery.js +93 -0
- package/src/utils/safety.js +44 -0
- package/src/utils/version.js +30 -0
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 (
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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 `
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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
|
-
| `
|
|
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.
|
|
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 +=
|
|
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
|
+
"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",
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
],
|
|
19
19
|
"scripts": {
|
|
20
20
|
"scan": "node src/cli.js scan",
|
|
21
|
+
"postinstall": "npx playwright install chromium 2>/dev/null || echo '⚠ JAKU: Could not auto-install Chromium. Run: npx playwright install chromium'",
|
|
21
22
|
"prepublishOnly": "node src/cli.js --help"
|
|
22
23
|
},
|
|
23
24
|
"keywords": [
|
package/src/agents/ai-agent.js
CHANGED
|
@@ -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
|
-
|
|
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 {
|
package/src/agents/api-agent.js
CHANGED
|
@@ -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 {
|