@kaitranntt/ccs 8.0.0-dev.3 → 8.1.0

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.
@@ -141,7 +141,7 @@ function getClaudeSubcommandName(args) {
141
141
  const arg = args[i];
142
142
  if (arg === '--')
143
143
  return null;
144
- if (arg === '--print')
144
+ if (arg === '--print' || arg === '-p')
145
145
  return null;
146
146
  if (arg.startsWith('-')) {
147
147
  if (VALUE_TAKING_FLAGS.has(arg)) {
@@ -1 +1 @@
1
- {"version":3,"file":"claude-subcommand-detector.js","sourceRoot":"","sources":["../../src/utils/claude-subcommand-detector.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"claude-subcommand-detector.js","sourceRoot":"","sources":["../../src/utils/claude-subcommand-detector.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,27 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="bun-types" />
1
3
  export type SqliteJsonRow = Record<string, unknown>;
2
- export declare function querySqliteJson(dbPath: string, sql: string): Promise<SqliteJsonRow[]>;
4
+ declare function getPlatformTrustedPrefixes(): string[];
5
+ /**
6
+ * Validate a CCS_SQLITE_BIN override path.
7
+ *
8
+ * Security invariant: the resolved (symlink-expanded) path must start with
9
+ * at least one trusted prefix. This prevents pointing at a binary in a
10
+ * user-writable location such as /tmp, $HOME/.local, or a relative PATH
11
+ * entry, which would reintroduce the PATH-hijack vector closed in #1347.
12
+ *
13
+ * Returns the validated path on success, or throws with an explanation.
14
+ */
15
+ declare function validateEnvOverridePath(rawPath: string): string;
16
+ /**
17
+ * Resolve the sqlite3 binary to use.
18
+ *
19
+ * Resolution order:
20
+ * 1. CCS_SQLITE_BIN env var override (validated against trusted prefixes)
21
+ * 2. First accessible path from the platform's hardcoded trusted list
22
+ * 3. Throw "sqlite3 command not available"
23
+ */
24
+ declare function resolveTrustedSqlitePath(env?: NodeJS.ProcessEnv): string;
25
+ export declare function querySqliteJson(dbPath: string, sql: string, env?: NodeJS.ProcessEnv): Promise<SqliteJsonRow[]>;
26
+ export { resolveTrustedSqlitePath, validateEnvOverridePath, getPlatformTrustedPrefixes };
3
27
  //# sourceMappingURL=sqlite-cli.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sqlite-cli.d.ts","sourceRoot":"","sources":["../../../src/web-server/usage/sqlite-cli.ts"],"names":[],"mappings":"AAYA,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAyBpD,wBAAsB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAyB3F"}
1
+ {"version":3,"file":"sqlite-cli.d.ts","sourceRoot":"","sources":["../../../src/web-server/usage/sqlite-cli.ts"],"names":[],"mappings":";;AA6CA,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAYpD,iBAAS,0BAA0B,IAAI,MAAM,EAAE,CAE9C;AAED;;;;;;;;;GASG;AACH,iBAAS,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAqCxD;AAED;;;;;;;GAOG;AACH,iBAAS,wBAAwB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAwB9E;AAED,wBAAsB,eAAe,CACnC,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,OAAO,CAAC,aAAa,EAAE,CAAC,CAgC1B;AAGD,OAAO,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,0BAA0B,EAAE,CAAC"}
@@ -23,27 +23,121 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.querySqliteJson = void 0;
26
+ exports.getPlatformTrustedPrefixes = exports.validateEnvOverridePath = exports.resolveTrustedSqlitePath = exports.querySqliteJson = void 0;
27
27
  const child_process_1 = require("child_process");
28
28
  const fs = __importStar(require("fs"));
29
29
  const util_1 = require("util");
30
30
  const execFileAsync = (0, util_1.promisify)(child_process_1.execFile);
31
31
  const SQLITE_JSON_MAX_BUFFER = 10 * 1024 * 1024;
32
- const TRUSTED_SQLITE_PATHS = [
32
+ // Trusted system paths per platform. These are fixed, non-user-writable
33
+ // locations managed by the OS or a system package manager.
34
+ // PATH-hijack threat model: we never resolve from $PATH; we only accept
35
+ // binaries whose realpath resolves under one of these prefixes.
36
+ const TRUSTED_SQLITE_PATHS_UNIX = [
33
37
  '/usr/bin/sqlite3',
34
38
  '/usr/local/bin/sqlite3',
35
39
  '/opt/homebrew/bin/sqlite3',
36
40
  ];
41
+ // Windows has no single canonical system install path for sqlite3
42
+ // (winget, Chocolatey, and Scoop all use different locations). An empty
43
+ // list means Windows falls through to the CCS_SQLITE_BIN env-var path.
44
+ const TRUSTED_SQLITE_PATHS_WINDOWS = [];
45
+ // Trusted path prefixes used to validate env-var overrides. A realpath that
46
+ // does not start with one of these prefixes is rejected to prevent users or
47
+ // CI from pointing CCS_SQLITE_BIN at a writable/untrusted location.
48
+ const TRUSTED_PREFIX_UNIX = [
49
+ '/usr/bin/',
50
+ '/usr/local/bin/',
51
+ '/usr/sbin/',
52
+ '/usr/local/sbin/',
53
+ '/opt/homebrew/',
54
+ '/opt/local/', // MacPorts
55
+ '/nix/store/', // Nix / NixOS immutable store
56
+ '/run/current-system/', // NixOS system activation symlink target
57
+ '/snap/', // Snap packages
58
+ ];
59
+ const TRUSTED_PREFIX_WINDOWS = [
60
+ 'C:\\Program Files\\',
61
+ 'C:\\Program Files (x86)\\',
62
+ 'C:\\Windows\\System32\\',
63
+ 'C:\\Windows\\SysWOW64\\',
64
+ 'C:\\ProgramData\\chocolatey\\bin\\', // Chocolatey managed bin dir
65
+ ];
37
66
  function isCommandMissing(error) {
38
67
  if (!(error instanceof Error))
39
68
  return false;
40
69
  const nodeError = error;
41
70
  return nodeError.code === 'ENOENT' || /not found/i.test(nodeError.message);
42
71
  }
43
- function resolveTrustedSqlitePath() {
44
- const trustedPath = TRUSTED_SQLITE_PATHS.find((candidate) => {
72
+ function getPlatformTrustedPaths() {
73
+ return process.platform === 'win32' ? TRUSTED_SQLITE_PATHS_WINDOWS : TRUSTED_SQLITE_PATHS_UNIX;
74
+ }
75
+ function getPlatformTrustedPrefixes() {
76
+ return process.platform === 'win32' ? TRUSTED_PREFIX_WINDOWS : TRUSTED_PREFIX_UNIX;
77
+ }
78
+ exports.getPlatformTrustedPrefixes = getPlatformTrustedPrefixes;
79
+ /**
80
+ * Validate a CCS_SQLITE_BIN override path.
81
+ *
82
+ * Security invariant: the resolved (symlink-expanded) path must start with
83
+ * at least one trusted prefix. This prevents pointing at a binary in a
84
+ * user-writable location such as /tmp, $HOME/.local, or a relative PATH
85
+ * entry, which would reintroduce the PATH-hijack vector closed in #1347.
86
+ *
87
+ * Returns the validated path on success, or throws with an explanation.
88
+ */
89
+ function validateEnvOverridePath(rawPath) {
90
+ let resolved;
91
+ try {
92
+ resolved = fs.realpathSync(rawPath);
93
+ }
94
+ catch {
95
+ throw new Error(`CCS_SQLITE_BIN path "${rawPath}" could not be resolved: file not found or inaccessible`);
96
+ }
97
+ // Verify executable bit (or file existence on Windows where X_OK is unreliable).
98
+ try {
99
+ if (process.platform === 'win32') {
100
+ fs.accessSync(resolved, fs.constants.F_OK);
101
+ }
102
+ else {
103
+ fs.accessSync(resolved, fs.constants.X_OK);
104
+ }
105
+ }
106
+ catch {
107
+ throw new Error(`CCS_SQLITE_BIN path "${resolved}" is not executable`);
108
+ }
109
+ const normalizedResolved = process.platform === 'win32' ? resolved.toLowerCase() : resolved;
110
+ const trusted = getPlatformTrustedPrefixes().some((prefix) => {
111
+ const normalizedPrefix = process.platform === 'win32' ? prefix.toLowerCase() : prefix;
112
+ return normalizedResolved.startsWith(normalizedPrefix);
113
+ });
114
+ if (!trusted) {
115
+ throw new Error(`CCS_SQLITE_BIN path "${resolved}" does not resolve under a trusted system prefix. ` +
116
+ `Paths under user-writable locations (e.g. /tmp, $HOME/.local) are rejected ` +
117
+ `to prevent PATH-hijack attacks.`);
118
+ }
119
+ return resolved;
120
+ }
121
+ exports.validateEnvOverridePath = validateEnvOverridePath;
122
+ /**
123
+ * Resolve the sqlite3 binary to use.
124
+ *
125
+ * Resolution order:
126
+ * 1. CCS_SQLITE_BIN env var override (validated against trusted prefixes)
127
+ * 2. First accessible path from the platform's hardcoded trusted list
128
+ * 3. Throw "sqlite3 command not available"
129
+ */
130
+ function resolveTrustedSqlitePath(env = process.env) {
131
+ const envOverride = env['CCS_SQLITE_BIN'];
132
+ if (envOverride && envOverride.trim().length > 0) {
133
+ // May throw — caller surfaces the error.
134
+ return validateEnvOverridePath(envOverride.trim());
135
+ }
136
+ const trustedPath = getPlatformTrustedPaths().find((candidate) => {
45
137
  try {
46
- fs.accessSync(candidate, fs.constants.X_OK);
138
+ // Resolve symlinks so the check is on the real binary.
139
+ const real = fs.realpathSync(candidate);
140
+ fs.accessSync(real, fs.constants.X_OK);
47
141
  return true;
48
142
  }
49
143
  catch {
@@ -53,14 +147,23 @@ function resolveTrustedSqlitePath() {
53
147
  if (!trustedPath) {
54
148
  throw new Error('sqlite3 command not available');
55
149
  }
56
- return trustedPath;
150
+ // Return the realpath to avoid double-hop symlink confusion at exec time.
151
+ return fs.realpathSync(trustedPath);
57
152
  }
58
- async function querySqliteJson(dbPath, sql) {
153
+ exports.resolveTrustedSqlitePath = resolveTrustedSqlitePath;
154
+ async function querySqliteJson(dbPath, sql, env = process.env) {
59
155
  if (!fs.existsSync(dbPath)) {
60
156
  return [];
61
157
  }
158
+ let sqlitePath;
159
+ try {
160
+ sqlitePath = resolveTrustedSqlitePath(env);
161
+ }
162
+ catch (error) {
163
+ const message = error instanceof Error ? error.message : String(error);
164
+ throw new Error(message);
165
+ }
62
166
  try {
63
- const sqlitePath = resolveTrustedSqlitePath();
64
167
  const { stdout } = await execFileAsync(sqlitePath, ['-json', dbPath, sql], {
65
168
  maxBuffer: SQLITE_JSON_MAX_BUFFER,
66
169
  });
@@ -1 +1 @@
1
- {"version":3,"file":"sqlite-cli.js","sourceRoot":"","sources":["../../../src/web-server/usage/sqlite-cli.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,iDAAyC;AACzC,uCAAyB;AACzB,+BAAiC;AAEjC,MAAM,aAAa,GAAG,IAAA,gBAAS,EAAC,wBAAQ,CAAC,CAAC;AAC1C,MAAM,sBAAsB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAChD,MAAM,oBAAoB,GAAG;IAC3B,kBAAkB;IAClB,wBAAwB;IACxB,2BAA2B;CAC5B,CAAC;AAIF,SAAS,gBAAgB,CAAC,KAAc;IACtC,IAAI,CAAC,CAAC,KAAK,YAAY,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC5C,MAAM,SAAS,GAAG,KAAkC,CAAC;IACrD,OAAO,SAAS,CAAC,IAAI,KAAK,QAAQ,IAAI,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;AAC7E,CAAC;AAED,SAAS,wBAAwB;IAC/B,MAAM,WAAW,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE;QAC1D,IAAI,CAAC;YACH,EAAE,CAAC,UAAU,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YAC5C,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACnD,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAEM,KAAK,UAAU,eAAe,CAAC,MAAc,EAAE,GAAW;IAC/D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,wBAAwB,EAAE,CAAC;QAC9C,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,aAAa,CAAC,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE;YACzE,SAAS,EAAE,sBAAsB;SAClC,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;QAC9B,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACnC,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAE,MAA0B,CAAC,CAAC,CAAC,EAAE,CAAC;IAClE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;QACnD,CAAC;QAED,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,MAAM,IAAI,KAAK,CAAC,4BAA4B,MAAM,KAAK,OAAO,EAAE,CAAC,CAAC;IACpE,CAAC;AACH,CAAC;AAzBD,0CAyBC"}
1
+ {"version":3,"file":"sqlite-cli.js","sourceRoot":"","sources":["../../../src/web-server/usage/sqlite-cli.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaitranntt/ccs",
3
- "version": "8.0.0-dev.3",
3
+ "version": "8.1.0",
4
4
  "description": "Claude Code Switch - Instant profile switching between Claude, GLM, Kimi, and more",
5
5
  "keywords": [
6
6
  "cli",