fix(cr-mbx-feishu-encryptkey-config-redaction-bypass): apply security fix (#53414)

Generated by staged fix workflow.
This commit is contained in:
Coy Geek
2026-03-26 16:58:37 -07:00
committed by GitHub
parent afc649255c
commit 8e285d112d
4 changed files with 41 additions and 11 deletions

View File

@@ -50,7 +50,10 @@ describe("redactConfigSnapshot", () => {
signingSecret: "slack-signing-secret-value-1234",
token: "secret-slack-token-value-here",
},
feishu: { appSecret: "feishu-app-secret-value-here-1234" },
feishu: {
appSecret: "feishu-app-secret-value-here-1234",
encryptKey: "feishu-encrypt-key-value-here-1234",
},
},
models: {
providers: {
@@ -70,6 +73,7 @@ describe("redactConfigSnapshot", () => {
expect(cfg.channels.slack.signingSecret).toBe(REDACTED_SENTINEL);
expect(cfg.channels.slack.token).toBe(REDACTED_SENTINEL);
expect(cfg.channels.feishu.appSecret).toBe(REDACTED_SENTINEL);
expect(cfg.channels.feishu.encryptKey).toBe(REDACTED_SENTINEL);
expect(cfg.models.providers.openai.apiKey).toBe(REDACTED_SENTINEL);
expect(cfg.models.providers.openai.baseUrl).toBe("https://api.openai.com");
expect(cfg.shortSecret.token).toBe(REDACTED_SENTINEL);

View File

@@ -1,5 +1,6 @@
import { describe, expect, it } from "vitest";
import { z } from "zod";
import { buildSecretInputSchema } from "../plugin-sdk/secret-input-schema.js";
import { __test__, isSensitiveConfigPath } from "./schema.hints.js";
import { OpenClawSchema } from "./zod-schema.js";
import { sensitive } from "./zod-schema.sensitive.js";
@@ -30,6 +31,8 @@ describe("isSensitiveConfigPath", () => {
expect(isSensitiveConfigPath("channels.slack.token")).toBe(true);
expect(isSensitiveConfigPath("models.providers.openai.apiKey")).toBe(true);
expect(isSensitiveConfigPath("channels.irc.nickserv.password")).toBe(true);
expect(isSensitiveConfigPath("channels.feishu.encryptKey")).toBe(true);
expect(isSensitiveConfigPath("channels.feishu.accounts.default.encryptKey")).toBe(true);
});
});
@@ -138,4 +141,19 @@ describe("mapSensitivePaths", () => {
expect(hints["models.providers.*.headers.*"]?.sensitive).toBe(true);
expect(hints["skills.entries.*.apiKey"]?.sensitive).toBe(true);
});
it("marks buildSecretInputSchema fields as sensitive via registry", () => {
const schema = z.object({
encryptKey: buildSecretInputSchema().optional(),
appSecret: buildSecretInputSchema().optional(),
nested: z.object({
verificationToken: buildSecretInputSchema().optional(),
}),
});
const hints = mapSensitivePaths(schema, "", {});
expect(hints["encryptKey"]?.sensitive).toBe(true);
expect(hints["appSecret"]?.sensitive).toBe(true);
expect(hints["nested.verificationToken"]?.sensitive).toBe(true);
});
});

View File

@@ -113,6 +113,7 @@ const SENSITIVE_PATTERNS = [
/password/i,
/secret/i,
/api.?key/i,
/encrypt.?key/i,
/serviceaccount(?:ref)?$/i,
];

View File

@@ -1,5 +1,6 @@
import { z } from "zod";
import { ENV_SECRET_REF_ID_RE } from "../config/types.secrets.js";
import { sensitive } from "../config/zod-schema.sensitive.js";
import {
formatExecSecretRefIdValidationMessage,
isValidExecSecretRefId,
@@ -7,16 +8,17 @@ import {
SECRET_PROVIDER_ALIAS_PATTERN,
} from "../secrets/ref-contract.js";
/** Build the shared zod schema for secret inputs accepted by plugin auth/config surfaces. */
export function buildSecretInputSchema() {
const providerSchema = z
.string()
.regex(
SECRET_PROVIDER_ALIAS_PATTERN,
'Secret reference provider must match /^[a-z][a-z0-9_-]{0,63}$/ (example: "default").',
);
const providerSchema = z
.string()
.regex(
SECRET_PROVIDER_ALIAS_PATTERN,
'Secret reference provider must match /^[a-z][a-z0-9_-]{0,63}$/ (example: "default").',
);
return z.union([
// Singleton registered with the sensitive registry so that mapSensitivePaths
// marks every config field using this schema as sensitive (redacted).
const secretInputSchema = z
.union([
z.string(),
z.discriminatedUnion("source", [
z.object({
@@ -45,5 +47,10 @@ export function buildSecretInputSchema() {
id: z.string().refine(isValidExecSecretRefId, formatExecSecretRefIdValidationMessage()),
}),
]),
]);
])
.register(sensitive);
/** Build the shared zod schema for secret inputs accepted by plugin auth/config surfaces. */
export function buildSecretInputSchema() {
return secretInputSchema;
}