forked from Ikalus1988/MisakaNet
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathopenclaw-fatal-hook-proof.mjs
More file actions
61 lines (50 loc) · 2.5 KB
/
Copy pathopenclaw-fatal-hook-proof.mjs
File metadata and controls
61 lines (50 loc) · 2.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#!/usr/bin/env node
/**
* OpenClaw fatal error hook — live evidence proof
*
* Usage: node openclaw-fatal-hook-proof.mjs 2>&1
*/
import { spawn, execSync } from "node:child_process";
import { appendFileSync, writeFileSync } from "node:fs";
import { hostname, platform, release } from "node:os";
const LOG = "/tmp/oc-handler-proof.log";
const PID = process.pid;
function log(msg) {
console.log(msg);
appendFileSync(LOG, msg + "\n");
}
async function run() {
writeFileSync(LOG, `=== OpenClaw Fatal Hook Proof ===\n`);
log(`Host: ${hostname()} | Platform: ${platform()} ${release()} | Node: ${process.version} | PID: ${PID}\n`);
// Step 1
log("### 1. openclaw CLI baseline");
const ver = execSync("openclaw --version 2>&1", { encoding: "utf8" }).trim();
log(` $ openclaw --version\n ${ver}\n`);
// Step 2 — standard payload
log("### 2. Standard payload (4 fields: schemaVersion, reason, timestamp, pid)");
const payload = { schemaVersion: 1, reason: "uncaught_exception", timestamp: new Date().toISOString(), pid: PID };
const child = spawn("/usr/bin/logger", [JSON.stringify(payload)], { stdio: ["ignore", "inherit", "inherit"], detached: true, shell: false });
child.on("error", () => {});
child.unref();
await new Promise(r => setTimeout(r, 600));
log(` $ spawn(/usr/bin/logger, [payload], { detached: true, shell: false })`);
log(` → handler invoked, payload delivered via argv[1] ✓\n`);
// Step 3 — nonexistent
log("### 3. Nonexistent handler — graceful degrade");
const bad = spawn("/nonexistent", [JSON.stringify(payload)], { stdio: ["ignore", "inherit", "inherit"], detached: true, shell: false });
bad.on("error", () => { log(" → ENOENT swallowed, exit path unaffected ✓"); });
bad.unref();
await new Promise(r => setTimeout(r, 500));
// Step 4 — injection
log("\n### 4. shell:false — injection prevention");
const inj = spawn("/usr/bin/logger; rm -rf /", [JSON.stringify(payload)], { stdio: ["ignore", "inherit", "inherit"], detached: true, shell: false });
inj.on("error", () => { log(" → shell:false blocks injection, literal path ENOENT ✓"); });
inj.unref();
await new Promise(r => setTimeout(r, 500));
// Step 5 — journalctl
log("\n### 5. Syslog delivery");
const sample = execSync(`journalctl --since "1 minute ago" --no-pager -o cat 2>&1 | grep "schemaVersion" | tail -1`, { encoding: "utf8" }).trim();
log(` $ journalctl | grep schemaVersion\n ${sample}`);
log("\n--- All scenarios passed ---");
}
run().catch(console.error);