jaku.sh 1.2.0 → 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 +57 -0
- package/package.json +6 -5
- package/scripts/postinstall.js +73 -0
- package/src/cli.js +11 -0
- package/src/utils/browser.js +62 -0
package/README.md
CHANGED
|
@@ -11,6 +11,7 @@ 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)
|
|
@@ -72,6 +73,62 @@ node src/cli.js security https://your-app.dev --severity high
|
|
|
72
73
|
|
|
73
74
|
---
|
|
74
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
|
+
|
|
75
132
|
## Architecture
|
|
76
133
|
|
|
77
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.
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jaku.sh",
|
|
3
|
-
"version": "1.2.
|
|
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": "
|
|
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": "
|
|
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
|
+
}
|
package/src/cli.js
CHANGED
|
@@ -16,6 +16,7 @@ import { ComplianceReporter } from './reporting/compliance-reporter.js';
|
|
|
16
16
|
import { AuthManager } from './core/auth-manager.js';
|
|
17
17
|
import { getVersion } from './utils/version.js';
|
|
18
18
|
import { LLMClient } from './core/llm/llm-client.js';
|
|
19
|
+
import { ensureChromium } from './utils/browser.js';
|
|
19
20
|
|
|
20
21
|
const VERSION = getVersion();
|
|
21
22
|
|
|
@@ -116,6 +117,16 @@ async function runScan(url, options, modulesToRun) {
|
|
|
116
117
|
);
|
|
117
118
|
console.log();
|
|
118
119
|
|
|
120
|
+
// ═══════════════════════════════════════
|
|
121
|
+
// Preflight: ensure the browser engine is available
|
|
122
|
+
// ═══════════════════════════════════════
|
|
123
|
+
try {
|
|
124
|
+
ensureChromium(logger);
|
|
125
|
+
} catch (err) {
|
|
126
|
+
console.error(chalk.red(`\n ⛔ ${err.message}\n`));
|
|
127
|
+
process.exit(1);
|
|
128
|
+
}
|
|
129
|
+
|
|
119
130
|
// ═══════════════════════════════════════
|
|
120
131
|
// Phase 0: Authentication (before spinners)
|
|
121
132
|
// ═══════════════════════════════════════
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import { spawnSync } from 'node:child_process';
|
|
3
|
+
import { chromium } from 'playwright';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Returns the path to the Chromium build Playwright expects, or null if it
|
|
7
|
+
* cannot be resolved.
|
|
8
|
+
*/
|
|
9
|
+
function resolveChromiumPath() {
|
|
10
|
+
try {
|
|
11
|
+
const p = chromium.executablePath();
|
|
12
|
+
return p || null;
|
|
13
|
+
} catch {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** True if the Chromium build is actually present on disk. */
|
|
19
|
+
export function isChromiumInstalled() {
|
|
20
|
+
const p = resolveChromiumPath();
|
|
21
|
+
return Boolean(p && fs.existsSync(p));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Ensure Chromium is available before a scan. If it is missing, attempt a
|
|
26
|
+
* one-time install (unless skipping is requested), then re-check.
|
|
27
|
+
*
|
|
28
|
+
* Throws a friendly Error if Chromium is required but unavailable so the CLI
|
|
29
|
+
* can print actionable guidance instead of a raw Playwright stack trace.
|
|
30
|
+
*/
|
|
31
|
+
export function ensureChromium(logger) {
|
|
32
|
+
if (isChromiumInstalled()) return true;
|
|
33
|
+
|
|
34
|
+
const skip =
|
|
35
|
+
process.env.JAKU_SKIP_BROWSER_DOWNLOAD ||
|
|
36
|
+
process.env.PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD;
|
|
37
|
+
if (skip) {
|
|
38
|
+
throw new Error(
|
|
39
|
+
'Chromium is not installed and a skip flag is set. Run: npx playwright install chromium'
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const msg = 'Chromium not found — installing it now (one-time, ~170 MB). This may take a minute...';
|
|
44
|
+
logger?.info?.(msg);
|
|
45
|
+
console.log(` ${msg}`);
|
|
46
|
+
|
|
47
|
+
try {
|
|
48
|
+
spawnSync('npx', ['playwright', 'install', 'chromium'], {
|
|
49
|
+
stdio: 'inherit',
|
|
50
|
+
shell: process.platform === 'win32',
|
|
51
|
+
});
|
|
52
|
+
} catch {
|
|
53
|
+
// fall through to the re-check below
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (!isChromiumInstalled()) {
|
|
57
|
+
throw new Error(
|
|
58
|
+
'Chromium is required but could not be installed automatically. Run: npx playwright install chromium'
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
return true;
|
|
62
|
+
}
|