@kenhkl/agent-moss 0.7.5 → 0.7.8
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 +228 -28
- package/dist/cli.js.map +1 -1
- package/dist/skills/browser_web_access_guard.md +31 -0
- package/dist/skills/data_exfiltration_guard.md +33 -0
- package/dist/skills/email_operation_guard.md +30 -0
- package/dist/skills/file_access_guard.md +33 -0
- package/dist/skills/general_tool_risk_guard.md +33 -0
- package/dist/skills/intent_deviation_guard.md +39 -0
- package/dist/skills/lateral_movement_guard.md +31 -0
- package/dist/skills/persistence_backdoor_guard.md +32 -0
- package/dist/skills/resource_exhaustion_guard.md +32 -0
- package/dist/skills/script_execution_guard.md +37 -0
- package/dist/skills/skill_installation_guard.md +30 -0
- package/dist/skills/supply_chain_guard.md +31 -0
- package/dist/templates/policy_mapping.md +87 -0
- package/dist/templates/prompt1_template.txt +62 -0
- package/dist/templates/prompt2_template.txt +45 -0
- package/dist/templates/security_judge_template.txt +71 -0
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -154,7 +154,7 @@ function isHeuristicEnabled() {
|
|
|
154
154
|
function isLogicRulesEnabled() {
|
|
155
155
|
return process.env.AGENT_MOSS_DISABLE_LOGIC_RULES !== "1";
|
|
156
156
|
}
|
|
157
|
-
var
|
|
157
|
+
var timeoutConfig, retryConfig, llmConfig, customRules, PROVIDER_HEADERS;
|
|
158
158
|
var init_config = __esm({
|
|
159
159
|
"src/config.ts"() {
|
|
160
160
|
"use strict";
|
|
@@ -596,7 +596,7 @@ function checkSensitivePath(command, cwd) {
|
|
|
596
596
|
}
|
|
597
597
|
for (const cp of CREDENTIAL_PATHS) {
|
|
598
598
|
const escaped = cp.path.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
599
|
-
const re = cp.path.startsWith(".") ? new RegExp(`(?:^|[\\s/\\\\])${escaped}\\b`) : new RegExp(`\\b${escaped}\\b`);
|
|
599
|
+
const re = cp.path.startsWith(".") ? new RegExp(`(?:^|[\\s/\\\\'"])${escaped}\\b`) : new RegExp(`\\b${escaped}\\b`);
|
|
600
600
|
if (re.test(command)) {
|
|
601
601
|
return {
|
|
602
602
|
allowed: false,
|
|
@@ -605,7 +605,8 @@ function checkSensitivePath(command, cwd) {
|
|
|
605
605
|
riskType: "sensitive_path_access",
|
|
606
606
|
confidence: 90,
|
|
607
607
|
source: "logic_rule",
|
|
608
|
-
violatedLayers: ["2"]
|
|
608
|
+
violatedLayers: ["2"],
|
|
609
|
+
isCredential: true
|
|
609
610
|
};
|
|
610
611
|
}
|
|
611
612
|
}
|
|
@@ -740,6 +741,170 @@ var init_logic_rules = __esm({
|
|
|
740
741
|
}
|
|
741
742
|
});
|
|
742
743
|
|
|
744
|
+
// src/engine/inline-analyzer.ts
|
|
745
|
+
function isLiteralTextCommand(command) {
|
|
746
|
+
ECHO_CMD_RE.lastIndex = 0;
|
|
747
|
+
return ECHO_CMD_RE.test(command);
|
|
748
|
+
}
|
|
749
|
+
function extractInlineCode(command) {
|
|
750
|
+
const parts = [];
|
|
751
|
+
let m;
|
|
752
|
+
INLINE_CODE_RE.lastIndex = 0;
|
|
753
|
+
while ((m = INLINE_CODE_RE.exec(command)) !== null) {
|
|
754
|
+
const code = m[1] ?? m[2];
|
|
755
|
+
if (code) parts.push(code);
|
|
756
|
+
}
|
|
757
|
+
ECHO_STRING_RE.lastIndex = 0;
|
|
758
|
+
while ((m = ECHO_STRING_RE.exec(command)) !== null) {
|
|
759
|
+
const code = m[1] ?? m[2];
|
|
760
|
+
if (code) parts.push(code);
|
|
761
|
+
}
|
|
762
|
+
return parts.join("\n");
|
|
763
|
+
}
|
|
764
|
+
function hasWriteExecChain(command) {
|
|
765
|
+
return WRITE_EXEC_CHAIN_PATTERNS.some((p) => {
|
|
766
|
+
p.lastIndex = 0;
|
|
767
|
+
return p.test(command);
|
|
768
|
+
});
|
|
769
|
+
}
|
|
770
|
+
function hasReadWriteKeyword(code) {
|
|
771
|
+
const lower = code.toLowerCase();
|
|
772
|
+
return READ_WRITE_KEYWORDS.some((kw) => lower.includes(kw));
|
|
773
|
+
}
|
|
774
|
+
function analyzeInlineScript(command) {
|
|
775
|
+
const code = extractInlineCode(command);
|
|
776
|
+
if (!code) {
|
|
777
|
+
return { actionable: false, allowed: true, reason: "", riskLevel: "low", riskType: "" };
|
|
778
|
+
}
|
|
779
|
+
if (hasWriteExecChain(command)) {
|
|
780
|
+
return {
|
|
781
|
+
actionable: true,
|
|
782
|
+
allowed: false,
|
|
783
|
+
reason: "\u5185\u8054\u811A\u672C\u542B\u5199\u5165\u6587\u4EF6\u540E\u6267\u884C\u7684\u6A21\u5F0F\uFF0C\u7591\u4F3C\u7ED5\u8FC7\u654F\u611F\u8DEF\u5F84\u68C0\u6D4B",
|
|
784
|
+
riskLevel: "critical",
|
|
785
|
+
riskType: "script_execution"
|
|
786
|
+
};
|
|
787
|
+
}
|
|
788
|
+
const redirMatch = command.match(REDIRECT_TO_SENSITIVE_RE);
|
|
789
|
+
if (redirMatch) {
|
|
790
|
+
return {
|
|
791
|
+
actionable: true,
|
|
792
|
+
allowed: false,
|
|
793
|
+
reason: `\u91CD\u5B9A\u5411\u5199\u5165\u654F\u611F\u8DEF\u5F84: ${redirMatch[1]}`,
|
|
794
|
+
riskLevel: "critical",
|
|
795
|
+
riskType: "file_access"
|
|
796
|
+
};
|
|
797
|
+
}
|
|
798
|
+
const isEchoOrPrintf = isLiteralTextCommand(command);
|
|
799
|
+
if (!isEchoOrPrintf && hasReadWriteKeyword(code)) {
|
|
800
|
+
return {
|
|
801
|
+
actionable: true,
|
|
802
|
+
allowed: false,
|
|
803
|
+
reason: "\u5185\u8054\u811A\u672C\u542B\u654F\u611F\u8DEF\u5F84\u4E14\u542B\u6587\u4EF6\u8BFB\u5199/\u547D\u4EE4\u6267\u884C\u8C03\u7528\uFF0C\u5224\u4E3A\u771F\u5B9E\u8BBF\u95EE",
|
|
804
|
+
riskLevel: "critical",
|
|
805
|
+
riskType: "file_access"
|
|
806
|
+
};
|
|
807
|
+
}
|
|
808
|
+
return {
|
|
809
|
+
actionable: true,
|
|
810
|
+
allowed: true,
|
|
811
|
+
reason: "\u654F\u611F\u8DEF\u5F84\u4EC5\u4F5C\u4E3A\u6587\u672C\u5B57\u9762\u91CF\u51FA\u73B0\uFF0C\u672A\u4F34\u968F\u8BFB\u5199\u64CD\u4F5C",
|
|
812
|
+
riskLevel: "low",
|
|
813
|
+
riskType: "file_access"
|
|
814
|
+
};
|
|
815
|
+
}
|
|
816
|
+
var INLINE_CODE_RE, ECHO_STRING_RE, ECHO_CMD_RE, READ_WRITE_KEYWORDS, WRITE_EXEC_CHAIN_PATTERNS, SENSITIVE_PATH_FRAGMENTS, REDIRECT_TO_SENSITIVE_RE;
|
|
817
|
+
var init_inline_analyzer = __esm({
|
|
818
|
+
"src/engine/inline-analyzer.ts"() {
|
|
819
|
+
"use strict";
|
|
820
|
+
init_esm_shims();
|
|
821
|
+
INLINE_CODE_RE = /(?:python|python3|perl|perl5|ruby|jruby|mruby|node|php|lua)\s+(?:-[a-zA-Z]*[cera][a-zA-Z]*\s+)"([^"\\]*(?:\\.[^"\\]*)*)"|'([^'\\]*(?:\\.[^'\\]*)*)'/gi;
|
|
822
|
+
ECHO_STRING_RE = /\b(?:echo|printf)\s+"([^"\\]*(?:\\.[^"\\]*)*)"|\b(?:echo|printf)\s+'([^'\\]*(?:\\.[^'\\]*)*)'/gi;
|
|
823
|
+
ECHO_CMD_RE = /(?:^|\s|;|&&|\|\|)(?:echo|printf)\s/gi;
|
|
824
|
+
READ_WRITE_KEYWORDS = [
|
|
825
|
+
// 函数调用形态(关键词后跟 '(')
|
|
826
|
+
"open(",
|
|
827
|
+
"read(",
|
|
828
|
+
"write(",
|
|
829
|
+
"fopen(",
|
|
830
|
+
"system(",
|
|
831
|
+
"exec(",
|
|
832
|
+
"eval(",
|
|
833
|
+
"popen(",
|
|
834
|
+
"load(",
|
|
835
|
+
"dump(",
|
|
836
|
+
// 文件读写(组合形态)
|
|
837
|
+
"readline",
|
|
838
|
+
"readlines",
|
|
839
|
+
"writelines",
|
|
840
|
+
"getpass",
|
|
841
|
+
"pickle.load",
|
|
842
|
+
"yaml.load",
|
|
843
|
+
"json.load",
|
|
844
|
+
"json.read",
|
|
845
|
+
"configparser",
|
|
846
|
+
"fread",
|
|
847
|
+
"fwrite",
|
|
848
|
+
"fgets",
|
|
849
|
+
// 子进程执行(组合形态)
|
|
850
|
+
"os.system",
|
|
851
|
+
"os.popen",
|
|
852
|
+
"subprocess",
|
|
853
|
+
"os.exec",
|
|
854
|
+
"os.spawn",
|
|
855
|
+
"import os",
|
|
856
|
+
"import subprocess",
|
|
857
|
+
"shell=true",
|
|
858
|
+
"check_output",
|
|
859
|
+
"check_call",
|
|
860
|
+
"run(",
|
|
861
|
+
// 绕过变体检测
|
|
862
|
+
"getattr(",
|
|
863
|
+
"__builtins__",
|
|
864
|
+
"globals(",
|
|
865
|
+
"locals(",
|
|
866
|
+
// PHP
|
|
867
|
+
"file_get_contents",
|
|
868
|
+
"file_put_contents",
|
|
869
|
+
"passthru",
|
|
870
|
+
"shell_exec",
|
|
871
|
+
"proc_open",
|
|
872
|
+
// Perl-Ruby
|
|
873
|
+
"<stdin>",
|
|
874
|
+
"open my"
|
|
875
|
+
];
|
|
876
|
+
WRITE_EXEC_CHAIN_PATTERNS = [
|
|
877
|
+
// echo/cat/printf "..." > file && bash/sh/python file
|
|
878
|
+
/(?:echo|cat|printf)\b.*?>\s*\S+.*(?:&&|;|\|)\s*(?:bash|sh|zsh|python\d?|perl|ruby|node|php)\s/gis,
|
|
879
|
+
// ... | bash / | sh / | python(管道喂解释器执行)
|
|
880
|
+
/\|\s*(?:bash|sh|zsh|python\d?|perl|ruby|node|php)\b/gi,
|
|
881
|
+
// eval "$(cat ...)" / eval "$(echo ...)"
|
|
882
|
+
/eval\s+"\$\(/gi,
|
|
883
|
+
// xargs bash / xargs sh
|
|
884
|
+
/\|\s*xargs\s+(?:bash|sh|zsh)/gi
|
|
885
|
+
];
|
|
886
|
+
SENSITIVE_PATH_FRAGMENTS = [
|
|
887
|
+
"/etc/shadow",
|
|
888
|
+
"/etc/gshadow",
|
|
889
|
+
"/etc/passwd",
|
|
890
|
+
"/etc/sudoers",
|
|
891
|
+
"/etc/hosts",
|
|
892
|
+
"/etc/crontab",
|
|
893
|
+
"/etc/systemd/",
|
|
894
|
+
"/etc/ssh/sshd_config",
|
|
895
|
+
"/boot/",
|
|
896
|
+
"/proc/sys/",
|
|
897
|
+
"/sys/",
|
|
898
|
+
"/dev/mem",
|
|
899
|
+
"/dev/kmsg",
|
|
900
|
+
".ssh/id_rsa",
|
|
901
|
+
".ssh/id_ed25519",
|
|
902
|
+
".ssh/authorized_keys"
|
|
903
|
+
];
|
|
904
|
+
REDIRECT_TO_SENSITIVE_RE = new RegExp(`>{1,2}\\s*(${SENSITIVE_PATH_FRAGMENTS.map((p) => p.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|")})`, "i");
|
|
905
|
+
}
|
|
906
|
+
});
|
|
907
|
+
|
|
743
908
|
// src/engine/skill-loader.ts
|
|
744
909
|
import { readFileSync, readdirSync, existsSync as existsSync2 } from "fs";
|
|
745
910
|
import { resolve, dirname } from "path";
|
|
@@ -747,16 +912,17 @@ import { fileURLToPath as fileURLToPath2 } from "url";
|
|
|
747
912
|
function loadAllSkills() {
|
|
748
913
|
if (cachedSkills) return cachedSkills;
|
|
749
914
|
cachedSkills = {};
|
|
750
|
-
|
|
751
|
-
|
|
915
|
+
const dir = existsSync2(SKILLS_DIR) ? SKILLS_DIR : SKILLS_DIR_FALLBACK;
|
|
916
|
+
if (!existsSync2(dir)) {
|
|
917
|
+
console.warn("[AgentMoss] Skills directory not found:", SKILLS_DIR, "and fallback:", SKILLS_DIR_FALLBACK);
|
|
752
918
|
return cachedSkills;
|
|
753
919
|
}
|
|
754
|
-
const files = readdirSync(
|
|
920
|
+
const files = readdirSync(dir).filter((f) => f.endsWith(".md"));
|
|
755
921
|
for (const f of files) {
|
|
756
922
|
const name = f.replace(".md", "");
|
|
757
|
-
cachedSkills[name] = readFileSync(resolve(
|
|
923
|
+
cachedSkills[name] = readFileSync(resolve(dir, f), "utf-8");
|
|
758
924
|
}
|
|
759
|
-
console.log(`[AgentMoss] Loaded ${Object.keys(cachedSkills).length} skills`);
|
|
925
|
+
console.log(`[AgentMoss] Loaded ${Object.keys(cachedSkills).length} skills from ${dir}`);
|
|
760
926
|
return cachedSkills;
|
|
761
927
|
}
|
|
762
928
|
function matchSkills(actionType, actionDetail, reason, maxSkills = 3) {
|
|
@@ -808,14 +974,15 @@ function formatSkillsForPrompt(skills) {
|
|
|
808
974
|
${s.skillContent}`
|
|
809
975
|
).join("\n\n---\n\n");
|
|
810
976
|
}
|
|
811
|
-
var __filename2, __dirname2, SKILLS_DIR, SKILL_KEYWORD_MAP, cachedSkills;
|
|
977
|
+
var __filename2, __dirname2, SKILLS_DIR, SKILLS_DIR_FALLBACK, SKILL_KEYWORD_MAP, cachedSkills;
|
|
812
978
|
var init_skill_loader = __esm({
|
|
813
979
|
"src/engine/skill-loader.ts"() {
|
|
814
980
|
"use strict";
|
|
815
981
|
init_esm_shims();
|
|
816
982
|
__filename2 = fileURLToPath2(import.meta.url);
|
|
817
983
|
__dirname2 = dirname(__filename2);
|
|
818
|
-
SKILLS_DIR = resolve(__dirname2, "
|
|
984
|
+
SKILLS_DIR = resolve(__dirname2, "../skills");
|
|
985
|
+
SKILLS_DIR_FALLBACK = resolve(__dirname2, "../../agent_moss/skills");
|
|
819
986
|
SKILL_KEYWORD_MAP = {
|
|
820
987
|
"file_access_guard": ["file", "\u6587\u4EF6", "path", "\u8DEF\u5F84", "read", "write", "cat", "open", "access", "\u8BBF\u95EE", "\u8BFB\u5199", "copy", "cp", "mv", "move"],
|
|
821
988
|
"script_execution_guard": ["command", "shell", "bash", "exec", "execute", "\u6267\u884C", "\u547D\u4EE4", "script", "\u811A\u672C", "run", "\u8FD0\u884C", "subprocess", "system", "eval", "compile", "\u5B89\u88C5", "install", "pip", "npm"],
|
|
@@ -825,7 +992,9 @@ var init_skill_loader = __esm({
|
|
|
825
992
|
"general_tool_risk_guard": ["tool", "\u5DE5\u5177", "api", "invoke", "\u8C03\u7528", "function", "\u51FD\u6570"],
|
|
826
993
|
"lateral_movement_guard": ["ssh", "scp", "ftp", "sftp", "rdp", "vnc", "telnet", "\u5185\u7F51", "\u6A2A\u5411", "tunnel", "\u4EE3\u7406", "proxy", "port", "\u7AEF\u53E3", "scan", "\u626B\u63CF", "ping", "traceroute", "nslookup"],
|
|
827
994
|
"persistence_backdoor_guard": ["cron", "crontab", "\u5B9A\u65F6", "scheduled", "startup", "\u542F\u52A8\u9879", "service", "\u670D\u52A1", "daemon", "\u5B88\u62A4", "registry", "\u6CE8\u518C\u8868", "backdoor", "\u540E\u95E8", "persist", "\u6301\u4E45\u5316", "authorized_keys", "bashrc", "zshrc", "profile", ".rc", "shell config", "shell \u914D\u7F6E"],
|
|
828
|
-
|
|
995
|
+
// 注意:避免裸 'memory'/'内存'/'dd'——会误命中 memory-addMemory(写记忆工具,
|
|
996
|
+
// 'dd' 是 'addMemory' 的子串)等无害操作。用组合词/命令前缀精准匹配攻击场景。
|
|
997
|
+
"resource_exhaustion_guard": ["fork", "bomb", "\u70B8\u5F39", "memory bomb", "oom", "out of memory", "\u5185\u5B58\u6EA2\u51FA", "\u5185\u5B58\u8017\u5C3D", "\u5185\u5B58\u6CC4\u6F0F", "disk", "\u78C1\u76D8", "cpu", "process", "\u8FDB\u7A0B", "dd if=", "/dev/zero", "/dev/null", "yes >", "while true", "\u65E0\u9650\u5FAA\u73AF", "\u8017\u5C3D", "exhaust", "\u8D44\u6E90"],
|
|
829
998
|
"skill_installation_guard": ["skill", "plugin", "\u63D2\u4EF6", "extension", "\u6269\u5C55", "install skill", "\u5B89\u88C5\u63D2\u4EF6", "\u5B89\u88C5\u6280\u80FD", "marketplace", "\u5546\u5E97"],
|
|
830
999
|
"supply_chain_guard": ["dependency", "\u4F9D\u8D56", "package", "\u5305", "npm install", "pip install", "requirements", "import", "library", "\u5E93", "registry", "\u4ED3\u5E93", "supply", "\u4F9B\u5E94\u94FE", "typosquatting"],
|
|
831
1000
|
"intent_deviation_guard": ["rm", "del", "delete", "remove", "\u5220\u9664", "format", "\u683C\u5F0F\u5316", "drop", "truncate", "\u6E05\u7A7A", "wipe", "\u64E6\u9664", "\u91CD\u7F6E", "reset", "sudo", "root", "admin", "\u7BA1\u7406\u5458", "privilege", "\u63D0\u6743"]
|
|
@@ -841,28 +1010,30 @@ import { fileURLToPath as fileURLToPath3 } from "url";
|
|
|
841
1010
|
function loadTemplates() {
|
|
842
1011
|
if (cachedTemplates) return cachedTemplates;
|
|
843
1012
|
cachedTemplates = {};
|
|
844
|
-
|
|
845
|
-
|
|
1013
|
+
const dir = existsSync3(TEMPLATES_DIR) ? TEMPLATES_DIR : TEMPLATES_DIR_FALLBACK;
|
|
1014
|
+
if (!existsSync3(dir)) {
|
|
1015
|
+
console.warn("[AgentMoss] Templates directory not found:", TEMPLATES_DIR, "and fallback:", TEMPLATES_DIR_FALLBACK);
|
|
846
1016
|
return cachedTemplates;
|
|
847
1017
|
}
|
|
848
1018
|
for (const file of TEMPLATE_FILES) {
|
|
849
|
-
const filePath = resolve2(
|
|
1019
|
+
const filePath = resolve2(dir, file);
|
|
850
1020
|
if (existsSync3(filePath)) {
|
|
851
1021
|
const key = file.replace(".txt", "").replace("_template", "");
|
|
852
1022
|
cachedTemplates[key] = readFileSync2(filePath, "utf-8");
|
|
853
1023
|
}
|
|
854
1024
|
}
|
|
855
|
-
console.log(`[AgentMoss] Loaded ${Object.keys(cachedTemplates).length} templates`);
|
|
1025
|
+
console.log(`[AgentMoss] Loaded ${Object.keys(cachedTemplates).length} templates from ${dir}`);
|
|
856
1026
|
return cachedTemplates;
|
|
857
1027
|
}
|
|
858
|
-
var __filename3, __dirname3, TEMPLATES_DIR, TEMPLATE_FILES, cachedTemplates;
|
|
1028
|
+
var __filename3, __dirname3, TEMPLATES_DIR, TEMPLATES_DIR_FALLBACK, TEMPLATE_FILES, cachedTemplates;
|
|
859
1029
|
var init_template_loader = __esm({
|
|
860
1030
|
"src/engine/template-loader.ts"() {
|
|
861
1031
|
"use strict";
|
|
862
1032
|
init_esm_shims();
|
|
863
1033
|
__filename3 = fileURLToPath3(import.meta.url);
|
|
864
1034
|
__dirname3 = dirname2(__filename3);
|
|
865
|
-
TEMPLATES_DIR = resolve2(__dirname3, "
|
|
1035
|
+
TEMPLATES_DIR = resolve2(__dirname3, "../templates");
|
|
1036
|
+
TEMPLATES_DIR_FALLBACK = resolve2(__dirname3, "../../agent_moss/templates");
|
|
866
1037
|
TEMPLATE_FILES = ["prompt1_template.txt", "prompt2_template.txt", "security_judge_template.txt"];
|
|
867
1038
|
cachedTemplates = null;
|
|
868
1039
|
}
|
|
@@ -1100,13 +1271,14 @@ async function runLLMAnalysis(input, previous) {
|
|
|
1100
1271
|
function buildPrompt(input, previous, matchedSkills, templates, scriptAnalysis) {
|
|
1101
1272
|
const skillsText = formatSkillsForPrompt(matchedSkills);
|
|
1102
1273
|
const historyStr = input.actionHistory.map((h, i) => `${i + 1}. ${h.actionType}: ${h.actionDetail}`).join("\n") || "(\u65E0\u5386\u53F2\u64CD\u4F5C)";
|
|
1103
|
-
const templateName = previous.heuristic || previous.logic ? "prompt2" : "prompt1";
|
|
1104
|
-
const baseTemplate = templates[templateName] || templates["prompt1"] || "";
|
|
1105
1274
|
const scriptAnalysisText = scriptAnalysis ? formatScriptAnalysisForPrompt(scriptAnalysis) : "";
|
|
1106
1275
|
const hintsText = formatHints(previous);
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1276
|
+
const securityJudgeTemplate = templates["security_judge"];
|
|
1277
|
+
if (securityJudgeTemplate) {
|
|
1278
|
+
return securityJudgeTemplate.replaceAll("{prompt_session}", input.promptSession || "\uFF08\u672A\u63D0\u4F9B\uFF09").replaceAll("{action_history}", historyStr).replaceAll("{action_type}", input.aNext.actionType).replaceAll("{action_detail}", input.aNext.actionDetail).replaceAll("{reason}", input.reason || "\u672A\u8BF4\u660E").replaceAll("{skills_text}", skillsText).replaceAll("{hints_text}", hintsText).replaceAll("{script_analysis_text}", scriptAnalysisText).replaceAll("{{", "{").replaceAll("}}", "}");
|
|
1279
|
+
}
|
|
1280
|
+
console.warn("[AgentMoss] security_judge template missing, using sparse fallback prompt");
|
|
1281
|
+
return `## \u5F53\u524D\u64CD\u4F5C\u4E0A\u4E0B\u6587
|
|
1110
1282
|
- \u4F1A\u8BDD ID: ${input.sessionId}
|
|
1111
1283
|
- \u7528\u6237\u4EFB\u52A1: ${input.promptSession || "\u672A\u6307\u5B9A"}
|
|
1112
1284
|
- \u64CD\u4F5C\u7CFB\u7EDF: ${input.osType}
|
|
@@ -1128,8 +1300,7 @@ ${scriptAnalysisText ? `
|
|
|
1128
1300
|
## \u811A\u672C\u5185\u5BB9\u5206\u6790
|
|
1129
1301
|
${scriptAnalysisText}` : ""}
|
|
1130
1302
|
|
|
1131
|
-
\u8BF7\u6839\u636E\u4EE5\u4E0A\u4FE1\u606F\uFF0C\u5BF9\u5373\u5C06\u6267\u884C\u7684\u64CD\u4F5C\u8FDB\u884C\u5B89\u5168\u5224\u65AD\u3002\u4F60\u5FC5\u987B\u8F93\u51FA\u4E25\u683C\u7684 JSON \u683C\u5F0F\uFF0C
|
|
1132
|
-
\u4E0D\u8981\u5305\u542B\u4EFB\u4F55\u5176\u4ED6\u6587\u5B57\u3001\u6CE8\u91CA\u6216 markdown \u6807\u8BB0\u3002
|
|
1303
|
+
\u8BF7\u6839\u636E\u4EE5\u4E0A\u4FE1\u606F\uFF0C\u5BF9\u5373\u5C06\u6267\u884C\u7684\u64CD\u4F5C\u8FDB\u884C\u5B89\u5168\u5224\u65AD\u3002\u524D\u7F6E\u68C0\u6D4B\u4E3A low/medium \u4E14\u6709\u5408\u7406\u6267\u884C\u7406\u7531\u65F6\u5E94\u5F53\u5141\u8BB8\u3002\u4F60\u5FC5\u987B\u8F93\u51FA\u4E25\u683C\u7684 JSON \u683C\u5F0F\uFF0C\u4E0D\u8981\u5305\u542B\u4EFB\u4F55\u5176\u4ED6\u6587\u5B57\u3001\u6CE8\u91CA\u6216 markdown \u6807\u8BB0\u3002
|
|
1133
1304
|
|
|
1134
1305
|
\u8F93\u51FA\u683C\u5F0F:
|
|
1135
1306
|
{"allowed": true/false, "reason": "\u5224\u65AD\u7406\u7531", "riskLevel": "low|medium|high|critical", "riskType": "\u98CE\u9669\u7C7B\u578B", "confidence": 0-100}`;
|
|
@@ -1176,7 +1347,9 @@ async function analyzeWithLLM(prompt, config) {
|
|
|
1176
1347
|
temperature: config.temperature || 0.1,
|
|
1177
1348
|
max_tokens: config.maxTokens || 1024,
|
|
1178
1349
|
messages: [
|
|
1179
|
-
|
|
1350
|
+
// security_judge 模板自带角色定义与判断规则,system 仅做输出格式约束,
|
|
1351
|
+
// 避免与模板里的"你是 xiaoO Audit Agent 安全审计员"角色定义冲突(对齐 Python:无独立 system)。
|
|
1352
|
+
{ role: "system", content: "\u53EA\u8F93\u51FA\u7EAF JSON\uFF0C\u4E0D\u8981\u5305\u542B markdown \u6807\u8BB0\u3001\u4EE3\u7801\u5757\u6216\u4EFB\u4F55\u5176\u4ED6\u6587\u5B57\u3002" },
|
|
1180
1353
|
{ role: "user", content: prompt }
|
|
1181
1354
|
]
|
|
1182
1355
|
});
|
|
@@ -1264,8 +1437,9 @@ function matchesAny(cmd, patterns) {
|
|
|
1264
1437
|
async function runAnalysis(input) {
|
|
1265
1438
|
const heuristicResult = isHeuristicEnabled() ? runHeuristicCheck(input) : null;
|
|
1266
1439
|
const isInlineScriptCmd = isInlineScriptCommand(input.aNext.actionDetail.toLowerCase());
|
|
1440
|
+
const isLiteralTextCmd = isLiteralTextCommand(input.aNext.actionDetail.toLowerCase());
|
|
1267
1441
|
if (heuristicResult && !heuristicResult.allowed) {
|
|
1268
|
-
const skipInlineFileAccess = isInlineScriptCmd && heuristicResult.riskType === "file_access";
|
|
1442
|
+
const skipInlineFileAccess = (isInlineScriptCmd || isLiteralTextCmd) && heuristicResult.riskType === "file_access";
|
|
1269
1443
|
if (!skipInlineFileAccess) {
|
|
1270
1444
|
return heuristicResult;
|
|
1271
1445
|
}
|
|
@@ -1322,8 +1496,33 @@ async function runAnalysis(input) {
|
|
|
1322
1496
|
}
|
|
1323
1497
|
const logicResult = isLogicRulesEnabled() ? runLogicCheck(input) : null;
|
|
1324
1498
|
if (logicResult && !logicResult.allowed) {
|
|
1325
|
-
const isCredentialPath = logicResult.
|
|
1326
|
-
const skipInlineFileAccess = isInlineScriptCmd && logicResult.riskType === "sensitive_path_access";
|
|
1499
|
+
const isCredentialPath = !!logicResult.isCredential;
|
|
1500
|
+
const skipInlineFileAccess = (isInlineScriptCmd || isLiteralTextCmd) && logicResult.riskType === "sensitive_path_access";
|
|
1501
|
+
if (skipInlineFileAccess && !isCredentialPath) {
|
|
1502
|
+
const inlineJudgment = analyzeInlineScript(input.aNext.actionDetail);
|
|
1503
|
+
if (inlineJudgment.actionable) {
|
|
1504
|
+
if (!inlineJudgment.allowed) {
|
|
1505
|
+
return {
|
|
1506
|
+
allowed: false,
|
|
1507
|
+
reason: inlineJudgment.reason,
|
|
1508
|
+
riskLevel: inlineJudgment.riskLevel,
|
|
1509
|
+
riskType: inlineJudgment.riskType,
|
|
1510
|
+
confidence: 90,
|
|
1511
|
+
source: "logic_rule",
|
|
1512
|
+
violatedLayers: ["1.2"]
|
|
1513
|
+
};
|
|
1514
|
+
}
|
|
1515
|
+
return {
|
|
1516
|
+
allowed: true,
|
|
1517
|
+
reason: inlineJudgment.reason,
|
|
1518
|
+
riskLevel: inlineJudgment.riskLevel,
|
|
1519
|
+
riskType: inlineJudgment.riskType,
|
|
1520
|
+
confidence: 90,
|
|
1521
|
+
source: "logic_rule",
|
|
1522
|
+
violatedLayers: []
|
|
1523
|
+
};
|
|
1524
|
+
}
|
|
1525
|
+
}
|
|
1327
1526
|
if (!skipInlineFileAccess || isCredentialPath) {
|
|
1328
1527
|
return logicResult;
|
|
1329
1528
|
}
|
|
@@ -1352,6 +1551,7 @@ var init_coordinator = __esm({
|
|
|
1352
1551
|
init_esm_shims();
|
|
1353
1552
|
init_heuristic();
|
|
1354
1553
|
init_logic_rules();
|
|
1554
|
+
init_inline_analyzer();
|
|
1355
1555
|
init_llm_analyzer();
|
|
1356
1556
|
init_config();
|
|
1357
1557
|
FULLY_SAFE_TOOLS = /* @__PURE__ */ new Set([
|