jaku.sh 1.0.3 → 1.2.1

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
@@ -11,12 +11,17 @@ JAKU crawls your entire app, generates test cases, probes for security vulnerabi
11
11
  ## Table of Contents
12
12
 
13
13
  - [Quick Start](#quick-start)
14
+ - [Updating](#updating)
14
15
  - [Architecture](#architecture)
15
16
  - [Module 01 — QA & Functional Testing](#module-01--qa--functional-testing)
16
17
  - [Module 02 — Security Vulnerability Scanning](#module-02--security-vulnerability-scanning)
18
+ - [Module 03 — Business Logic Validation](#module-03--business-logic-validation)
17
19
  - [Module 04 — Prompt Injection & AI Abuse Detection](#module-04--prompt-injection--ai-abuse-detection)
20
+ - [Module 05 — API & Auth Flow Verification](#module-05--api--auth-flow-verification)
18
21
  - [Correlation Engine](#correlation-engine)
19
22
  - [CLI Reference](#cli-reference)
23
+ - [Safety Modes](#safety-modes)
24
+ - [LLM Augmentation (optional)](#llm-augmentation-optional)
20
25
  - [Reports](#reports)
21
26
  - [Severity Framework](#severity-framework)
22
27
  - [Configuration](#configuration)
@@ -68,6 +73,62 @@ node src/cli.js security https://your-app.dev --severity high
68
73
 
69
74
  ---
70
75
 
76
+ ## Updating
77
+
78
+ Already running JAKU? Update to the latest release:
79
+
80
+ ```bash
81
+ # Global install (most common)
82
+ npm install -g jaku.sh@latest
83
+ jaku --version # confirm you're on the latest
84
+
85
+ # Refresh the browser engine if the post-install step was skipped
86
+ npx playwright install chromium
87
+ ```
88
+
89
+ ```bash
90
+ # npx users — pin @latest so a stale cached copy isn't reused
91
+ npx jaku.sh@latest scan https://your-app.dev --prod-safe
92
+
93
+ # Project dependency
94
+ npm install -D jaku.sh@latest
95
+
96
+ # GitHub Action — pin to the release tag
97
+ # - uses: theshantanupandey/jaku@v1.2.0
98
+ ```
99
+
100
+ ### What's new in v1.2.1
101
+
102
+ - **Resilient install.** The Chromium download no longer blocks or breaks
103
+ `npm install` — it is non-fatal, interrupt-safe (a Ctrl+C won't fail the
104
+ install), and skippable with `JAKU_SKIP_BROWSER_DOWNLOAD=1`.
105
+ - **Auto browser setup on first scan.** If Chromium is missing when you run a
106
+ scan, JAKU installs it automatically (one-time) instead of erroring out.
107
+
108
+ > Updating? If a previous Chromium download was interrupted, just run a scan —
109
+ > JAKU will finish setting up the browser — or run `npx playwright install chromium`.
110
+
111
+ ### What's new in v1.2.0
112
+
113
+ > ⚠ **Behavior change for existing users:** destructive business-logic tests
114
+ > (race conditions, pricing/checkout mutation, etc.) are now **gated behind
115
+ > `--aggressive`** and **skipped by default**. A plain `jaku scan` is now safer
116
+ > than before — if you relied on those tests running by default, add
117
+ > `--aggressive`. Everything else is additive and backward-compatible.
118
+
119
+ | Area | Change |
120
+ |------|--------|
121
+ | **Safety modes** | New `--passive` / `--safe-active` (default) / `--aggressive` tiers; destructive tests gated to `--aggressive` |
122
+ | **AI testing fix** | AI endpoint detection now works on JSON/API chat endpoints (previously skipped silently) |
123
+ | **LLM augmentation** | Optional, bring-your-own-key AI assistance — remediation, exec summaries, tailored payloads, FP triage. Off by default, no new dependencies — see [LLM Augmentation](#llm-augmentation-optional) |
124
+ | **Deeper scanning** | Real parameter discovery for XSS/SQLi + boolean-based and time-based **blind SQLi** detection |
125
+ | **Better outputs** | Reports reflect the actual modules that ran; SARIF adds `partialFingerprints` + proper web URIs for cross-run tracking |
126
+ | **Config & safety** | Lightweight config validation with warnings; API keys rejected from config files; version centralized |
127
+
128
+ Full file-level history is on [GitHub](https://github.com/theshantanupandey/jaku/commits/main).
129
+
130
+ ---
131
+
71
132
  ## Architecture
72
133
 
73
134
  JAKU is a **multi-agent system** — a central Orchestrator coordinates 6 specialized sub-agents that run in parallel, sharing discoveries through an event-driven message bus and a unified findings ledger with attack chain correlation.
@@ -78,7 +139,7 @@ JAKU is a **multi-agent system** — a central Orchestrator coordinates 6 specia
78
139
  |-------|------|-------------|---------|
79
140
  | **JAKU-CRAWL** | Surface discovery | — | Wave 1 (solo) |
80
141
  | **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) |
142
+ | **JAKU-SEC** | Security vulnerability scanning (15 sub-modules) | JAKU-CRAWL | Wave 2 (parallel) |
82
143
  | **JAKU-AI** | Prompt injection & AI abuse (8 sub-modules) | JAKU-CRAWL | Wave 2 (parallel) |
83
144
  | **JAKU-LOGIC** | Business logic validation (6 sub-modules) | JAKU-CRAWL | Wave 2 (parallel) |
84
145
  | **JAKU-API** | API & auth flow verification (5 sub-modules) | JAKU-CRAWL | Wave 2 (parallel) |
@@ -213,19 +274,34 @@ node src/cli.js qa https://your-app.dev --verbose
213
274
 
214
275
  ## Module 02 — Security Vulnerability Scanning
215
276
 
216
- Probes your app's attack surface with safe, non-destructive payloads.
277
+ Probes your app's attack surface. Under the default `--safe-active` mode these
278
+ checks use detection-only payloads and do not issue state-changing requests
279
+ (see [Safety Modes](#safety-modes)).
217
280
 
218
281
  | Sub-Module | What It Does |
219
282
  |-----------|-------------|
220
283
  | **Header Analyzer** | Checks CSP, HSTS, X-Frame-Options, X-Content-Type-Options, CORS, Referrer-Policy, Permissions-Policy, and technology fingerprinting |
221
284
  | **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 |
285
+ | **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) |
286
+ | **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
287
  | **Dependency Auditor** | Runs `npm audit`, maps CVE advisories to JAKU severity, checks for unpinned dependencies and risky npm scripts |
225
288
  | **TLS Checker** | Validates certificate expiry, detects self-signed certs, checks HTTP→HTTPS redirect, and scans for mixed content |
226
289
  | **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.
290
+ | **File Upload Tester** | Tests upload endpoints for MIME spoofing, dangerous extensions, and path traversal *(active — `safe-active`+)* |
291
+ | **CSRF Detector** | Checks state-changing forms/endpoints for anti-CSRF tokens and SameSite cookie protection |
292
+ | **Open Redirect Detector** | Tests redirect parameters for unvalidated off-site redirection *(active — `safe-active`+)* |
293
+ | **Subdomain Scanner** | Enumerates common subdomains and flags exposed/sensitive hosts |
294
+ | **Cookie Auditor** | Audits cookies for `HttpOnly`, `Secure`, `SameSite`, and scope/expiry hygiene |
295
+ | **CSP Validator** | Parses Content-Security-Policy for unsafe directives (`unsafe-inline`, `unsafe-eval`, wildcards, missing directives) |
296
+ | **Clickjacking Detector** | Verifies frame-busting protection via `X-Frame-Options` / CSP `frame-ancestors` |
297
+ | **SSRF Prober** | Probes server-side request forgery via URL/host parameters *(active — `safe-active`+)* |
298
+
299
+ > **Safety:** Module 02 (security) checks use detection-only payloads and do not
300
+ > perform destructive operations in any mode. Note that some **Module 03
301
+ > (business logic)** tests *do* send real state-changing requests (e.g. race
302
+ > conditions, pricing/checkout mutation) — those are gated behind the
303
+ > `--aggressive` safety mode and are **skipped by default**. See
304
+ > [Safety Modes](#safety-modes).
229
305
 
230
306
  ```bash
231
307
  # Security only
@@ -238,6 +314,12 @@ node src/cli.js security https://your-app.dev --verbose
238
314
 
239
315
  Detects business logic flaws that traditional scanners miss: pricing manipulation, access control bypass, workflow skipping, race conditions, and referral abuse.
240
316
 
317
+ > ⚠ **Some logic tests are destructive.** Pricing exploitation, race-condition,
318
+ > cart-manipulation, coupon-abuse, and account-takeover testing issue (or are
319
+ > classified as) real state-changing requests. They only run under
320
+ > `--aggressive` and are **skipped by default** (`--safe-active`). See
321
+ > [Safety Modes](#safety-modes).
322
+
241
323
  ### How It Works
242
324
 
243
325
  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 +370,11 @@ node src/cli.js scan https://your-app.dev --modules security,logic
288
370
  | 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
371
  | 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
372
  | 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 |
373
+ | 6 | **Model DoS Tester** | resource probes | Context bombing, token-loop / repetition attacks, and oversized-input handling to detect denial-of-wallet / resource exhaustion |
374
+ | 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 |
375
+
376
+ > Detection runs first via the **AI Endpoint Detector**, then the 7 phases above
377
+ > run against each detected endpoint — 8 AI sub-modules in total.
291
378
 
292
379
  ### AI Threat Categories
293
380
 
@@ -417,10 +504,103 @@ Correlations appear in the CLI output and reports with severity escalation.
417
504
  | `--halt-on-critical` | Abort scan immediately on any critical finding | off |
418
505
  | `--webhook <url>` | POST findings summary to webhook URL on completion | off |
419
506
  | `--prod-safe` | Confirm authorization to scan production targets | off |
507
+ | `--passive` | Safety mode: recon + static analysis only (no attack probing) | — |
508
+ | `--safe-active` | Safety mode: non-destructive active probing | **default** |
509
+ | `--aggressive` | Safety mode: enable destructive/state-changing tests | — |
510
+ | `--llm` | Enable optional LLM augmentation (key from env) | off |
511
+ | `--llm-provider <name>` | LLM provider: `openai` or `anthropic` | `openai` |
512
+ | `--llm-model <id>` | LLM model id | provider default |
513
+ | `--llm-consent` | Consent to send minimal finding/target data to the provider | off |
420
514
  | `--json` | Output JSON report | off |
421
515
  | `--html` | Output HTML report | off |
422
516
  | `-v, --verbose` | Enable verbose logging | off |
423
517
 
518
+ ### Safety Modes
519
+
520
+ JAKU exposes three explicit safety tiers so you control how invasive a scan is.
521
+ The default is `--safe-active`. You can also set `"safety_mode"` in
522
+ `jaku.config.json`; the CLI flag takes precedence.
523
+
524
+ | Mode | Flag | What runs | What it never does |
525
+ |------|------|-----------|--------------------|
526
+ | **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. |
527
+ | **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. |
528
+ | **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) |
529
+
530
+ > JAKU is a security scanner and **intentionally does not honor `robots.txt`** in
531
+ > any mode. The legacy `respect_robots` / `respect_robots_txt` config key has
532
+ > been removed.
533
+
534
+ ### LLM Augmentation (optional)
535
+
536
+ JAKU can optionally use your **own** LLM API key to make scans smarter. This
537
+ feature is **off by default and strictly additive** — with no key, no `--llm`
538
+ flag, no consent, an unreachable API, or an exhausted budget, JAKU behaves
539
+ **exactly** as it does without it. The LLM **never** decides core pass/fail;
540
+ deterministic scanners always own the verdict.
541
+
542
+ **What the LLM adds (all advisory / tagged `source: "llm"`):**
543
+
544
+ | Phase | Augmentation | Where |
545
+ |-------|--------------|-------|
546
+ | 0 | Framework-specific remediation guidance + executive summary | reports |
547
+ | 1 | Context-aware prompt-injection payloads tailored to a leaked system prompt | `JAKU-AI` |
548
+ | 2 | False-positive triage of borderline findings + attack-chain narrative enrichment | synthesis + reports |
549
+ | 3 | Extra business-domain / invariant inference | `JAKU-LOGIC` |
550
+
551
+ **Enabling it:**
552
+
553
+ ```bash
554
+ # Key comes ONLY from the environment — never the config file or CLI
555
+ export OPENAI_API_KEY=sk-... # or ANTHROPIC_API_KEY=sk-ant-...
556
+
557
+ node src/cli.js scan https://myapp.dev --llm --llm-consent --llm-provider openai
558
+ ```
559
+
560
+ Both `--llm` (enablement) **and** `--llm-consent` (or `llm.consent: true`) are
561
+ required before any data leaves your machine. Configure non-secret settings in
562
+ `jaku.config.json`:
563
+
564
+ ```jsonc
565
+ "llm": {
566
+ "enabled": false, // or pass --llm
567
+ "provider": "openai", // openai | anthropic
568
+ "model": null, // null → cheap provider default
569
+ "max_tokens": 1024, // per-call output cap
570
+ "max_calls": 50, // per-scan call budget
571
+ "token_budget": 100000, // per-scan token budget
572
+ "timeout_seconds": 30,
573
+ "consent": false, // or pass --llm-consent
574
+ "base_url": null // optional self-hosted/proxy endpoint
575
+ }
576
+ ```
577
+
578
+ **What data leaves the machine (data minimization):**
579
+
580
+ - *Remediation:* finding title, module, severity, description.
581
+ - *Triage:* title, severity, description, a short evidence snippet — borderline findings only.
582
+ - *Executive summary:* severity counts + finding **titles** (no bodies/evidence).
583
+ - *Payload generation:* a snippet of the **already-leaked** system prompt + the target host.
584
+ - *Business inference:* discovered URL **paths** + form field **names** (no values, no bodies).
585
+
586
+ **Security & safety guarantees:**
587
+
588
+ - **Keys never persist or print.** The API key is read from the environment only,
589
+ is never written to config, logs, reports, `meta`, `finding.evidence`, or PR
590
+ comments. The logger scrubs `sk-…`, `Bearer …`, and `x-api-key` patterns from
591
+ all output. Putting an `api_key` in `jaku.config.json` is rejected with a warning.
592
+ - **Passive mode = no egress.** Third-party calls are auto-disabled in `--passive`.
593
+ - **Safety-tier gating.** LLM-generated **destructive** payloads only fire under
594
+ `--aggressive`; non-destructive generated probes require `--safe-active`.
595
+ - **Budgeted & resilient.** Per-scan call/token budgets, per-call timeout,
596
+ 429 backoff, and a connection-failure circuit breaker — any failure degrades
597
+ silently to deterministic behavior.
598
+ - **No new dependencies.** Uses the built-in `fetch` only.
599
+
600
+ To disable, simply omit `--llm` (or set `"enabled": false`). In CI, set
601
+ `enable-llm: 'true'` on the action and provide `OPENAI_API_KEY` /
602
+ `ANTHROPIC_API_KEY` from repository secrets in the job environment.
603
+
424
604
  ### Report Formats
425
605
 
426
606
  Every scan generates 5 report files:
@@ -467,12 +647,14 @@ node src/cli.js ai https://myapp.dev/api/chat --max-pages 1 -v
467
647
  ```
468
648
  ╦╔═╗╦╔═╦ ╦
469
649
  ║╠═╣╠╩╗║ ║ 呪 Autonomous Security & Quality Intelligence
470
- ╚╝╩ ╩╩ ╩╚═╝ v1.0.3 · Multi-Agent
650
+ ╚╝╩ ╩╩ ╩╚═╝ v1.2.0 · Multi-Agent
471
651
 
472
652
  Target: https://your-app.dev
473
653
  Modules: QA + SECURITY + AI
474
654
  Mode: Multi-Agent Orchestration
655
+ Safety: Safe-Active (non-destructive probing)
475
656
  Severity: ≥ low
657
+ LLM: disabled — not enabled (set llm.enabled or pass --llm)
476
658
 
477
659
  ✔ [JAKU-CRAWL] Complete — 0 findings in 2.1s
478
660
  ✔ [JAKU-QA] Complete — 3 findings in 14.9s ⚡parallel
@@ -505,13 +687,16 @@ node src/cli.js ai https://myapp.dev/api/chat --max-pages 1 -v
505
687
 
506
688
  ## Reports
507
689
 
508
- Every scan generates three report formats, saved to `jaku-reports/<timestamp>/`:
690
+ Every scan generates the following report formats, saved to `jaku-reports/<timestamp>/`:
509
691
 
510
692
  | Format | File | Description |
511
693
  |--------|------|-------------|
512
694
  | **JSON** | `report.json` | Machine-readable findings array for CI/CD integration |
513
695
  | **Markdown** | `report.md` | Human-readable narrative with severity tables and finding details |
514
696
  | **HTML** | `report.html` | Self-contained dark-themed report with severity charts, filters, and embedded evidence |
697
+ | **SARIF** | `report.sarif` | GitHub/GitLab Security Dashboard integration (SARIF v2.1.0) |
698
+ | **Diff** | `diff-report.md` / `diff-report.json` | Regression detection vs. the previous scan run |
699
+ | **OWASP Compliance** | `compliance-owasp.*` | OWASP Top 10 pass/fail report (JSON + MD + HTML) — only with `--compliance owasp` |
515
700
 
516
701
  ### Finding Schema
517
702
 
@@ -536,7 +721,7 @@ Every scan generates three report formats, saved to `jaku-reports/<timestamp>/`:
536
721
  }
537
722
  ```
538
723
 
539
- Modules tag findings as: `qa`, `security`, or `ai`.
724
+ Modules tag findings as: `qa`, `security`, `ai`, `logic`, or `api`.
540
725
 
541
726
  ---
542
727
 
@@ -563,33 +748,48 @@ cp jaku.config.example.json jaku.config.json
563
748
  ```json
564
749
  {
565
750
  "target_url": "https://your-app.dev",
566
- "credentials": {
567
- "username": "",
568
- "password": ""
569
- },
570
- "modules": ["qa", "security", "ai"],
751
+ "modules_enabled": ["qa", "security", "ai", "logic", "api"],
571
752
  "severity_threshold": "low",
753
+ "safety_mode": "safe-active",
572
754
  "halt_on_critical": true,
573
755
  "crawler": {
574
756
  "max_pages": 50,
575
757
  "max_depth": 5,
576
- "respect_robots": true
758
+ "concurrency": 4
759
+ },
760
+ "llm": {
761
+ "enabled": false,
762
+ "provider": "openai",
763
+ "consent": false
577
764
  }
578
765
  }
579
766
  ```
580
767
 
768
+ > The LLM API key is **never** stored in this file — it is read from the
769
+ > `OPENAI_API_KEY` / `ANTHROPIC_API_KEY` environment variable only. See
770
+ > [LLM Augmentation](#llm-augmentation-optional).
771
+
772
+ Unknown, mistyped, or deprecated keys in `jaku.config.json` are reported as
773
+ warnings on load (and ignored) rather than silently honored.
774
+
581
775
  ### Configuration Options
582
776
 
583
777
  | Key | Type | Description |
584
778
  |-----|------|-------------|
585
779
  | `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` |
780
+ | `credentials` | object[] | Login credentials for authenticated scanning |
781
+ | `modules_enabled` | string[] | Modules to enable: `qa`, `security`, `ai`, `logic`, `api` |
588
782
  | `severity_threshold` | string | Minimum severity to report: `critical`, `high`, `medium`, `low` |
783
+ | `safety_mode` | string | Safety tier: `passive`, `safe-active` (default), `aggressive` — see [Safety Modes](#safety-modes) |
589
784
  | `halt_on_critical` | boolean | Exit with code 1 if critical findings detected (for CI/CD) |
590
785
  | `crawler.max_pages` | number | Maximum pages to crawl |
591
786
  | `crawler.max_depth` | number | Maximum link depth to follow |
592
- | `crawler.respect_robots` | boolean | Honor robots.txt directives |
787
+ | `crawler.concurrency` | number | Parallel crawl workers |
788
+ | `llm.enabled` | boolean | Enable optional LLM augmentation (default `false`) — see [LLM Augmentation](#llm-augmentation-optional) |
789
+ | `llm.provider` | string | `openai` or `anthropic` |
790
+ | `llm.model` | string | Model id (provider default if omitted) |
791
+ | `llm.consent` | boolean | Required (with enablement) before any data egress |
792
+ | `llm.max_calls` / `llm.token_budget` | number | Per-scan call / token budgets |
593
793
 
594
794
  ### CI/CD Integration
595
795
 
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,11 +1,11 @@
1
1
  {
2
2
  "name": "jaku.sh",
3
- "version": "1.0.3",
3
+ "version": "1.2.1",
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",
7
7
  "bin": {
8
- "jaku": "./bin/jaku"
8
+ "jaku": "bin/jaku"
9
9
  },
10
10
  "engines": {
11
11
  "node": ">=20"
@@ -13,12 +13,13 @@
13
13
  "files": [
14
14
  "src/",
15
15
  "bin/",
16
+ "scripts/",
16
17
  "action.yml",
17
18
  "README.md"
18
19
  ],
19
20
  "scripts": {
20
21
  "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'",
22
+ "postinstall": "node scripts/postinstall.js",
22
23
  "prepublishOnly": "node src/cli.js --help"
23
24
  },
24
25
  "keywords": [
@@ -46,7 +47,7 @@
46
47
  "homepage": "https://jaku.app",
47
48
  "repository": {
48
49
  "type": "git",
49
- "url": "https://github.com/theshantanupandey/jaku.git"
50
+ "url": "git+https://github.com/theshantanupandey/jaku.git"
50
51
  },
51
52
  "bugs": {
52
53
  "url": "https://github.com/theshantanupandey/jaku/issues"
@@ -59,4 +60,4 @@
59
60
  "playwright": "^1.49.1",
60
61
  "winston": "^3.17.0"
61
62
  }
62
- }
63
+ }
@@ -0,0 +1,73 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * JAKU postinstall — installs the Chromium build Playwright needs.
4
+ *
5
+ * Design goals (it must NEVER break `npm install`):
6
+ * - Skippable via JAKU_SKIP_BROWSER_DOWNLOAD / PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD.
7
+ * - Non-fatal: any failure (network, missing npx, etc.) exits 0 with guidance.
8
+ * - Interrupt-safe: a Ctrl+C (SIGINT) during the ~170 MB download leaves the
9
+ * CLI installed and exits 0 instead of failing the whole install. JAKU will
10
+ * auto-install the browser on first scan if it is still missing.
11
+ */
12
+ import { spawnSync } from 'node:child_process';
13
+
14
+ function log(msg) {
15
+ process.stdout.write(`${msg}\n`);
16
+ }
17
+
18
+ const MANUAL = 'Run `npx playwright install chromium` before your first scan.';
19
+
20
+ // If interrupted directly, don't fail the install.
21
+ process.on('SIGINT', () => {
22
+ log(`\n⚠ JAKU: Chromium download interrupted. JAKU is installed — ${MANUAL}`);
23
+ process.exit(0);
24
+ });
25
+
26
+ function main() {
27
+ const skip =
28
+ process.env.JAKU_SKIP_BROWSER_DOWNLOAD ||
29
+ process.env.PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD;
30
+
31
+ if (skip) {
32
+ log(`JAKU: Skipping Chromium download (skip flag set). ${MANUAL}`);
33
+ return 0;
34
+ }
35
+
36
+ log('JAKU: Installing Chromium for Playwright (~170 MB, one-time).');
37
+ log(' Set JAKU_SKIP_BROWSER_DOWNLOAD=1 to skip; JAKU also auto-installs it on first scan.');
38
+
39
+ let res;
40
+ try {
41
+ res = spawnSync('npx', ['playwright', 'install', 'chromium'], {
42
+ stdio: 'inherit',
43
+ shell: process.platform === 'win32',
44
+ });
45
+ } catch (e) {
46
+ log(`⚠ JAKU: Could not auto-install Chromium (${e.message}). ${MANUAL}`);
47
+ return 0;
48
+ }
49
+
50
+ if (res.signal) {
51
+ log(`\n⚠ JAKU: Chromium install was interrupted (${res.signal}). JAKU is installed — ${MANUAL}`);
52
+ return 0;
53
+ }
54
+ if (res.error) {
55
+ log(`⚠ JAKU: Could not auto-install Chromium (${res.error.message}). ${MANUAL}`);
56
+ return 0;
57
+ }
58
+ if (res.status !== 0) {
59
+ log(`⚠ JAKU: Could not auto-install Chromium. ${MANUAL}`);
60
+ return 0;
61
+ }
62
+
63
+ log('JAKU: Chromium ready. ✔');
64
+ return 0;
65
+ }
66
+
67
+ // Always exit 0 — installing the CLI must never fail because of the browser.
68
+ try {
69
+ process.exit(main());
70
+ } catch (e) {
71
+ log(`⚠ JAKU: postinstall encountered an issue (${e.message}). ${MANUAL}`);
72
+ process.exit(0);
73
+ }
@@ -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 {