openclaw/extensions
Lewis 26644c4b89
fix(msteams): add SSRF protection to attachment downloads via redirect and DNS validation (#23598)
* fix(msteams): add SSRF protection to attachment downloads via redirect and DNS validation

The attachment download flow in fetchWithAuthFallback() followed
redirects automatically on the initial fetch without any allowlist
or IP validation. This allowed DNS rebinding attacks where an
allowlisted domain (e.g. evil.trafficmanager.net) could redirect
or resolve to a private IP like 169.254.169.254, bypassing the
hostname allowlist entirely (issue #11811).

This commit adds three layers of SSRF protection:

1. safeFetch() in shared.ts: a redirect-safe fetch wrapper that uses
   redirect: "manual" and validates every redirect hop against the
   hostname allowlist AND DNS-resolved IP before following it.

2. isPrivateOrReservedIP() + resolveAndValidateIP() in shared.ts:
   rejects RFC 1918, loopback, link-local, and IPv6 private ranges
   for both initial URLs and redirect targets.

3. graph.ts SharePoint redirect handling now also uses redirect:
   "manual" and validates resolved IPs, not just hostnames.

The initial fetch in fetchWithAuthFallback now goes through safeFetch
instead of a bare fetch(), ensuring redirects are never followed
without validation.

Includes 38 new tests covering IP validation, DNS resolution checks,
redirect following, DNS rebinding attacks, redirect loops, and
protocol downgrade blocking.

* fix: address review feedback on SSRF protection

- Replace hand-rolled isPrivateOrReservedIP with SDK's isPrivateIpAddress
  which handles IPv4-mapped IPv6, expanded notation, NAT64, 6to4, Teredo,
  octal IPv4, and fails closed on parse errors
- Add redirect: "manual" to auth retry redirect fetch in download.ts to
  prevent chained redirect attacks bypassing SSRF checks
- Add redirect: "manual" to SharePoint redirect fetch in graph.ts to
  prevent the same chained redirect bypass
- Update test expectations for SDK's fail-closed behavior on malformed IPs
- Add expanded IPv6 loopback (0:0:0:0:0:0:0:1) test case

* fix: type fetchMock as typeof fetch to fix TS tuple index error

* msteams: harden attachment auth and graph redirect fetch flow

* changelog(msteams): credit redirect-safeFetch hardening contributors

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-02-22 18:00:54 -05:00
..
bluebubbles fix(bluebubbles): tighten chat target handling 2026-02-22 11:29:31 +00:00
copilot-proxy fix(ci): sync plugin versions and harden install smoke 2026-02-21 20:18:37 +01:00
device-pair Security: disable plugin runtime command execution primitive (#20828) 2026-02-19 10:17:29 +00:00
diagnostics-otel fix(ci): sync plugin versions and harden install smoke 2026-02-21 20:18:37 +01:00
discord fix(extensions): preserve mediaLocalRoots in telegram/discord sendMedia 2026-02-22 22:53:57 +01:00
feishu fix(feishu): prefer video file_key for inbound media 2026-02-22 19:21:42 +01:00
google-antigravity-auth fix(ci): sync plugin versions and harden install smoke 2026-02-21 20:18:37 +01:00
google-gemini-cli-auth fix(ci): sync plugin versions and harden install smoke 2026-02-21 20:18:37 +01:00
googlechat refactor(channels): reuse runtime group policy helpers 2026-02-22 12:44:23 +01:00
imessage refactor(channels): reuse runtime group policy helpers 2026-02-22 12:44:23 +01:00
irc refactor(channels): reuse runtime group policy helpers 2026-02-22 12:44:23 +01:00
line refactor(channels): reuse runtime group policy helpers 2026-02-22 12:44:23 +01:00
llm-task fix(ci): sync plugin versions and harden install smoke 2026-02-21 20:18:37 +01:00
lobster fix(ci): sync plugin versions and harden install smoke 2026-02-21 20:18:37 +01:00
matrix refactor(channels): reuse runtime group policy helpers 2026-02-22 12:44:23 +01:00
mattermost refactor(channels): reuse runtime group policy helpers 2026-02-22 12:44:23 +01:00
memory-core fix(ci): sync plugin versions and harden install smoke 2026-02-21 20:18:37 +01:00
memory-lancedb fix(ci): sync plugin versions and harden install smoke 2026-02-21 20:18:37 +01:00
minimax-portal-auth fix(ci): sync plugin versions and harden install smoke 2026-02-21 20:18:37 +01:00
msteams fix(msteams): add SSRF protection to attachment downloads via redirect and DNS validation (#23598) 2026-02-22 18:00:54 -05:00
nextcloud-talk refactor(channels): reuse runtime group policy helpers 2026-02-22 12:44:23 +01:00
nostr fix(ci): sync plugin versions and harden install smoke 2026-02-21 20:18:37 +01:00
open-prose fix(ci): sync plugin versions and harden install smoke 2026-02-21 20:18:37 +01:00
phone-control style: align formatting with oxfmt 0.33 2026-02-18 01:34:35 +00:00
qwen-portal-auth TypeScript: add extensions to tsconfig and fix type errors (#12781) 2026-02-09 10:05:38 -08:00
shared refactor(extensions): dedupe connector helper usage 2026-02-16 14:59:30 +00:00
signal refactor(channels): reuse runtime group policy helpers 2026-02-22 12:44:23 +01:00
slack fix(slack extension): preserve thread IDs for read + outbound delivery (#23836) 2026-02-22 14:34:32 -05:00
synology-chat test: speed up slow media and synology suites 2026-02-22 14:18:44 +00:00
talk-voice Gateway/Plugins: device pairing + phone control plugins (#11755) 2026-02-08 18:07:13 +01:00
telegram fix(extensions): preserve mediaLocalRoots in telegram/discord sendMedia 2026-02-22 22:53:57 +01:00
thread-ownership test(extensions): cast fetch mocks to satisfy tsgo 2026-02-16 21:25:35 -05:00
tlon refactor(plugin-sdk): unify channel dedupe primitives 2026-02-22 10:46:34 +01:00
twitch refactor(security): unify secure id paths and guard weak patterns 2026-02-22 10:16:19 +01:00
voice-call fix(voice-call): harden media stream pre-start websocket handling 2026-02-22 23:25:32 +01:00
whatsapp refactor(channels): reuse runtime group policy helpers 2026-02-22 12:44:23 +01:00
zalo test(zalo): broaden webhook monitor coverage 2026-02-22 11:29:31 +00:00
zalouser refactor(channels): reuse runtime group policy helpers 2026-02-22 12:44:23 +01:00