@kenhkl/agent-moss 0.11.3 → 0.11.5
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/cli.js +24 -4
- package/dist/cli.js.map +1 -1
- package/dist/engine/coordinator.js +24 -4
- package/dist/engine/coordinator.js.map +1 -1
- package/dist/server.js +24 -4
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
package/dist/server.js
CHANGED
|
@@ -963,7 +963,11 @@ var init_logic_rules = __esm({
|
|
|
963
963
|
// SSH 主机私钥(排除 .pub 公钥变体,对齐 Python .ssh/id_rsa(?!\.pub) 范式)
|
|
964
964
|
{ path: "/etc/ssh/ssh_host_rsa_key(?!\\.pub)", riskLevel: "critical", desc: "SSH \u4E3B\u673A RSA \u79C1\u94A5", credential: true },
|
|
965
965
|
{ path: "/etc/ssh/ssh_host_ed25519_key(?!\\.pub)", riskLevel: "critical", desc: "SSH \u4E3B\u673A Ed25519 \u79C1\u94A5", credential: true },
|
|
966
|
-
{ path: "/etc/ssh/ssh_host_ecdsa_key(?!\\.pub)", riskLevel: "critical", desc: "SSH \u4E3B\u673A ECDSA \u79C1\u94A5", credential: true }
|
|
966
|
+
{ path: "/etc/ssh/ssh_host_ecdsa_key(?!\\.pub)", riskLevel: "critical", desc: "SSH \u4E3B\u673A ECDSA \u79C1\u94A5", credential: true },
|
|
967
|
+
// Nginx 配置(仅拦截写入,对齐 Python linux.py sensitive_paths)
|
|
968
|
+
{ path: "/etc/nginx/nginx.conf", riskLevel: "high", desc: "Nginx \u4E3B\u914D\u7F6E" },
|
|
969
|
+
{ path: "/etc/nginx/conf.d/", riskLevel: "high", desc: "Nginx \u5B50\u914D\u7F6E\u76EE\u5F55" },
|
|
970
|
+
{ path: "/etc/nginx/sites-enabled/", riskLevel: "high", desc: "Nginx \u542F\u7528\u7AD9\u70B9\u914D\u7F6E\u76EE\u5F55" }
|
|
967
971
|
];
|
|
968
972
|
HOME_SENSITIVE_PATHS = [
|
|
969
973
|
{ path: ".ssh/id_rsa", riskLevel: "critical", desc: "SSH \u79C1\u94A5", credential: true },
|
|
@@ -2298,7 +2302,7 @@ function runHeuristicCheck(input) {
|
|
|
2298
2302
|
}
|
|
2299
2303
|
}
|
|
2300
2304
|
}
|
|
2301
|
-
const injectionText = `${input.aNext.actionType} ${input.aNext.actionDetail} ${input.reason || ""} ${input.promptSession || ""}`.toLowerCase();
|
|
2305
|
+
const injectionText = isSearchActionType(input.aNext.actionType) ? `${input.aNext.actionType} ${input.reason || ""} ${input.promptSession || ""}`.toLowerCase() : `${input.aNext.actionType} ${input.aNext.actionDetail} ${input.reason || ""} ${input.promptSession || ""}`.toLowerCase();
|
|
2302
2306
|
const injectionHits = checkInjectionKeywords(injectionText, agentExt?.extra_injection_keywords);
|
|
2303
2307
|
if (injectionHits.length > 0) {
|
|
2304
2308
|
const topHit = injectionHits.reduce((a, b) => severityRank(a.riskLevel) >= severityRank(b.riskLevel) ? a : b);
|
|
@@ -2374,6 +2378,12 @@ function stripLiteralTextSegments(actionDetail) {
|
|
|
2374
2378
|
}
|
|
2375
2379
|
return resultParts.join("");
|
|
2376
2380
|
}
|
|
2381
|
+
function stripHeredocContent(actionDetail) {
|
|
2382
|
+
return actionDetail.replace(
|
|
2383
|
+
/<<-?\s*(?:['"]?)([A-Za-z_][A-Za-z0-9_]*)(?:['"]?)[^\n]*\n[\s\S]*?\n\s*\1\s*(?:\n|$)/g,
|
|
2384
|
+
"<<heredoc>>\n"
|
|
2385
|
+
);
|
|
2386
|
+
}
|
|
2377
2387
|
function splitCommandSegments(actionDetail) {
|
|
2378
2388
|
const segments = [];
|
|
2379
2389
|
let cur = "";
|
|
@@ -2419,6 +2429,10 @@ function severityRank(s) {
|
|
|
2419
2429
|
const ranks = { low: 1, medium: 2, high: 3, critical: 4 };
|
|
2420
2430
|
return ranks[s] || 0;
|
|
2421
2431
|
}
|
|
2432
|
+
function isSearchActionType(actionType) {
|
|
2433
|
+
const at = actionType.toLowerCase();
|
|
2434
|
+
return SEARCH_ACTION_PREFIXES.some((p) => at.startsWith(p)) || ["websearch", "web_search", "search", "query"].includes(at);
|
|
2435
|
+
}
|
|
2422
2436
|
function checkSensitivePath(command, cwd, agentExt) {
|
|
2423
2437
|
const expandedCwd = cwd.replace(/^~/, process.env.HOME || "/home/user");
|
|
2424
2438
|
const isWriteOpFlag = isWriteOperation("", command);
|
|
@@ -2538,11 +2552,13 @@ function checkSensitivePath(command, cwd, agentExt) {
|
|
|
2538
2552
|
}
|
|
2539
2553
|
function checkDangerousPatterns(actionType, actionDetail) {
|
|
2540
2554
|
if (actionType === "file_write" || actionType === "file_edit") return null;
|
|
2555
|
+
const scan = stripHeredocContent(actionDetail);
|
|
2541
2556
|
const TEMP_DIRS = ["/tmp", "/var/tmp", "/run", "/dev/shm"];
|
|
2542
2557
|
const isTempPath = TEMP_DIRS.some(
|
|
2543
2558
|
(td) => new RegExp(`(?:^|[\\s/])${td.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}(?:[\\s/]|$)`).test(actionDetail)
|
|
2544
2559
|
);
|
|
2545
|
-
|
|
2560
|
+
const wildcardDeleteRe = /(?:\brm\b|\b(r?mdir|del|delete|remove|rmdir|unlink)\b|\b删除\b|\b移除\b)[\s\S]{0,40}?[*?]|[*?][\s\S]{0,40}?\b(?:rm|del|delete|remove|rmdir|unlink)\b|rm\s+-[a-zA-Z]*[rf][a-zA-Z]*\s+\S*[*?]/i;
|
|
2561
|
+
if (!isTempPath && wildcardDeleteRe.test(scan)) {
|
|
2546
2562
|
return {
|
|
2547
2563
|
allowed: false,
|
|
2548
2564
|
reason: "\u68C0\u6D4B\u5230\u901A\u914D\u7B26\u7ED3\u5408\u5220\u9664\u64CD\u4F5C\uFF0C\u53EF\u80FD\u9020\u6210\u6279\u91CF\u8BEF\u5220",
|
|
@@ -2684,7 +2700,7 @@ function checkLateralMovement(actionDetail) {
|
|
|
2684
2700
|
}
|
|
2685
2701
|
return null;
|
|
2686
2702
|
}
|
|
2687
|
-
var INJECTION_KEYWORDS, DANGEROUS_PATTERNS, SENSITIVE_EXCLUDED_PREFIXES;
|
|
2703
|
+
var INJECTION_KEYWORDS, DANGEROUS_PATTERNS, SENSITIVE_EXCLUDED_PREFIXES, SEARCH_ACTION_PREFIXES;
|
|
2688
2704
|
var init_heuristic = __esm({
|
|
2689
2705
|
"src/engine/heuristic.ts"() {
|
|
2690
2706
|
"use strict";
|
|
@@ -2805,7 +2821,10 @@ var init_heuristic = __esm({
|
|
|
2805
2821
|
{ pattern: />\s*\/boot\//i, severity: "critical", description: "\u8986\u76D6\u5199\u5165\u542F\u52A8\u5F15\u5BFC\u76EE\u5F55", riskType: "file_access" },
|
|
2806
2822
|
// 注:/proc/ 重定向覆盖走 checkSensitivePath 的 high(内核参数 /proc/sys/),此处不拦 /proc/ 避免遮蔽(对齐 Python)。
|
|
2807
2823
|
// --- High: download script + execute risk ---
|
|
2824
|
+
// curl -X POST 外传敏感信息(对齐 Python linux.py: curl POST env/key/token)
|
|
2825
|
+
{ pattern: /curl\s+.*-X\s+POST.*\b(env|environment|secret|key|token|password)\b/i, severity: "high", description: "\u68C0\u6D4B\u5230\u901A\u8FC7 curl POST \u5916\u4F20\u53EF\u80FD\u5305\u542B\u654F\u611F\u4FE1\u606F\u7684\u8BF7\u6C42", riskType: "data_exfiltration" },
|
|
2808
2826
|
{ pattern: /(?:curl|wget)\s+.*(?:-o|--output|>)\s*\S+\.(?:sh|bash)\b/i, severity: "high", description: "\u8FDC\u7A0B\u4E0B\u8F7D\u811A\u672C\u5230\u672C\u5730", riskType: "script_execution" },
|
|
2827
|
+
{ pattern: /(?:curl|wget)\s+\S+.*\b(?:chmod|chown)\s+\+x\b/i, severity: "high", description: "\u8FDC\u7A0B\u4E0B\u8F7D\u540E\u4FEE\u6539\u53EF\u6267\u884C\u6743\u9650\uFF0C\u5B58\u5728\u8FDC\u7A0B\u4EE3\u7801\u6267\u884C\u98CE\u9669", riskType: "script_execution" },
|
|
2809
2828
|
{ pattern: /(?:curl|wget)\s+.*\s+&&?\s*(?:chmod\s+\+x|bash|sh)/i, severity: "high", description: "\u4E0B\u8F7D\u540E\u6267\u884C", riskType: "script_execution" },
|
|
2810
2829
|
// --- High: package manager pipe-to-shell ---
|
|
2811
2830
|
{ pattern: /git\s+clone\s+.*\|.*bash/i, severity: "high", description: "git clone pipe shell", riskType: "script_execution" },
|
|
@@ -2847,6 +2866,7 @@ var init_heuristic = __esm({
|
|
|
2847
2866
|
{ pattern: /\b(useradd|luseradd|groupadd|usermod|lusermod|groupmod|lgroupmod)\b[^&|;]*?\s-p\b/i, severity: "high", description: "\u68C0\u6D4B\u5230\u901A\u8FC7 -p \u53C2\u6570\u8BBE\u7F6E\u6216\u4FEE\u6539\u5BC6\u7801 (useradd/usermod/groupmod)", riskType: "script_execution" }
|
|
2848
2867
|
];
|
|
2849
2868
|
SENSITIVE_EXCLUDED_PREFIXES = ["memory-", "skill-", "skill-manager-", "mailbox-", "app-"];
|
|
2869
|
+
SEARCH_ACTION_PREFIXES = ["search-", "web-", "browser-", "query-", "websearch", "web_search"];
|
|
2850
2870
|
}
|
|
2851
2871
|
});
|
|
2852
2872
|
|