mirror of
https://github.com/moltbot/moltbot.git
synced 2026-04-25 23:47:20 +00:00
fix(memory): prevent QMD scope deny bypass
This commit is contained in:
@@ -33,4 +33,22 @@ describe("qmd scope", () => {
|
||||
expect(isQmdScopeAllowed(scope, "agent:agent-1:workspace:group:123")).toBe(true);
|
||||
expect(isQmdScopeAllowed(scope, "agent:agent-1:other:group:123")).toBe(false);
|
||||
});
|
||||
|
||||
it("supports rawKeyPrefix matches for agent-prefixed keys", () => {
|
||||
const scope: ResolvedQmdConfig["scope"] = {
|
||||
default: "allow",
|
||||
rules: [{ action: "deny", match: { rawKeyPrefix: "agent:main:discord:" } }],
|
||||
};
|
||||
expect(isQmdScopeAllowed(scope, "agent:main:discord:channel:c123")).toBe(false);
|
||||
expect(isQmdScopeAllowed(scope, "agent:main:slack:channel:c123")).toBe(true);
|
||||
});
|
||||
|
||||
it("keeps legacy agent-prefixed keyPrefix rules working", () => {
|
||||
const scope: ResolvedQmdConfig["scope"] = {
|
||||
default: "allow",
|
||||
rules: [{ action: "deny", match: { keyPrefix: "agent:main:discord:" } }],
|
||||
};
|
||||
expect(isQmdScopeAllowed(scope, "agent:main:discord:channel:c123")).toBe(false);
|
||||
expect(isQmdScopeAllowed(scope, "agent:main:slack:channel:c123")).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -15,6 +15,7 @@ export function isQmdScopeAllowed(scope: ResolvedQmdConfig["scope"], sessionKey?
|
||||
const channel = parsed.channel;
|
||||
const chatType = parsed.chatType;
|
||||
const normalizedKey = parsed.normalizedKey ?? "";
|
||||
const rawKey = sessionKey?.trim().toLowerCase() ?? "";
|
||||
for (const rule of scope.rules ?? []) {
|
||||
if (!rule) {
|
||||
continue;
|
||||
@@ -26,9 +27,23 @@ export function isQmdScopeAllowed(scope: ResolvedQmdConfig["scope"], sessionKey?
|
||||
if (match.chatType && match.chatType !== chatType) {
|
||||
continue;
|
||||
}
|
||||
if (match.keyPrefix && !normalizedKey.startsWith(match.keyPrefix)) {
|
||||
const normalizedPrefix = match.keyPrefix?.trim().toLowerCase() || undefined;
|
||||
const rawPrefix = match.rawKeyPrefix?.trim().toLowerCase() || undefined;
|
||||
|
||||
if (rawPrefix && !rawKey.startsWith(rawPrefix)) {
|
||||
continue;
|
||||
}
|
||||
if (normalizedPrefix) {
|
||||
// Backward compat: older configs used `keyPrefix: "agent:<id>:..."` to match raw keys.
|
||||
const isLegacyRaw = normalizedPrefix.startsWith("agent:");
|
||||
if (isLegacyRaw) {
|
||||
if (!rawKey.startsWith(normalizedPrefix)) {
|
||||
continue;
|
||||
}
|
||||
} else if (!normalizedKey.startsWith(normalizedPrefix)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return rule.action === "allow";
|
||||
}
|
||||
const fallback = scope.default ?? "allow";
|
||||
|
||||
Reference in New Issue
Block a user