clay-server 2.22.2 → 2.22.3-beta.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.
@@ -0,0 +1,57 @@
1
+ // build-user-env.js — Build a minimal, safe environment for user subprocesses.
2
+ // Prevents leaking the root daemon's full process.env to user sessions.
3
+
4
+ var os = require("os");
5
+
6
+ // Only these vars are forwarded from the daemon's environment.
7
+ var ALLOWED_KEYS = ["PATH", "LANG", "NODE_ENV"];
8
+
9
+ /**
10
+ * Build a clean env object for spawning a user process.
11
+ * osUserInfo: { uid, gid, home, user, shell } or null for same-user fallback.
12
+ */
13
+ function buildUserEnv(osUserInfo) {
14
+ var env = {};
15
+
16
+ // Copy only allowlisted keys from daemon env
17
+ for (var i = 0; i < ALLOWED_KEYS.length; i++) {
18
+ var key = ALLOWED_KEYS[i];
19
+ if (process.env[key]) env[key] = process.env[key];
20
+ }
21
+
22
+ // Copy all LC_* locale vars
23
+ var keys = Object.keys(process.env);
24
+ for (var j = 0; j < keys.length; j++) {
25
+ if (keys[j].indexOf("LC_") === 0) {
26
+ env[keys[j]] = process.env[keys[j]];
27
+ }
28
+ }
29
+
30
+ // Terminal settings
31
+ env.TERM = "xterm-256color";
32
+ env.COLORFGBG = "15;0"; // Suppress OSC 11 background-color queries
33
+
34
+ // User identity
35
+ if (osUserInfo) {
36
+ env.HOME = osUserInfo.home;
37
+ env.USER = osUserInfo.user;
38
+ env.LOGNAME = osUserInfo.user;
39
+ if (osUserInfo.shell) env.SHELL = osUserInfo.shell;
40
+ } else {
41
+ env.HOME = process.env.HOME || os.homedir();
42
+ env.USER = process.env.USER || "";
43
+ env.LOGNAME = process.env.LOGNAME || process.env.USER || "";
44
+ env.SHELL = process.env.SHELL || "/bin/bash";
45
+ }
46
+
47
+ // XDG runtime dir (needed for dbus, systemd user services, etc.)
48
+ if (osUserInfo) {
49
+ env.XDG_RUNTIME_DIR = "/run/user/" + osUserInfo.uid;
50
+ } else if (process.env.XDG_RUNTIME_DIR) {
51
+ env.XDG_RUNTIME_DIR = process.env.XDG_RUNTIME_DIR;
52
+ }
53
+
54
+ return env;
55
+ }
56
+
57
+ module.exports = { buildUserEnv: buildUserEnv };
package/lib/sdk-bridge.js CHANGED
@@ -708,11 +708,13 @@ function createSDKBridge(opts) {
708
708
  try { fs.chmodSync(socketPath, 0o777); } catch (e) {}
709
709
 
710
710
  // Spawn worker process as the target Linux user.
711
- // Inherit full env from daemon, override user-specific vars.
712
- var workerEnv = Object.assign({}, process.env, {
713
- HOME: userInfo.home,
714
- USER: linuxUser,
715
- LOGNAME: linuxUser,
711
+ // Build a minimal, isolated env (no daemon env leakage).
712
+ var workerEnv = require("./build-user-env").buildUserEnv({
713
+ uid: userInfo.uid,
714
+ gid: userInfo.gid,
715
+ home: userInfo.home,
716
+ user: linuxUser,
717
+ shell: userInfo.shell || "/bin/bash",
716
718
  });
717
719
 
718
720
  console.log("[sdk-bridge] Spawning worker: uid=" + userInfo.uid + " gid=" + userInfo.gid + " cwd=" + cwd + " socket=" + socketPath);
package/lib/terminal.js CHANGED
@@ -5,14 +5,17 @@ try {
5
5
  pty = null;
6
6
  }
7
7
 
8
+ var { buildUserEnv } = require("./build-user-env");
9
+
8
10
  function createTerminal(cwd, cols, rows, osUserInfo) {
9
11
  if (!pty) return null;
10
12
 
11
- var shell = process.env.SHELL
13
+ // Determine shell: prefer target user's shell, then fallback
14
+ var shell = (osUserInfo && osUserInfo.shell)
12
15
  || (process.platform === "win32" ? process.env.COMSPEC || "cmd.exe" : "/bin/bash");
13
16
 
14
- // OS-level user isolation: spawn terminal as the mapped Linux user
15
- var termEnv = Object.assign({}, process.env, { TERM: "xterm-256color" });
17
+ // Build a minimal, isolated environment (no daemon env leakage)
18
+ var termEnv = buildUserEnv(osUserInfo);
16
19
  var spawnOpts = {
17
20
  name: "xterm-256color",
18
21
  cols: cols || 80,
@@ -24,12 +27,6 @@ function createTerminal(cwd, cols, rows, osUserInfo) {
24
27
  if (osUserInfo) {
25
28
  spawnOpts.uid = osUserInfo.uid;
26
29
  spawnOpts.gid = osUserInfo.gid;
27
- // Use the target user's shell and home
28
- termEnv.HOME = osUserInfo.home;
29
- termEnv.USER = osUserInfo.user;
30
- termEnv.LOGNAME = osUserInfo.user;
31
- // Use target user's shell if available
32
- if (osUserInfo.shell) shell = osUserInfo.shell;
33
30
  }
34
31
 
35
32
  var args = osUserInfo ? ["-l"] : [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clay-server",
3
- "version": "2.22.2",
3
+ "version": "2.22.3-beta.1",
4
4
  "description": "Self-hosted Claude Code in your browser. Multi-session, multi-user, push notifications.",
5
5
  "bin": {
6
6
  "clay-server": "./bin/cli.js",