

























@@ -0,0 +1,143 @@
1+import { DANGEROUS_SANDBOX_DOCKER_BOOLEAN_KEYS } from "../agents/sandbox/config.js";
2+import type { OpenClawConfig } from "../config/types.openclaw.js";
3+import { isRecord } from "../utils.js";
4+import { collectCoreInsecureOrDangerousFlags } from "./core-dangerous-config-flags.js";
5+6+type DangerousFlagValue = string | number | boolean | null;
7+8+type DangerousFlagContract = {
9+path: string;
10+equals: DangerousFlagValue;
11+};
12+13+type PluginConfigContractMetadata = {
14+configContracts: {
15+dangerousFlags?: DangerousFlagContract[];
16+};
17+};
18+19+type PluginConfigContractMatch = {
20+path: string;
21+value: unknown;
22+};
23+24+type CollectPluginConfigContractMatches = (input: {
25+pathPattern: string;
26+root: Record<string, unknown>;
27+}) => Iterable<PluginConfigContractMatch>;
28+29+export type DangerousConfigFlagContractInputs = {
30+configContractsById?: ReadonlyMap<string, PluginConfigContractMetadata>;
31+collectPluginConfigContractMatches?: CollectPluginConfigContractMatches;
32+};
33+34+function formatDangerousConfigFlagValue(value: DangerousFlagValue): string {
35+return value === null ? "null" : String(value);
36+}
37+38+function getAgentDangerousFlagPathSegment(agent: unknown, index: number): string {
39+const id =
40+agent &&
41+typeof agent === "object" &&
42+!Array.isArray(agent) &&
43+typeof (agent as { id?: unknown }).id === "string" &&
44+(agent as { id: string }).id.length > 0
45+ ? (agent as { id: string }).id
46+ : undefined;
47+return id ? `agents.list[id=${JSON.stringify(id)}]` : `agents.list[${index}]`;
48+}
49+50+function collectExactPluginConfigContractMatches({
51+ pathPattern,
52+ root,
53+}: {
54+pathPattern: string;
55+root: Record<string, unknown>;
56+}): PluginConfigContractMatch[] {
57+return Object.hasOwn(root, pathPattern) ? [{ path: pathPattern, value: root[pathPattern] }] : [];
58+}
59+60+export function collectEnabledInsecureOrDangerousFlagsFromContracts(
61+cfg: OpenClawConfig,
62+inputs: DangerousConfigFlagContractInputs = {},
63+): string[] {
64+const enabledFlags = collectCoreInsecureOrDangerousFlags(cfg);
65+66+const collectSandboxDockerDangerousFlags = (
67+docker: Record<string, unknown> | undefined,
68+pathPrefix: string,
69+): void => {
70+if (!isRecord(docker)) {
71+return;
72+}
73+for (const key of DANGEROUS_SANDBOX_DOCKER_BOOLEAN_KEYS) {
74+if (docker[key] === true) {
75+enabledFlags.push(`${pathPrefix}.${key}=true`);
76+}
77+}
78+};
79+80+if (cfg.hooks?.allowRequestSessionKey === true) {
81+enabledFlags.push("hooks.allowRequestSessionKey=true");
82+}
83+if (cfg.browser?.ssrfPolicy?.dangerouslyAllowPrivateNetwork === true) {
84+enabledFlags.push("browser.ssrfPolicy.dangerouslyAllowPrivateNetwork=true");
85+}
86+if (cfg.tools?.fs?.workspaceOnly === false) {
87+enabledFlags.push("tools.fs.workspaceOnly=false");
88+}
89+collectSandboxDockerDangerousFlags(
90+isRecord(cfg.agents?.defaults?.sandbox?.docker)
91+ ? cfg.agents?.defaults?.sandbox?.docker
92+ : undefined,
93+"agents.defaults.sandbox.docker",
94+);
95+if (Array.isArray(cfg.agents?.list)) {
96+for (const [index, agent] of cfg.agents.list.entries()) {
97+collectSandboxDockerDangerousFlags(
98+isRecord(agent?.sandbox?.docker) ? agent.sandbox.docker : undefined,
99+`${getAgentDangerousFlagPathSegment(agent, index)}.sandbox.docker`,
100+);
101+}
102+}
103+104+const pluginEntries = cfg.plugins?.entries;
105+if (!isRecord(pluginEntries)) {
106+return enabledFlags;
107+}
108+109+const configContracts = inputs.configContractsById ?? new Map();
110+const collectPluginConfigContractMatches =
111+inputs.collectPluginConfigContractMatches ?? collectExactPluginConfigContractMatches;
112+const seenFlags = new Set<string>();
113+for (const [pluginId, metadata] of configContracts.entries()) {
114+const dangerousFlags = metadata.configContracts.dangerousFlags;
115+if (!dangerousFlags?.length) {
116+continue;
117+}
118+const pluginEntry = pluginEntries[pluginId];
119+if (!isRecord(pluginEntry) || !isRecord(pluginEntry.config)) {
120+continue;
121+}
122+for (const flag of dangerousFlags) {
123+for (const match of collectPluginConfigContractMatches({
124+root: pluginEntry.config,
125+pathPattern: flag.path,
126+})) {
127+if (!Object.is(match.value, flag.equals)) {
128+continue;
129+}
130+const rendered =
131+`plugins.entries.${pluginId}.config.${match.path}` +
132+`=${formatDangerousConfigFlagValue(flag.equals)}`;
133+if (seenFlags.has(rendered)) {
134+continue;
135+}
136+seenFlags.add(rendered);
137+enabledFlags.push(rendered);
138+}
139+}
140+}
141+142+return enabledFlags;
143+}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。