@sprid/scout 0.1.1 → 0.1.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.2 - 2026-10-23
4
+
5
+ - `job_results` refuses a run id that is not one scout issued. A crafted id could read any JSON file on the machine.
6
+
3
7
  ## 0.1.1 - 2026-10-19
4
8
 
5
9
  - Remove automatic likes from TikTok discovery. Research no longer clicks like controls while collecting accounts.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sprid/scout",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Local MCP server that researches a niche over your own Chrome: the accounts winning it, and the ads running in it.",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "homepage": "https://sprid.studio/agents",
package/src/store.js CHANGED
@@ -23,16 +23,25 @@ function readJson(file, fallback) {
23
23
  }
24
24
  }
25
25
 
26
+ // A run id is `${tool}-${8 hex}` (jobs.js). It arrives from a tool argument,
27
+ // so anything else is refused before it reaches a path: `../` in it read any
28
+ // JSON file on the machine.
29
+ const RUN_ID = /^[a-z]+-[0-9a-f]{8}$/;
30
+
26
31
  function runFile(runId) {
32
+ if (!RUN_ID.test(String(runId))) return null;
27
33
  return path.join(RUNS_DIR, `${runId}.json`);
28
34
  }
29
35
 
30
36
  function saveRun(run) {
31
- writeAtomic(runFile(run.id), run);
37
+ const file = runFile(run.id);
38
+ if (!file) throw new Error(`Invalid run id: ${run.id}`);
39
+ writeAtomic(file, run);
32
40
  }
33
41
 
34
42
  function loadRun(runId) {
35
- return readJson(runFile(runId), null);
43
+ const file = runFile(runId);
44
+ return file ? readJson(file, null) : null;
36
45
  }
37
46
 
38
47
  function listRuns() {