fix: enforce explicit group auth boundaries across channels

This commit is contained in:
Peter Steinberger
2026-02-26 18:15:57 +01:00
parent d0d83a2020
commit 64de4b6d6a
20 changed files with 614 additions and 331 deletions

View File

@@ -11,6 +11,7 @@ import {
resolveMentionGating,
formatAllowlistMatchMeta,
resolveEffectiveAllowFromLists,
resolveDmGroupAccessWithLists,
type HistoryEntry,
} from "openclaw/plugin-sdk";
import {
@@ -146,53 +147,13 @@ export function createMSTeamsMessageHandler(deps: MSTeamsMessageHandlerDeps) {
storeAllowFrom: storedAllowFrom,
dmPolicy,
});
const effectiveDmAllowFrom = resolvedAllowFromLists.effectiveAllowFrom;
if (isDirectMessage && msteamsCfg) {
if (dmPolicy === "disabled") {
log.debug?.("dropping dm (dms disabled)");
return;
}
if (dmPolicy !== "open") {
const allowNameMatching = isDangerousNameMatchingEnabled(msteamsCfg);
const allowMatch = resolveMSTeamsAllowlistMatch({
allowFrom: effectiveDmAllowFrom,
senderId,
senderName,
allowNameMatching,
});
if (!allowMatch.allowed) {
if (dmPolicy === "pairing") {
const request = await core.channel.pairing.upsertPairingRequest({
channel: "msteams",
id: senderId,
meta: { name: senderName },
});
if (request) {
log.info("msteams pairing request created", {
sender: senderId,
label: senderName,
});
}
}
log.debug?.("dropping dm (not allowlisted)", {
sender: senderId,
label: senderName,
allowlistMatch: formatAllowlistMatchMeta(allowMatch),
});
return;
}
}
}
const defaultGroupPolicy = resolveDefaultGroupPolicy(cfg);
const groupPolicy =
!isDirectMessage && msteamsCfg
? (msteamsCfg.groupPolicy ?? defaultGroupPolicy ?? "allowlist")
: "disabled";
const effectiveGroupAllowFrom =
!isDirectMessage && msteamsCfg ? resolvedAllowFromLists.effectiveGroupAllowFrom : [];
const effectiveGroupAllowFrom = resolvedAllowFromLists.effectiveGroupAllowFrom;
const teamId = activity.channelData?.team?.id;
const teamName = activity.channelData?.team?.name;
const channelName = activity.channelData?.channel?.name;
@@ -203,6 +164,61 @@ export function createMSTeamsMessageHandler(deps: MSTeamsMessageHandlerDeps) {
conversationId,
channelName,
});
const senderGroupPolicy =
groupPolicy === "disabled"
? "disabled"
: effectiveGroupAllowFrom.length > 0
? "allowlist"
: "open";
const access = resolveDmGroupAccessWithLists({
isGroup: !isDirectMessage,
dmPolicy,
groupPolicy: senderGroupPolicy,
allowFrom: configuredDmAllowFrom,
groupAllowFrom,
storeAllowFrom: storedAllowFrom,
groupAllowFromFallbackToAllowFrom: false,
isSenderAllowed: (allowFrom) =>
resolveMSTeamsAllowlistMatch({
allowFrom,
senderId,
senderName,
allowNameMatching: isDangerousNameMatchingEnabled(msteamsCfg),
}).allowed,
});
const effectiveDmAllowFrom = access.effectiveAllowFrom;
if (isDirectMessage && msteamsCfg && access.decision !== "allow") {
if (access.reason === "dmPolicy=disabled") {
log.debug?.("dropping dm (dms disabled)");
return;
}
const allowMatch = resolveMSTeamsAllowlistMatch({
allowFrom: effectiveDmAllowFrom,
senderId,
senderName,
allowNameMatching: isDangerousNameMatchingEnabled(msteamsCfg),
});
if (access.decision === "pairing") {
const request = await core.channel.pairing.upsertPairingRequest({
channel: "msteams",
id: senderId,
meta: { name: senderName },
});
if (request) {
log.info("msteams pairing request created", {
sender: senderId,
label: senderName,
});
}
}
log.debug?.("dropping dm (not allowlisted)", {
sender: senderId,
label: senderName,
allowlistMatch: formatAllowlistMatchMeta(allowMatch),
});
return;
}
if (!isDirectMessage && msteamsCfg) {
if (groupPolicy === "disabled") {
@@ -229,13 +245,12 @@ export function createMSTeamsMessageHandler(deps: MSTeamsMessageHandlerDeps) {
});
return;
}
if (effectiveGroupAllowFrom.length > 0) {
const allowNameMatching = isDangerousNameMatchingEnabled(msteamsCfg);
if (effectiveGroupAllowFrom.length > 0 && access.decision !== "allow") {
const allowMatch = resolveMSTeamsAllowlistMatch({
allowFrom: effectiveGroupAllowFrom,
senderId,
senderName,
allowNameMatching,
allowNameMatching: isDangerousNameMatchingEnabled(msteamsCfg),
});
if (!allowMatch.allowed) {
log.debug?.("dropping group message (not in groupAllowFrom)", {