sema-core 2.0.5 → 2.0.7
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/dist/events/types.d.ts +13 -0
- package/dist/events/types.d.ts.map +1 -1
- package/dist/manager/PermissionManager.d.ts.map +1 -1
- package/dist/manager/PermissionManager.js +66 -88
- package/dist/manager/PermissionManager.js.map +1 -1
- package/dist/manager/StateManager.d.ts +1 -1
- package/dist/manager/StateManager.js +1 -1
- package/dist/prompt/memory.d.ts.map +1 -1
- package/dist/prompt/memory.js +23 -12
- package/dist/prompt/memory.js.map +1 -1
- package/dist/prompt/permission.d.ts +1 -1
- package/dist/prompt/permission.d.ts.map +1 -1
- package/dist/prompt/permission.js +43 -7
- package/dist/prompt/permission.js.map +1 -1
- package/dist/services/api/apiUtil.js +2 -2
- package/dist/services/api/apiUtil.js.map +1 -1
- package/dist/tools/FetchUrl.js +1 -1
- package/dist/tools/FetchUrl.js.map +1 -1
- package/dist/tools/PickOption.d.ts +26 -0
- package/dist/tools/PickOption.d.ts.map +1 -1
- package/dist/tools/PickOption.js +30 -18
- package/dist/tools/PickOption.js.map +1 -1
- package/dist/tools/RunShell.d.ts.map +1 -1
- package/dist/tools/RunShell.js +8 -7
- package/dist/tools/RunShell.js.map +1 -1
- package/dist/util/commands.d.ts +14 -0
- package/dist/util/commands.d.ts.map +1 -1
- package/dist/util/commands.js +115 -4
- package/dist/util/commands.js.map +1 -1
- package/dist/util/commands.test.d.ts +2 -0
- package/dist/util/commands.test.d.ts.map +1 -0
- package/dist/util/commands.test.js +93 -0
- package/dist/util/commands.test.js.map +1 -0
- package/dist/util/fetchSafety.d.ts +11 -0
- package/dist/util/fetchSafety.d.ts.map +1 -0
- package/dist/util/fetchSafety.js +86 -0
- package/dist/util/fetchSafety.js.map +1 -0
- package/dist/util/fetchSafety.test.d.ts +2 -0
- package/dist/util/fetchSafety.test.d.ts.map +1 -0
- package/dist/util/fetchSafety.test.js +44 -0
- package/dist/util/fetchSafety.test.js.map +1 -0
- package/dist/util/fetchUrl.d.ts +1 -1
- package/dist/util/fetchUrl.d.ts.map +1 -1
- package/dist/util/fetchUrl.js +2 -2
- package/dist/util/fetchUrl.js.map +1 -1
- package/dist/util/shellSafety.d.ts +34 -0
- package/dist/util/shellSafety.d.ts.map +1 -0
- package/dist/util/shellSafety.js +122 -0
- package/dist/util/shellSafety.js.map +1 -0
- package/dist/util/shellSafety.test.d.ts +2 -0
- package/dist/util/shellSafety.test.d.ts.map +1 -0
- package/dist/util/shellSafety.test.js +103 -0
- package/dist/util/shellSafety.test.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.hasRedirection = hasRedirection;
|
|
4
|
+
exports.hasDangerousCommand = hasDangerousCommand;
|
|
5
|
+
exports.isUnsafeForPrefixAuth = isUnsafeForPrefixAuth;
|
|
6
|
+
exports.isReadonlySafeCommand = isReadonlySafeCommand;
|
|
7
|
+
const commands_1 = require("./commands");
|
|
8
|
+
// 仅凭首词即可判定安全的「真只读」单命令。
|
|
9
|
+
// find 列入只读,但需额外排除危险动作 flag(见 DANGEROUS_FIND_FLAGS)。
|
|
10
|
+
const READONLY_COMMANDS = new Set([
|
|
11
|
+
'pwd', 'tree', 'date', 'which', 'find',
|
|
12
|
+
'ls', 'grep', 'head', 'tail', 'cat', 'du', 'wc', 'echo', 'env', 'printenv',
|
|
13
|
+
]);
|
|
14
|
+
// find 的危险动作 flag:可执行任意命令(-exec/-execdir/-ok/-okdir)、删除(-delete)、
|
|
15
|
+
// 写文件(-fprintf/-fprint/-fls)。命中则该 find 不走只读快速通道。
|
|
16
|
+
const DANGEROUS_FIND_FLAGS = /(^|\s)-(exec(dir)?|ok(dir)?|delete|fprintf?|fls)\b/;
|
|
17
|
+
// 仅允许整条精确匹配的完整命令(多词命令不能按首词放行,如 git 仅放行只读子命令)
|
|
18
|
+
const SAFE_FULL_COMMANDS = new Set([
|
|
19
|
+
'git status', 'git diff', 'git log', 'git branch',
|
|
20
|
+
]);
|
|
21
|
+
// 段内重定向:> >> < << <<< >| <> n> n>> &> 等。命中则不走只读快速通道,
|
|
22
|
+
// 防止 `echo x > /etc/passwd`、`cat secret > file` 这类「只读首词 + 重定向」变成写文件原语。
|
|
23
|
+
const REDIRECTION_RE = /(^|\s)\d*(?:>>|<<<|<<|>\||<>|<&|>&|>|<)/;
|
|
24
|
+
/**
|
|
25
|
+
* 命令是否含重定向。用于「前缀授权」纵深防御:前缀匹配只看首词,
|
|
26
|
+
* 而 `echo x > file` 的危险来自重定向,故含重定向的命令不应被前缀授权覆盖,
|
|
27
|
+
* 也不应向用户提供「按前缀授权」选项。
|
|
28
|
+
*
|
|
29
|
+
* 先用 splitCommand 规范化(它会把 `x>file` 这类无空格重定向还原成带空格的 ` > ` 形式,
|
|
30
|
+
* 并正确处理引号),再用 REDIRECTION_RE 检测;解析失败时保守按「含重定向」处理。
|
|
31
|
+
*/
|
|
32
|
+
function hasRedirection(command) {
|
|
33
|
+
if (REDIRECTION_RE.test(command))
|
|
34
|
+
return true;
|
|
35
|
+
try {
|
|
36
|
+
return (0, commands_1.splitCommand)(command).some(seg => REDIRECTION_RE.test(seg));
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
// 危险首词:危险性在参数里、不该按首词前缀授权的命令。授权 rm:* / sudo:* 等会把
|
|
43
|
+
// `rm -rf /`、任意 `sudo ...` 一并放行,故这些命令不提供前缀授权、也不被已存前缀覆盖。
|
|
44
|
+
const DANGEROUS_PREFIX_COMMANDS = new Set([
|
|
45
|
+
'rm', 'rmdir', 'dd', 'shred', 'truncate',
|
|
46
|
+
'chmod', 'chown', 'chgrp',
|
|
47
|
+
'kill', 'killall', 'pkill',
|
|
48
|
+
'sudo', 'doas', 'su',
|
|
49
|
+
'mv',
|
|
50
|
+
]);
|
|
51
|
+
function isDangerousSubcommand(seg) {
|
|
52
|
+
const s = seg.trim();
|
|
53
|
+
const first = s.split(/\s+/)[0] ?? '';
|
|
54
|
+
if (DANGEROUS_PREFIX_COMMANDS.has(first))
|
|
55
|
+
return true;
|
|
56
|
+
if (first.startsWith('mkfs'))
|
|
57
|
+
return true; // mkfs / mkfs.ext4 等格式化
|
|
58
|
+
if (first === 'find' && DANGEROUS_FIND_FLAGS.test(s))
|
|
59
|
+
return true;
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* 命令是否含「语义危险」子命令:危险首词(rm/sudo/mv 等)或 find 危险 flag。
|
|
64
|
+
* 不含重定向——重定向是否危险取决于路径(项目内可能安全),应交给上层模型判断。
|
|
65
|
+
*
|
|
66
|
+
* 用于 AutoRun:命中即「确定性危险」,直接转人工,不调模型(避免模型误判 safe 放行)。
|
|
67
|
+
* 解析失败保守按「危险」处理(fail-closed)。
|
|
68
|
+
*/
|
|
69
|
+
function hasDangerousCommand(command) {
|
|
70
|
+
let segs;
|
|
71
|
+
try {
|
|
72
|
+
segs = (0, commands_1.splitCommand)(command);
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
return segs.some(isDangerousSubcommand);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* 命令是否「不适合按前缀授权」。命中则:
|
|
81
|
+
* - checkRunShellPermission 不向用户提供「按前缀授权」选项(只许单次确认)
|
|
82
|
+
* - matchesSavedPrefix 即便命中已存前缀也不放行(纵深防御,治存量配置)
|
|
83
|
+
*
|
|
84
|
+
* 涵盖:含重定向 / 危险首词(rm、sudo、mv 等)/ find 危险 flag。
|
|
85
|
+
*/
|
|
86
|
+
function isUnsafeForPrefixAuth(command) {
|
|
87
|
+
return hasRedirection(command) || hasDangerousCommand(command);
|
|
88
|
+
}
|
|
89
|
+
function isReadonlySafeSubcommand(seg) {
|
|
90
|
+
const s = seg.trim();
|
|
91
|
+
if (!s || REDIRECTION_RE.test(s))
|
|
92
|
+
return false;
|
|
93
|
+
const first = s.split(/\s+/)[0];
|
|
94
|
+
if (!READONLY_COMMANDS.has(first))
|
|
95
|
+
return false;
|
|
96
|
+
if (first === 'find' && DANGEROUS_FIND_FLAGS.test(s))
|
|
97
|
+
return false;
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* 整条命令是否可判定为「只读安全」,可直接放行(无需人工/模型)。
|
|
102
|
+
* 基于 splitCommand 的分词逐子命令判定,从根本上消除「整串 split(' ')[0]」带来的
|
|
103
|
+
* 重定向 / 不带空格管道 / find 等绕过:
|
|
104
|
+
* - 含 && || ; ` $( 换行 → 交上层逐子命令或人工,这里不放行
|
|
105
|
+
* - 含管道时,要求每一段首词都在只读集合且段内无重定向
|
|
106
|
+
*/
|
|
107
|
+
function isReadonlySafeCommand(command) {
|
|
108
|
+
const trimmed = command.trim();
|
|
109
|
+
if (SAFE_FULL_COMMANDS.has(trimmed))
|
|
110
|
+
return true;
|
|
111
|
+
if ((0, commands_1.hasCommandInjection)(command))
|
|
112
|
+
return false;
|
|
113
|
+
let segs;
|
|
114
|
+
try {
|
|
115
|
+
segs = (0, commands_1.splitCommand)(command);
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
return segs.length > 0 && segs.every(isReadonlySafeSubcommand);
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=shellSafety.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shellSafety.js","sourceRoot":"","sources":["../../src/util/shellSafety.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shellSafety.test.d.ts","sourceRoot":"","sources":["../../src/util/shellSafety.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const node_test_1 = require("node:test");
|
|
7
|
+
const strict_1 = __importDefault(require("node:assert/strict"));
|
|
8
|
+
const shellSafety_1 = require("./shellSafety");
|
|
9
|
+
(0, node_test_1.test)('正常只读命令放行', () => {
|
|
10
|
+
for (const c of [
|
|
11
|
+
'ls -la /tmp', 'cat README.md', 'grep -r foo .',
|
|
12
|
+
'pwd', 'git status', 'git diff', 'head -n5 a.txt',
|
|
13
|
+
'ls | grep x | wc -l',
|
|
14
|
+
]) {
|
|
15
|
+
strict_1.default.equal((0, shellSafety_1.isReadonlySafeCommand)(c), true, c);
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
(0, node_test_1.test)('回归: echo/cat 重定向写文件不得放行', () => {
|
|
19
|
+
strict_1.default.equal((0, shellSafety_1.isReadonlySafeCommand)('echo evil > ~/.ssh/authorized_keys'), false);
|
|
20
|
+
strict_1.default.equal((0, shellSafety_1.isReadonlySafeCommand)('echo x >> /etc/hosts'), false);
|
|
21
|
+
strict_1.default.equal((0, shellSafety_1.isReadonlySafeCommand)('cat secret > /etc/passwd'), false);
|
|
22
|
+
strict_1.default.equal((0, shellSafety_1.isReadonlySafeCommand)('echo x 2> /tmp/y'), false);
|
|
23
|
+
});
|
|
24
|
+
(0, node_test_1.test)('回归: 不带空格的管道不得绕过', () => {
|
|
25
|
+
strict_1.default.equal((0, shellSafety_1.isReadonlySafeCommand)('cat foo|rm -rf /'), false);
|
|
26
|
+
strict_1.default.equal((0, shellSafety_1.isReadonlySafeCommand)('ls|rm -rf .'), false);
|
|
27
|
+
});
|
|
28
|
+
(0, node_test_1.test)('回归: 带空格的管道含危险段不得放行', () => {
|
|
29
|
+
strict_1.default.equal((0, shellSafety_1.isReadonlySafeCommand)('find . | rm -rf /'), false);
|
|
30
|
+
strict_1.default.equal((0, shellSafety_1.isReadonlySafeCommand)('cat a | sh'), false);
|
|
31
|
+
});
|
|
32
|
+
(0, node_test_1.test)('find: 只读用法放行', () => {
|
|
33
|
+
strict_1.default.equal((0, shellSafety_1.isReadonlySafeCommand)('find . -name x'), true);
|
|
34
|
+
strict_1.default.equal((0, shellSafety_1.isReadonlySafeCommand)('find . -type f -mtime -1'), true);
|
|
35
|
+
strict_1.default.equal((0, shellSafety_1.isReadonlySafeCommand)('find src | grep ts'), true);
|
|
36
|
+
});
|
|
37
|
+
(0, node_test_1.test)('回归: find 危险 flag 不放行', () => {
|
|
38
|
+
strict_1.default.equal((0, shellSafety_1.isReadonlySafeCommand)('find . -delete'), false);
|
|
39
|
+
strict_1.default.equal((0, shellSafety_1.isReadonlySafeCommand)('find . -type f -exec rm {} +'), false);
|
|
40
|
+
strict_1.default.equal((0, shellSafety_1.isReadonlySafeCommand)('find . -execdir sh -c "rm" {} ;'), false);
|
|
41
|
+
strict_1.default.equal((0, shellSafety_1.isReadonlySafeCommand)('find . -ok rm {} +'), false);
|
|
42
|
+
strict_1.default.equal((0, shellSafety_1.isReadonlySafeCommand)('find . -fprintf /etc/x %p'), false);
|
|
43
|
+
});
|
|
44
|
+
(0, node_test_1.test)('链式命令交由上层逐子命令处理, 这里不放行', () => {
|
|
45
|
+
strict_1.default.equal((0, shellSafety_1.isReadonlySafeCommand)('ls && rm -rf /'), false);
|
|
46
|
+
strict_1.default.equal((0, shellSafety_1.isReadonlySafeCommand)('ls; rm -rf /'), false);
|
|
47
|
+
strict_1.default.equal((0, shellSafety_1.isReadonlySafeCommand)('ls;rm -rf /'), false);
|
|
48
|
+
});
|
|
49
|
+
(0, node_test_1.test)('命令注入字符不放行', () => {
|
|
50
|
+
strict_1.default.equal((0, shellSafety_1.isReadonlySafeCommand)('echo $(rm -rf /)'), false);
|
|
51
|
+
strict_1.default.equal((0, shellSafety_1.isReadonlySafeCommand)('cat `id`'), false);
|
|
52
|
+
});
|
|
53
|
+
(0, node_test_1.test)('非白名单命令不放行', () => {
|
|
54
|
+
strict_1.default.equal((0, shellSafety_1.isReadonlySafeCommand)('rm -rf /'), false);
|
|
55
|
+
strict_1.default.equal((0, shellSafety_1.isReadonlySafeCommand)('git push'), false);
|
|
56
|
+
strict_1.default.equal((0, shellSafety_1.isReadonlySafeCommand)('curl http://x'), false);
|
|
57
|
+
});
|
|
58
|
+
(0, node_test_1.test)('hasRedirection 识别各类重定向(含无空格)', () => {
|
|
59
|
+
for (const c of [
|
|
60
|
+
'echo x > /etc/passwd', 'echo x >> a', 'cat a < b',
|
|
61
|
+
'echo x 2> e.log', 'cmd &> all.log', 'echo x >| f',
|
|
62
|
+
'echo evil>/tmp/x', 'echo x>>a', 'echo a; echo b>f', // 无空格 / 链中重定向
|
|
63
|
+
]) {
|
|
64
|
+
strict_1.default.equal((0, shellSafety_1.hasRedirection)(c), true, c);
|
|
65
|
+
}
|
|
66
|
+
for (const c of ['echo x', 'ls -la', 'npm run build']) {
|
|
67
|
+
strict_1.default.equal((0, shellSafety_1.hasRedirection)(c), false, c);
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
(0, node_test_1.test)('isUnsafeForPrefixAuth: 危险命令不可前缀授权', () => {
|
|
71
|
+
for (const c of [
|
|
72
|
+
'rm -rf /', 'rm file', 'rmdir d', 'sudo apt install x', 'su -',
|
|
73
|
+
'dd if=/dev/zero of=/dev/sda', 'mkfs.ext4 /dev/sda1', 'shred f',
|
|
74
|
+
'chmod 777 /etc', 'chown root f', 'kill -9 1', 'pkill node',
|
|
75
|
+
'mv a /etc/b', 'truncate -s0 f',
|
|
76
|
+
'find . -delete', 'find . -exec rm {} +', // find 危险 flag
|
|
77
|
+
'echo x > f', 'cat a|rm -rf b', // 重定向 / 链中危险段
|
|
78
|
+
]) {
|
|
79
|
+
strict_1.default.equal((0, shellSafety_1.isUnsafeForPrefixAuth)(c), true, c);
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
(0, node_test_1.test)('hasDangerousCommand: 语义危险命令直接转人工(AutoRun 不调模型)', () => {
|
|
83
|
+
// 危险首词 / find 危险 flag / 链中危险段 → true
|
|
84
|
+
for (const c of [
|
|
85
|
+
'rm -rf /', 'sudo apt install x', 'mv a /etc/b', 'kill -9 1',
|
|
86
|
+
'find . -delete', 'find . -exec rm {} +', 'cat a|rm -rf b',
|
|
87
|
+
]) {
|
|
88
|
+
strict_1.default.equal((0, shellSafety_1.hasDangerousCommand)(c), true, c);
|
|
89
|
+
}
|
|
90
|
+
// 纯重定向不算「语义危险」(路径安全性交模型判) → false
|
|
91
|
+
for (const c of ['echo x > /tmp/f', 'echo hi', 'npm run build', 'find . -name x']) {
|
|
92
|
+
strict_1.default.equal((0, shellSafety_1.hasDangerousCommand)(c), false, c);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
(0, node_test_1.test)('isUnsafeForPrefixAuth: 普通命令可前缀授权', () => {
|
|
96
|
+
for (const c of [
|
|
97
|
+
'npm run build', 'cargo test', 'git commit -m msg', 'echo hello',
|
|
98
|
+
'ls -la', 'find . -name x', 'docker ps', 'python script.py',
|
|
99
|
+
]) {
|
|
100
|
+
strict_1.default.equal((0, shellSafety_1.isUnsafeForPrefixAuth)(c), false, c);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
//# sourceMappingURL=shellSafety.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shellSafety.test.js","sourceRoot":"","sources":["../../src/util/shellSafety.test.ts"],"names":[],"mappings":"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"}
|