@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
|
@@ -953,7 +953,11 @@ var init_logic_rules = __esm({
|
|
|
953
953
|
// SSH 主机私钥(排除 .pub 公钥变体,对齐 Python .ssh/id_rsa(?!\.pub) 范式)
|
|
954
954
|
{ path: "/etc/ssh/ssh_host_rsa_key(?!\\.pub)", riskLevel: "critical", desc: "SSH \u4E3B\u673A RSA \u79C1\u94A5", credential: true },
|
|
955
955
|
{ path: "/etc/ssh/ssh_host_ed25519_key(?!\\.pub)", riskLevel: "critical", desc: "SSH \u4E3B\u673A Ed25519 \u79C1\u94A5", credential: true },
|
|
956
|
-
{ path: "/etc/ssh/ssh_host_ecdsa_key(?!\\.pub)", riskLevel: "critical", desc: "SSH \u4E3B\u673A ECDSA \u79C1\u94A5", credential: true }
|
|
956
|
+
{ path: "/etc/ssh/ssh_host_ecdsa_key(?!\\.pub)", riskLevel: "critical", desc: "SSH \u4E3B\u673A ECDSA \u79C1\u94A5", credential: true },
|
|
957
|
+
// Nginx 配置(仅拦截写入,对齐 Python linux.py sensitive_paths)
|
|
958
|
+
{ path: "/etc/nginx/nginx.conf", riskLevel: "high", desc: "Nginx \u4E3B\u914D\u7F6E" },
|
|
959
|
+
{ path: "/etc/nginx/conf.d/", riskLevel: "high", desc: "Nginx \u5B50\u914D\u7F6E\u76EE\u5F55" },
|
|
960
|
+
{ path: "/etc/nginx/sites-enabled/", riskLevel: "high", desc: "Nginx \u542F\u7528\u7AD9\u70B9\u914D\u7F6E\u76EE\u5F55" }
|
|
957
961
|
];
|
|
958
962
|
HOME_SENSITIVE_PATHS = [
|
|
959
963
|
{ path: ".ssh/id_rsa", riskLevel: "critical", desc: "SSH \u79C1\u94A5", credential: true },
|
|
@@ -2288,7 +2292,7 @@ function runHeuristicCheck(input) {
|
|
|
2288
2292
|
}
|
|
2289
2293
|
}
|
|
2290
2294
|
}
|
|
2291
|
-
const injectionText = `${input.aNext.actionType} ${input.aNext.actionDetail} ${input.reason || ""} ${input.promptSession || ""}`.toLowerCase();
|
|
2295
|
+
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();
|
|
2292
2296
|
const injectionHits = checkInjectionKeywords(injectionText, agentExt?.extra_injection_keywords);
|
|
2293
2297
|
if (injectionHits.length > 0) {
|
|
2294
2298
|
const topHit = injectionHits.reduce((a, b) => severityRank(a.riskLevel) >= severityRank(b.riskLevel) ? a : b);
|
|
@@ -2364,6 +2368,12 @@ function stripLiteralTextSegments(actionDetail) {
|
|
|
2364
2368
|
}
|
|
2365
2369
|
return resultParts.join("");
|
|
2366
2370
|
}
|
|
2371
|
+
function stripHeredocContent(actionDetail) {
|
|
2372
|
+
return actionDetail.replace(
|
|
2373
|
+
/<<-?\s*(?:['"]?)([A-Za-z_][A-Za-z0-9_]*)(?:['"]?)[^\n]*\n[\s\S]*?\n\s*\1\s*(?:\n|$)/g,
|
|
2374
|
+
"<<heredoc>>\n"
|
|
2375
|
+
);
|
|
2376
|
+
}
|
|
2367
2377
|
function splitCommandSegments(actionDetail) {
|
|
2368
2378
|
const segments = [];
|
|
2369
2379
|
let cur = "";
|
|
@@ -2409,6 +2419,10 @@ function severityRank(s) {
|
|
|
2409
2419
|
const ranks = { low: 1, medium: 2, high: 3, critical: 4 };
|
|
2410
2420
|
return ranks[s] || 0;
|
|
2411
2421
|
}
|
|
2422
|
+
function isSearchActionType(actionType) {
|
|
2423
|
+
const at = actionType.toLowerCase();
|
|
2424
|
+
return SEARCH_ACTION_PREFIXES.some((p) => at.startsWith(p)) || ["websearch", "web_search", "search", "query"].includes(at);
|
|
2425
|
+
}
|
|
2412
2426
|
function checkSensitivePath(command, cwd, agentExt) {
|
|
2413
2427
|
const expandedCwd = cwd.replace(/^~/, process.env.HOME || "/home/user");
|
|
2414
2428
|
const isWriteOpFlag = isWriteOperation("", command);
|
|
@@ -2528,11 +2542,13 @@ function checkSensitivePath(command, cwd, agentExt) {
|
|
|
2528
2542
|
}
|
|
2529
2543
|
function checkDangerousPatterns(actionType, actionDetail) {
|
|
2530
2544
|
if (actionType === "file_write" || actionType === "file_edit") return null;
|
|
2545
|
+
const scan = stripHeredocContent(actionDetail);
|
|
2531
2546
|
const TEMP_DIRS = ["/tmp", "/var/tmp", "/run", "/dev/shm"];
|
|
2532
2547
|
const isTempPath = TEMP_DIRS.some(
|
|
2533
2548
|
(td) => new RegExp(`(?:^|[\\s/])${td.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}(?:[\\s/]|$)`).test(actionDetail)
|
|
2534
2549
|
);
|
|
2535
|
-
|
|
2550
|
+
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;
|
|
2551
|
+
if (!isTempPath && wildcardDeleteRe.test(scan)) {
|
|
2536
2552
|
return {
|
|
2537
2553
|
allowed: false,
|
|
2538
2554
|
reason: "\u68C0\u6D4B\u5230\u901A\u914D\u7B26\u7ED3\u5408\u5220\u9664\u64CD\u4F5C\uFF0C\u53EF\u80FD\u9020\u6210\u6279\u91CF\u8BEF\u5220",
|
|
@@ -2674,7 +2690,7 @@ function checkLateralMovement(actionDetail) {
|
|
|
2674
2690
|
}
|
|
2675
2691
|
return null;
|
|
2676
2692
|
}
|
|
2677
|
-
var INJECTION_KEYWORDS, DANGEROUS_PATTERNS, SENSITIVE_EXCLUDED_PREFIXES;
|
|
2693
|
+
var INJECTION_KEYWORDS, DANGEROUS_PATTERNS, SENSITIVE_EXCLUDED_PREFIXES, SEARCH_ACTION_PREFIXES;
|
|
2678
2694
|
var init_heuristic = __esm({
|
|
2679
2695
|
"src/engine/heuristic.ts"() {
|
|
2680
2696
|
"use strict";
|
|
@@ -2795,7 +2811,10 @@ var init_heuristic = __esm({
|
|
|
2795
2811
|
{ pattern: />\s*\/boot\//i, severity: "critical", description: "\u8986\u76D6\u5199\u5165\u542F\u52A8\u5F15\u5BFC\u76EE\u5F55", riskType: "file_access" },
|
|
2796
2812
|
// 注:/proc/ 重定向覆盖走 checkSensitivePath 的 high(内核参数 /proc/sys/),此处不拦 /proc/ 避免遮蔽(对齐 Python)。
|
|
2797
2813
|
// --- High: download script + execute risk ---
|
|
2814
|
+
// curl -X POST 外传敏感信息(对齐 Python linux.py: curl POST env/key/token)
|
|
2815
|
+
{ 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" },
|
|
2798
2816
|
{ 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" },
|
|
2817
|
+
{ 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" },
|
|
2799
2818
|
{ pattern: /(?:curl|wget)\s+.*\s+&&?\s*(?:chmod\s+\+x|bash|sh)/i, severity: "high", description: "\u4E0B\u8F7D\u540E\u6267\u884C", riskType: "script_execution" },
|
|
2800
2819
|
// --- High: package manager pipe-to-shell ---
|
|
2801
2820
|
{ pattern: /git\s+clone\s+.*\|.*bash/i, severity: "high", description: "git clone pipe shell", riskType: "script_execution" },
|
|
@@ -2837,6 +2856,7 @@ var init_heuristic = __esm({
|
|
|
2837
2856
|
{ 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" }
|
|
2838
2857
|
];
|
|
2839
2858
|
SENSITIVE_EXCLUDED_PREFIXES = ["memory-", "skill-", "skill-manager-", "mailbox-", "app-"];
|
|
2859
|
+
SEARCH_ACTION_PREFIXES = ["search-", "web-", "browser-", "query-", "websearch", "web_search"];
|
|
2840
2860
|
}
|
|
2841
2861
|
});
|
|
2842
2862
|
|