mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-14 10:41:23 +00:00
refactor: dedupe security lowercase helpers
This commit is contained in:
@@ -27,6 +27,7 @@ import type { AgentToolsConfig } from "../config/types.tools.js";
|
||||
import { readInstalledPackageVersion } from "../infra/package-update-utils.js";
|
||||
import { normalizePluginsConfig } from "../plugins/config-state.js";
|
||||
import { normalizeAgentId } from "../routing/session-key.js";
|
||||
import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js";
|
||||
import {
|
||||
formatPermissionDetail,
|
||||
formatPermissionRemediation,
|
||||
@@ -239,7 +240,11 @@ function resolveToolPolicies(params: {
|
||||
}
|
||||
|
||||
function normalizePluginIdSet(entries: string[]): Set<string> {
|
||||
return new Set(entries.map((entry) => entry.trim().toLowerCase()).filter(Boolean));
|
||||
return new Set(
|
||||
entries
|
||||
.map((entry) => normalizeOptionalLowercaseString(entry))
|
||||
.filter((entry): entry is string => Boolean(entry)),
|
||||
);
|
||||
}
|
||||
|
||||
function resolveEnabledExtensionPluginIds(params: {
|
||||
@@ -255,12 +260,16 @@ function resolveEnabledExtensionPluginIds(params: {
|
||||
const denySet = normalizePluginIdSet(normalized.deny);
|
||||
const entryById = new Map<string, { enabled?: boolean }>();
|
||||
for (const [id, entry] of Object.entries(normalized.entries)) {
|
||||
entryById.set(id.trim().toLowerCase(), entry);
|
||||
const normalizedId = normalizeOptionalLowercaseString(id);
|
||||
if (!normalizedId) {
|
||||
continue;
|
||||
}
|
||||
entryById.set(normalizedId, entry);
|
||||
}
|
||||
|
||||
const enabled: string[] = [];
|
||||
for (const id of params.pluginDirs) {
|
||||
const normalizedId = id.trim().toLowerCase();
|
||||
const normalizedId = normalizeOptionalLowercaseString(id);
|
||||
if (!normalizedId) {
|
||||
continue;
|
||||
}
|
||||
@@ -286,7 +295,9 @@ function collectAllowEntries(config?: { allow?: string[]; alsoAllow?: string[] }
|
||||
if (Array.isArray(config?.alsoAllow)) {
|
||||
out.push(...config.alsoAllow);
|
||||
}
|
||||
return out.map((entry) => entry.trim().toLowerCase()).filter(Boolean);
|
||||
return out
|
||||
.map((entry) => normalizeOptionalLowercaseString(entry))
|
||||
.filter((entry): entry is string => Boolean(entry));
|
||||
}
|
||||
|
||||
function hasExplicitPluginAllow(params: {
|
||||
@@ -496,7 +507,7 @@ function parsePublishedHostFromDockerPortLine(line: string): string | null {
|
||||
}
|
||||
|
||||
function isLoopbackPublishHost(host: string): boolean {
|
||||
const normalized = host.trim().toLowerCase();
|
||||
const normalized = normalizeOptionalLowercaseString(host);
|
||||
return normalized === "127.0.0.1" || normalized === "::1" || normalized === "localhost";
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ import {
|
||||
DEFAULT_DANGEROUS_NODE_COMMANDS,
|
||||
resolveNodeCommandAllowlist,
|
||||
} from "../gateway/node-command-policy.js";
|
||||
import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js";
|
||||
import { pickSandboxToolPolicy } from "./audit-tool-policy.js";
|
||||
|
||||
export type SecurityAuditFinding = {
|
||||
@@ -815,7 +816,7 @@ export function collectSandboxDangerousConfigFindings(cfg: OpenClawConfig): Secu
|
||||
|
||||
const seccompProfile =
|
||||
typeof docker.seccompProfile === "string" ? docker.seccompProfile : undefined;
|
||||
if (seccompProfile && seccompProfile.trim().toLowerCase() === "unconfined") {
|
||||
if (normalizeOptionalLowercaseString(seccompProfile) === "unconfined") {
|
||||
findings.push({
|
||||
checkId: "sandbox.dangerous_seccomp_profile",
|
||||
severity: "critical",
|
||||
@@ -827,7 +828,7 @@ export function collectSandboxDangerousConfigFindings(cfg: OpenClawConfig): Secu
|
||||
|
||||
const apparmorProfile =
|
||||
typeof docker.apparmorProfile === "string" ? docker.apparmorProfile : undefined;
|
||||
if (apparmorProfile && apparmorProfile.trim().toLowerCase() === "unconfined") {
|
||||
if (normalizeOptionalLowercaseString(apparmorProfile) === "unconfined") {
|
||||
findings.push({
|
||||
checkId: "sandbox.dangerous_apparmor_profile",
|
||||
severity: "critical",
|
||||
@@ -842,7 +843,7 @@ export function collectSandboxDangerousConfigFindings(cfg: OpenClawConfig): Secu
|
||||
const defaultBrowser = resolveSandboxConfigForAgent(cfg).browser;
|
||||
if (
|
||||
defaultBrowser.enabled &&
|
||||
defaultBrowser.network.trim().toLowerCase() === "bridge" &&
|
||||
normalizeOptionalLowercaseString(defaultBrowser.network) === "bridge" &&
|
||||
!defaultBrowser.cdpSourceRange?.trim()
|
||||
) {
|
||||
browserExposurePaths.push("agents.defaults.sandbox.browser");
|
||||
@@ -855,7 +856,7 @@ export function collectSandboxDangerousConfigFindings(cfg: OpenClawConfig): Secu
|
||||
if (!browser.enabled) {
|
||||
continue;
|
||||
}
|
||||
if (browser.network.trim().toLowerCase() !== "bridge") {
|
||||
if (normalizeOptionalLowercaseString(browser.network) !== "bridge") {
|
||||
continue;
|
||||
}
|
||||
if (browser.cdpSourceRange?.trim()) {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { randomBytes } from "node:crypto";
|
||||
import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js";
|
||||
|
||||
/**
|
||||
* Security utilities for handling untrusted external content.
|
||||
@@ -109,7 +110,7 @@ const EXTERNAL_SOURCE_LABELS: Record<ExternalContentSource, string> = {
|
||||
export function resolveHookExternalContentSource(
|
||||
sessionKey: string,
|
||||
): HookExternalContentSource | undefined {
|
||||
const normalized = sessionKey.trim().toLowerCase();
|
||||
const normalized = normalizeLowercaseStringOrEmpty(sessionKey);
|
||||
if (normalized.startsWith("hook:gmail:")) {
|
||||
return "gmail";
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import os from "node:os";
|
||||
import { runExec } from "../process/exec.js";
|
||||
import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js";
|
||||
|
||||
export type ExecFn = typeof runExec;
|
||||
|
||||
@@ -63,7 +64,7 @@ const STATUS_PREFIXES = [
|
||||
"no mapping between account names",
|
||||
];
|
||||
|
||||
const normalize = (value: string) => value.trim().toLowerCase();
|
||||
const normalize = (value: string) => normalizeLowercaseStringOrEmpty(value);
|
||||
|
||||
function normalizeSid(value: string): string {
|
||||
const normalized = normalize(value);
|
||||
|
||||
Reference in New Issue
Block a user