Skip to content

fix(security): cap Slack media downloads and validate Slack file URLs#6639

Merged
steipete merged 6 commits intoopenclaw:mainfrom
davidiach:security/slack-media-guards
Feb 2, 2026
Merged

fix(security): cap Slack media downloads and validate Slack file URLs#6639
steipete merged 6 commits intoopenclaw:mainfrom
davidiach:security/slack-media-guards

Conversation

@davidiach
Copy link
Copy Markdown
Contributor

@davidiach davidiach commented Feb 1, 2026

Summary

  • Prevents accidental Slack token leakage by refusing to attach auth headers to non-Slack file hosts.
  • Ensures Slack inbound media downloads are bounded via fetchRemoteMedia(..., maxBytes).
  • Ensures outbound mediaUrl fetches used by Slack uploads are bounded at fetch-time.

Testing

  • Not run (not requested).

AI Assistance

  • AI-assisted (OpenAI Codex).
  • Prompts/logs: not included.
  • I understand the changes.

Greptile Overview

Greptile Summary

This PR hardens Slack media handling by (1) validating Slack file URLs and refusing to attach Slack Authorization headers to non-Slack hosts, (2) adding a maxBytes cap to inbound Slack media downloads via fetchRemoteMedia, and (3) ensuring outbound mediaUrl downloads in the web media loader are capped during fetch to avoid unbounded memory usage.

Changes integrate cleanly with the existing fetchRemoteMedia implementation in src/media/fetch.ts, which already supports maxBytes enforcement using both Content-Length and streaming limits. Tests in src/slack/monitor/media.test.ts cover host rejection and redirect behavior for the Slack-auth fetch wrapper.

Confidence Score: 4/5

  • This PR looks safe to merge and meaningfully improves media download safety, with small edge-case considerations around URL enforcement assumptions.
  • Key changes are localized and backed by tests for fetchWithSlackAuth behavior. maxBytes enforcement is delegated to an existing well-scoped helper (fetchRemoteMedia). Remaining concerns are mostly about future-proofing assumptions (e.g., how fetchImpl is invoked) rather than clear regressions today.
  • src/slack/monitor/media.ts (URL/host enforcement assumptions and comment accuracy)

(2/5) Greptile learns from your feedback when you react with thumbs up/down!

Context used:

  • Context from dashboard - CLAUDE.md (source)
  • Context from dashboard - AGENTS.md (source)

@openclaw-barnacle openclaw-barnacle bot added channel: slack Channel integration: slack channel: whatsapp-web Channel integration: whatsapp-web labels Feb 1, 2026
Copy link
Copy Markdown
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 file reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

Comment on lines 53 to +55
export async function fetchWithSlackAuth(url: string, token: string): Promise<Response> {
const parsed = assertSlackFileUrl(url);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] Token-leak prevention can be bypassed when callers pass a URL object (or Request) into fetchWithSlackAuth via fetchImpl.

In fetchImpl you derive inputUrl as input.href when input instanceof URL (and likely input.url for Request). For URL/Request, fetchWithSlackAuth will call assertSlackFileUrl(inputUrl, ...) on the stringified URL as expected, but for Request objects input.url is already a fully-qualified URL and may include redirects or be mutated by upstream callers. This makes the host allowlist enforcement dependent on how fetchRemoteMedia constructs input.

If fetchRemoteMedia ever passes a Request with a non-Slack URL into fetchImpl, fetchWithSlackAuth will currently still attempt the initial fetch (with token) because assertSlackFileUrl only runs on the original url parameter; it does not re-check that parsed.href matches the original Slack URL intended by the Slack file metadata.

Clarification question: does fetchRemoteMedia ever call fetchImpl with a Request instance (vs string/URL), and can that request URL differ from the url field provided to fetchRemoteMedia?

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/slack/monitor/media.ts
Line: 53:55

Comment:
[P1] Token-leak prevention can be bypassed when callers pass a URL object (or Request) into `fetchWithSlackAuth` via `fetchImpl`.

In `fetchImpl` you derive `inputUrl` as `input.href` when `input instanceof URL` (and likely `input.url` for Request). For URL/Request, `fetchWithSlackAuth` will call `assertSlackFileUrl(inputUrl, ...)` on the *stringified* URL as expected, but for `Request` objects `input.url` is already a fully-qualified URL and may include redirects or be mutated by upstream callers. This makes the host allowlist enforcement dependent on how `fetchRemoteMedia` constructs `input`.

If `fetchRemoteMedia` ever passes a `Request` with a non-Slack URL into `fetchImpl`, `fetchWithSlackAuth` will currently still attempt the initial fetch (with token) because `assertSlackFileUrl` only runs on the original `url` parameter; it does not re-check that `parsed.href` matches the original Slack URL intended by the Slack file metadata.

Clarification question: does `fetchRemoteMedia` ever call `fetchImpl` with a `Request` instance (vs string/URL), and can that request URL differ from the `url` field provided to `fetchRemoteMedia`?

How can I resolve this? If you propose a fix, please make it concise.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Feb 1, 2026

Additional Comments (1)

src/slack/monitor/media.ts
[P3] fetchImpl comment is now stale/inaccurate after adding maxBytes.

The comment says “fetchRemoteMedia only passes the URL”, but fetchRemoteMedia does pass a fetchImpl and now also uses maxBytes internally; more importantly it calls fetcher(url) (string) in src/media/fetch.ts:84, so the Request/URL branches here are currently unnecessary. Consider simplifying inputUrl derivation or updating the comment to reflect the actual call pattern so future refactors don’t accidentally reintroduce header leaks.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/slack/monitor/media.ts
Line: 104:107

Comment:
[P3] `fetchImpl` comment is now stale/inaccurate after adding `maxBytes`.

The comment says “fetchRemoteMedia only passes the URL”, but `fetchRemoteMedia` *does* pass a `fetchImpl` and now also uses `maxBytes` internally; more importantly it calls `fetcher(url)` (string) in `src/media/fetch.ts:84`, so the `Request`/`URL` branches here are currently unnecessary. Consider simplifying `inputUrl` derivation or updating the comment to reflect the actual call pattern so future refactors don’t accidentally reintroduce header leaks.

How can I resolve this? If you propose a fix, please make it concise.

@openclaw-barnacle openclaw-barnacle bot added agents Agent runtime and tooling and removed agents Agent runtime and tooling labels Feb 1, 2026
@davidiach
Copy link
Copy Markdown
Contributor Author

Greptile notes:

  • P1 (Request/URL path): fetchRemoteMedia calls fetcher(url) with the URL string today (src/media/fetch.ts), so fetchImpl receives the original Slack URL and assertSlackFileUrl runs on that value; no token is sent to arbitrary hosts.
  • P3 (stale comment): updated the fetchImpl comment in src/slack/monitor/media.ts to reflect the current call pattern and maxBytes handling.

@steipete steipete force-pushed the security/slack-media-guards branch from 05070ad to db8dec9 Compare February 2, 2026 08:45
@openclaw-barnacle openclaw-barnacle bot added the agents Agent runtime and tooling label Feb 2, 2026
@steipete steipete force-pushed the security/slack-media-guards branch from db8dec9 to 31b1968 Compare February 2, 2026 08:47
@steipete steipete merged commit 4e4ed2e into openclaw:main Feb 2, 2026
12 of 23 checks passed
@steipete
Copy link
Copy Markdown
Contributor

steipete commented Feb 2, 2026

Landed via temp rebase onto main.

  • Gate: pnpm lint && pnpm build && pnpm test (lint/build failed on existing upstream type errors; tests failed in pi-embedded-runner createSystemPromptOverride)
  • Land commit: 31b1968
  • Merge commit: 4e4ed2e

Thanks @davidiach!

xrehpicx added a commit to xrehpicx/openclaw that referenced this pull request Feb 2, 2026
Fixes build regression from openclaw#6639 where the function was changed to
return string instead of (defaultPrompt?: string) => string.

Co-authored-by: Cursor <[email protected]>
dbachelder pushed a commit to dbachelder/openclaw that referenced this pull request Feb 3, 2026
…openclaw#6639)

* Security: cap Slack media downloads and validate Slack file URLs

* Security: relax web media fetch cap for compression

* Fixes: sync pi-coding-agent options

* Fixes: align system prompt override type

* Slack: clarify fetchImpl assumptions

* fix: respect raw media fetch cap (openclaw#6639) (thanks @davidiach)

---------

Co-authored-by: Peter Steinberger <[email protected]>
claudio-neo pushed a commit to claudio-neo/openclaw that referenced this pull request Feb 3, 2026
…openclaw#6639)

* Security: cap Slack media downloads and validate Slack file URLs

* Security: relax web media fetch cap for compression

* Fixes: sync pi-coding-agent options

* Fixes: align system prompt override type

* Slack: clarify fetchImpl assumptions

* fix: respect raw media fetch cap (openclaw#6639) (thanks @davidiach)

---------

Co-authored-by: Peter Steinberger <[email protected]>
cjiewong pushed a commit to cjiewong/moltbot that referenced this pull request Feb 3, 2026
…openclaw#6639)

* Security: cap Slack media downloads and validate Slack file URLs

* Security: relax web media fetch cap for compression

* Fixes: sync pi-coding-agent options

* Fixes: align system prompt override type

* Slack: clarify fetchImpl assumptions

* fix: respect raw media fetch cap (openclaw#6639) (thanks @davidiach)

---------

Co-authored-by: Peter Steinberger <[email protected]>
HashWarlock pushed a commit to HashWarlock/openclaw that referenced this pull request Feb 4, 2026
…openclaw#6639)

* Security: cap Slack media downloads and validate Slack file URLs

* Security: relax web media fetch cap for compression

* Fixes: sync pi-coding-agent options

* Fixes: align system prompt override type

* Slack: clarify fetchImpl assumptions

* fix: respect raw media fetch cap (openclaw#6639) (thanks @davidiach)

---------

Co-authored-by: Peter Steinberger <[email protected]>
uxcu pushed a commit to uxcu/kook-openclaw that referenced this pull request Feb 5, 2026
…openclaw#6639)

* Security: cap Slack media downloads and validate Slack file URLs

* Security: relax web media fetch cap for compression

* Fixes: sync pi-coding-agent options

* Fixes: align system prompt override type

* Slack: clarify fetchImpl assumptions

* fix: respect raw media fetch cap (openclaw#6639) (thanks @davidiach)

---------

Co-authored-by: Peter Steinberger <[email protected]>
bestNiu pushed a commit to bestNiu/clawdbot that referenced this pull request Feb 5, 2026
…openclaw#6639)

* Security: cap Slack media downloads and validate Slack file URLs

* Security: relax web media fetch cap for compression

* Fixes: sync pi-coding-agent options

* Fixes: align system prompt override type

* Slack: clarify fetchImpl assumptions

* fix: respect raw media fetch cap (openclaw#6639) (thanks @davidiach)

---------

Co-authored-by: Peter Steinberger <[email protected]>
batao9 pushed a commit to batao9/openclaw that referenced this pull request Feb 7, 2026
…openclaw#6639)

* Security: cap Slack media downloads and validate Slack file URLs

* Security: relax web media fetch cap for compression

* Fixes: sync pi-coding-agent options

* Fixes: align system prompt override type

* Slack: clarify fetchImpl assumptions

* fix: respect raw media fetch cap (openclaw#6639) (thanks @davidiach)

---------

Co-authored-by: Peter Steinberger <[email protected]>
hughdidit pushed a commit to hughdidit/DAISy-Agency that referenced this pull request Feb 8, 2026
…openclaw#6639)

* Security: cap Slack media downloads and validate Slack file URLs

* Security: relax web media fetch cap for compression

* Fixes: sync pi-coding-agent options

* Fixes: align system prompt override type

* Slack: clarify fetchImpl assumptions

* fix: respect raw media fetch cap (openclaw#6639) (thanks @davidiach)

---------

Co-authored-by: Peter Steinberger <[email protected]>
(cherry picked from commit 4e4ed2e)

# Conflicts:
#	CHANGELOG.md
FullStackKevinVanDriel pushed a commit to FullStackKevinVanDriel/openclaw that referenced this pull request Feb 10, 2026
…openclaw#6639)

* Security: cap Slack media downloads and validate Slack file URLs

* Security: relax web media fetch cap for compression

* Fixes: sync pi-coding-agent options

* Fixes: align system prompt override type

* Slack: clarify fetchImpl assumptions

* fix: respect raw media fetch cap (openclaw#6639) (thanks @davidiach)

---------

Co-authored-by: Peter Steinberger <[email protected]>
battman21 pushed a commit to battman21/openclaw that referenced this pull request Feb 12, 2026
…openclaw#6639)

* Security: cap Slack media downloads and validate Slack file URLs

* Security: relax web media fetch cap for compression

* Fixes: sync pi-coding-agent options

* Fixes: align system prompt override type

* Slack: clarify fetchImpl assumptions

* fix: respect raw media fetch cap (openclaw#6639) (thanks @davidiach)

---------

Co-authored-by: Peter Steinberger <[email protected]>
battman21 pushed a commit to battman21/openclaw that referenced this pull request Feb 12, 2026
…openclaw#6639)

* Security: cap Slack media downloads and validate Slack file URLs

* Security: relax web media fetch cap for compression

* Fixes: sync pi-coding-agent options

* Fixes: align system prompt override type

* Slack: clarify fetchImpl assumptions

* fix: respect raw media fetch cap (openclaw#6639) (thanks @davidiach)

---------

Co-authored-by: Peter Steinberger <[email protected]>
jiulingyun added a commit to jiulingyun/openclaw-cn that referenced this pull request Feb 15, 2026
hughdidit added a commit to hughdidit/DAISy-Agency that referenced this pull request Mar 1, 2026
* fix(security): harden SSH target handling (openclaw#4001)

Thanks @YLChen-007.

Co-authored-by: Edward-x <[email protected]>
(cherry picked from commit 06289b3)

# Conflicts:
#	src/plugins/config-state.ts

* chore(release): bump versions to 2026.1.29

(cherry picked from commit cb4b3f7)

* refactor: rename to openclaw

(cherry picked from commit 9a71607)

# Conflicts:
#	CHANGELOG.md
#	README.md
#	src/agents/bash-tools.test.ts
#	src/auto-reply/reply/dispatch-from-config.test.ts
#	src/canvas-host/server.test.ts
#	src/media-understanding/apply.test.ts
#	src/plugins/loader.ts
#	ui/src/ui/app-chat.ts
#	ui/src/ui/app-gateway.ts

* chore: bump npm version

(cherry picked from commit 7d03cae)

* chore: bump beta

(cherry picked from commit 67918dc)

# Conflicts:
#	package.json

* chore: bump beta

(cherry picked from commit d9c8199)

# Conflicts:
#	package.json

* chore: update pnpm lockfile

(cherry picked from commit c5d7d11)

* docs: clarify security scope

(cherry picked from commit 2cdfecd)

* fix(security): prevent gateway token from defaulting to 'undefined' string

(cherry picked from commit 201d7fa)

* fix(security): restrict local path extraction in media parser to prevent LFI (openclaw#4880)

* Media: restrict local path extraction to prevent LFI

* Lint: remove unused variable hasValidMediaOnLine

(cherry picked from commit c67df65)

* Agents: update pi dependencies to 0.50.7

(cherry picked from commit c0a6e67)

* chore: update deps and pi model discovery

(cherry picked from commit 08ed628)

# Conflicts:
#	docs/index.md
#	src/agents/pi-embedded-runner/model.test.ts
#	src/commands/auth-choice.apply.oauth.ts
#	src/commands/models.list.test.ts
#	src/commands/onboard-auth.credentials.ts

* chore: Switch from TypeScript to build with `tsdown`, speeds up `pnpm build` by 5-10x.

(cherry picked from commit 67945e8)

* Switch from TypeScript to TypeScript Go. Use `pnpm tsgo` for Typechecks.

(cherry picked from commit 7626522)

* chore: Remove unused deps.

(cherry picked from commit 88fe4de)

# Conflicts:
#	package.json

* chore: Oops, "long" is actually used + fix TypeScript error.

(cherry picked from commit 86d38c2)

# Conflicts:
#	src/imessage/send.ts

* chore: `signal-utils` is actually used too.

(cherry picked from commit d4ed79f)

* build: add typescript for a2ui bundling

(cherry picked from commit 1766cd4)

* revert: Switch back to `tsc` for compiling.

(cherry picked from commit 76361ae)

# Conflicts:
#	openclaw.mjs
#	scripts/postinstall.js
#	scripts/run-node.mjs
#	scripts/watch-node.mjs
#	src/cli/browser-cli.test.ts
#	src/infra/control-ui-assets.ts
#	src/infra/gateway-lock.ts

* chore: bump version to 2026.1.30

(cherry picked from commit 247fab4)

# Conflicts:
#	CHANGELOG.md
#	extensions/bluebubbles/package.json
#	extensions/copilot-proxy/package.json
#	extensions/diagnostics-otel/package.json
#	extensions/discord/package.json
#	extensions/google-antigravity-auth/package.json
#	extensions/google-gemini-cli-auth/package.json
#	extensions/googlechat/package.json
#	extensions/imessage/package.json
#	extensions/line/package.json
#	extensions/llm-task/package.json
#	extensions/lobster/package.json
#	extensions/matrix/package.json
#	extensions/mattermost/package.json
#	extensions/memory-core/package.json
#	extensions/memory-lancedb/package.json
#	extensions/msteams/package.json
#	extensions/nextcloud-talk/package.json
#	extensions/nostr/package.json
#	extensions/open-prose/package.json
#	extensions/signal/package.json
#	extensions/slack/package.json
#	extensions/telegram/package.json
#	extensions/tlon/package.json
#	extensions/twitch/package.json
#	extensions/voice-call/package.json
#	extensions/whatsapp/package.json
#	extensions/zalo/package.json
#	extensions/zalouser/package.json
#	package.json

* feat: add MiniMax OAuth plugin (openclaw#4521) (thanks @Maosghoul)

(cherry picked from commit 1287328)

# Conflicts:
#	README.md
#	src/agents/auth-profiles/external-cli-sync.ts
#	src/agents/model-auth.ts
#	src/commands/auth-choice-options.ts

* chore: Add `openclaw` to `devDependencies` for all extensions so that types resolve.

(cherry picked from commit aa91f6e)

# Conflicts:
#	extensions/bluebubbles/package.json
#	extensions/copilot-proxy/package.json
#	extensions/diagnostics-otel/package.json
#	extensions/discord/package.json
#	extensions/google-antigravity-auth/package.json
#	extensions/google-gemini-cli-auth/package.json
#	extensions/imessage/package.json
#	extensions/llm-task/package.json
#	extensions/lobster/package.json
#	extensions/mattermost/package.json
#	extensions/minimax-portal-auth/package.json
#	extensions/msteams/package.json
#	extensions/nextcloud-talk/package.json
#	extensions/nostr/package.json
#	extensions/open-prose/package.json
#	extensions/signal/package.json
#	extensions/slack/package.json
#	extensions/telegram/package.json
#	extensions/tlon/package.json
#	extensions/whatsapp/package.json
#	extensions/zalo/package.json

* fix: align npm publish metadata

(cherry picked from commit 7d89855)

* fix(security): restrict MEDIA path extraction to prevent LFI (openclaw#4930)

* fix(security): restrict inbound media staging to media directory

* docs: update MEDIA path guidance for security restrictions

- Update agent hint to warn against absolute/~ paths
- Update docs example to use https:// instead of /tmp/

---------

Co-authored-by: Evan Otero <[email protected]>
(cherry picked from commit 34e2425)

* fix(agents): update cacheControlTtl to cacheRetention for pi-ai 0.50.9

- Update @mariozechner/pi-ai and pi-agent-core to 0.50.9
- Rename cacheControlTtl to cacheRetention with values none/short/long
- Add backwards compatibility mapping: 5m->short, 1h->long
- Remove dead OpenRouter check (uses openai-completions API)
- Default new configs to cacheRetention: short

(cherry picked from commit ba4a55f)

# Conflicts:
#	src/agents/pi-embedded-runner/extra-params.ts
#	src/config/defaults.ts

* security(message-tool): validate filePath/path against sandbox root (openclaw#6398)

* security(message-tool): validate filePath/path against sandbox root

* style: translate Polish comments to English for consistency

(cherry picked from commit 9b6fffd)

# Conflicts:
#	src/agents/tools/message-tool.ts

* security(web): sanitize WhatsApp accountId to prevent path traversal (openclaw#4610)

* security(web): sanitize WhatsApp accountId to prevent path traversal

Apply normalizeAccountId() from routing/session-key to
resolveDefaultAuthDir() so that malicious config values like
"../../../etc" cannot escape the intended auth directory.

Fixes openclaw#2692

* fix(web): check sanitized segment instead of full path in Windows test

* style(web): fix oxfmt formatting in accounts test

(cherry picked from commit 1bdd9e3)

# Conflicts:
#	src/web/accounts.ts

* fix: override vulnerable transitive deps

(cherry picked from commit 2601f41)

# Conflicts:
#	package.json

* fix: override request dependency

(cherry picked from commit e4d5721)

* Revert "fix: override request dependency"

This reverts commit e4d5721.

(cherry picked from commit e550e25)

* Security: harden web tools and file parsing (openclaw#4058)

* feat: web content security wrapping + gkeep/simple-backup skills

* fix: harden web fetch + media text detection (openclaw#4058) (thanks @VACInc)

---------

Co-authored-by: VAC <[email protected]>
Co-authored-by: Peter Steinberger <[email protected]>
(cherry picked from commit b796f6e)

# Conflicts:
#	CHANGELOG.md
#	docs/providers/moonshot.md
#	src/agents/tools/web-fetch.ts
#	src/agents/tools/web-search.ts
#	src/commands/onboard-non-interactive.gateway.test.ts
#	src/media-understanding/apply.ts

* fix(security): enforce strict environment variable validation in exec tool (openclaw#4896)

(cherry picked from commit 0a5821a)

# Conflicts:
#	src/agents/bash-tools.exec.path.test.ts

* fix: update pi packages to 0.51.0, remove bogus type augmentation

- Update @mariozechner/pi-agent-core, pi-ai, pi-coding-agent, pi-tui to 0.51.0
- Delete src/types/pi-coding-agent.d.ts (declared additionalExtensionPaths which SDK never supported)
- Fix ToolDefinition.execute signature (parameter order changed in 0.51.0)
- Remove dead additionalExtensionPaths from createAgentSession calls

(cherry picked from commit cf1d3f7)

* chore: Update deps.

(cherry picked from commit bd259ee)

* fix(security): cap Slack media downloads and validate Slack file URLs (openclaw#6639)

* Security: cap Slack media downloads and validate Slack file URLs

* Security: relax web media fetch cap for compression

* Fixes: sync pi-coding-agent options

* Fixes: align system prompt override type

* Slack: clarify fetchImpl assumptions

* fix: respect raw media fetch cap (openclaw#6639) (thanks @davidiach)

---------

Co-authored-by: Peter Steinberger <[email protected]>
(cherry picked from commit 4e4ed2e)

# Conflicts:
#	CHANGELOG.md

* chore: bump to 2026.2.1

(cherry picked from commit 85cd55e)

# Conflicts:
#	CHANGELOG.md
#	docs/platforms/mac/release.md
#	extensions/bluebubbles/package.json
#	extensions/copilot-proxy/package.json
#	extensions/diagnostics-otel/package.json
#	extensions/discord/package.json
#	extensions/google-antigravity-auth/package.json
#	extensions/google-gemini-cli-auth/package.json
#	extensions/googlechat/package.json
#	extensions/imessage/package.json
#	extensions/line/package.json
#	extensions/llm-task/package.json
#	extensions/lobster/package.json
#	extensions/matrix/package.json
#	extensions/mattermost/package.json
#	extensions/memory-core/package.json
#	extensions/memory-lancedb/package.json
#	extensions/minimax-portal-auth/package.json
#	extensions/msteams/package.json
#	extensions/nextcloud-talk/package.json
#	extensions/nostr/package.json
#	extensions/open-prose/package.json
#	extensions/signal/package.json
#	extensions/slack/package.json
#	extensions/telegram/package.json
#	extensions/tlon/package.json
#	extensions/twitch/package.json
#	extensions/voice-call/package.json
#	extensions/whatsapp/package.json
#	extensions/zalo/package.json
#	extensions/zalouser/package.json
#	package.json
#	src/agents/auth-profiles/oauth.ts

* chore: Update deps.

(cherry picked from commit 9e3ea26)

# Conflicts:
#	extensions/matrix/package.json

* Security: new openclaw-system-admin skill + bootstrap audit

(cherry picked from commit a6afcb4)

* Security: rename openclaw-system-admin skill to healthcheck

(cherry picked from commit cdec53b)

* Security: remove openclaw-system-admin skill path

(cherry picked from commit 1523ef2)

* Security: refine healthcheck workflow

(cherry picked from commit e2c0384)

* Security: healthcheck skill (openclaw#7641) (thanks @Takhoffman)

(cherry picked from commit 578bde1)

# Conflicts:
#	CHANGELOG.md

* Security: tune bootstrap healthcheck prompt + healthcheck wording

(cherry picked from commit 83715ec)

# Conflicts:
#	docs/reference/templates/BOOTSTRAP.md
#	skills/healthcheck/SKILL.md

* chore: Migrate to tsdown, speed up JS bundling by ~10x (thanks @hyf0).

The previous migration to tsdown was reverted because it caused a ~20x slowdown when running OpenClaw from the repo. @hyf0 investigated and found that simply renaming the `dist` folder also caused the same slowdown. It turns out the Plugin script loader has a bunch of voodoo vibe logic to determine if it should load files from source and compile them, or if it should load them from dist. When building with tsdown, the filesystem layout is different (bundled), and so some files weren't in the right location, and the Plugin script loader decided to compile source files from scratch using Jiti.

The new implementation uses tsdown to embed `NODE_ENV: 'production'`, which we now use to determine if we are running OpenClaw from a "production environmen" (ie. from dist). This removes the slop in favor of a deterministic toggle, and doesn't rely on directory names or similar.

There is some code reaching into `dist` to load specific modules, primarily in the voice-call extension, which I simplified into loading an "officially" exported `extensionAPI.js` file. With tsdown, entry points need to be explicitly configured, so we should be able to avoid sloppy code reaching into internals from now on. This might break some existing users, but if it does, it's because they were using "private" APIs.

(cherry picked from commit a03d852)

# Conflicts:
#	package.json
#	scripts/postinstall.js
#	scripts/run-node.mjs
#	scripts/watch-node.mjs

* Channels: finish Feishu/Lark integration

(cherry picked from commit 0223416)

# Conflicts:
#	CHANGELOG.md
#	src/discord/monitor.tool-result.accepts-guild-messages-mentionpatterns-match.test.ts

* chore: bump version to 2026.2.2-1

(cherry picked from commit e59eb81)

# Conflicts:
#	CHANGELOG.md
#	package.json

* chore: bump version to 2026.2.3

(cherry picked from commit e4b084c)

# Conflicts:
#	CHANGELOG.md
#	apps/android/app/build.gradle.kts
#	apps/ios/Sources/Info.plist
#	apps/ios/Tests/Info.plist
#	apps/ios/project.yml
#	apps/macos/Sources/OpenClaw/Resources/Info.plist
#	docs/platforms/mac/release.md
#	package.json

* fix(security): separate untrusted channel metadata from system prompt (thanks @KonstantinMirin)

(cherry picked from commit 35eb40a)

# Conflicts:
#	CHANGELOG.md
#	src/discord/monitor/message-handler.process.ts
#	src/slack/monitor/message-handler/prepare.ts
#	src/slack/monitor/slash.ts

* TUI/Gateway: fix pi streaming + tool routing + model display + msg updating (openclaw#8432)

* TUI/Gateway: fix pi streaming + tool routing

* Tests: clarify verbose tool output expectation

* fix: avoid seq gaps for targeted tool events (openclaw#8432) (thanks @gumadeiras)

(cherry picked from commit 38e6da1)

# Conflicts:
#	CHANGELOG.md
#	src/agents/pi-embedded-subscribe.handlers.types.ts
#	src/agents/pi-embedded-subscribe.ts
#	src/gateway/server-broadcast.ts
#	src/gateway/server-chat.agent-events.test.ts
#	src/gateway/server-chat.ts
#	src/gateway/server-methods/agent.ts
#	src/gateway/server-methods/chat.ts
#	src/gateway/server-methods/sessions.ts
#	src/gateway/sessions-patch.ts
#	src/tui/tui-command-handlers.ts
#	src/tui/tui-event-handlers.test.ts
#	src/tui/tui-event-handlers.ts
#	src/tui/tui-session-actions.ts

* Security: Prevent gateway credential exfiltration via URL override (openclaw#9179)

* Gateway: require explicit auth for url overrides

* Gateway: scope credential blocking to non-local URLs only

Address review feedback: the previous fix blocked credential fallback for
ALL URL overrides, which was overly strict and could break workflows that
use --url to switch between loopback/tailnet without passing credentials.

Now credential fallback is only blocked for non-local URLs (public IPs,
external hostnames). Local addresses (127.0.0.1, localhost, private IPs
like 192.168.x.x, 10.x.x.x, tailnet 100.x.x.x) still get credential
fallback as before.

This maintains the security fix (preventing credential exfiltration to
attacker-controlled URLs) while preserving backward compatibility for
legitimate local URL overrides.

* Security: require explicit credentials for gateway url overrides (openclaw#8113) (thanks @victormier)

* Gateway: reuse explicit auth helper for url overrides (openclaw#8113) (thanks @victormier)

* Tests: format gateway chat test (openclaw#8113) (thanks @victormier)

* Tests: require explicit auth for gateway url overrides (openclaw#8113) (thanks @victormier)

---------

Co-authored-by: Victor Mier <[email protected]>
(cherry picked from commit a13ff55)

# Conflicts:
#	CHANGELOG.md

* Security: harden sandboxed media handling (openclaw#9182)

* Message: enforce sandbox for media param

* fix: harden sandboxed media handling (openclaw#8780) (thanks @victormier)

* chore: format message action runner (openclaw#8780) (thanks @victormier)

---------

Co-authored-by: Victor Mier <[email protected]>
(cherry picked from commit 4434cae)

# Conflicts:
#	CHANGELOG.md
#	src/agents/tools/message-tool.ts
#	src/infra/outbound/message-action-runner.ts

* Security: owner-only tools + command auth hardening (openclaw#9202)

* Security: gate whatsapp_login by sender auth

* Security: treat undefined senderAuthorized as unauthorized (opt-in)

* fix: gate whatsapp_login to owner senders (openclaw#8768) (thanks @victormier)

* fix: add explicit owner allowlist for tools (openclaw#8768) (thanks @victormier)

* fix: normalize escaped newlines in send actions (openclaw#8768) (thanks @victormier)

---------

Co-authored-by: Victor Mier <[email protected]>
(cherry picked from commit 392bbdd)

# Conflicts:
#	CHANGELOG.md
#	src/agents/pi-tools.ts
#	src/auto-reply/command-auth.ts

* Tests: add test coverage for security/windows-acl.ts

Adds comprehensive unit tests for Windows ACL inspection utilities:
- resolveWindowsUserPrincipal: username resolution with fallback
- parseIcaclsOutput: icacls output parsing
- summarizeWindowsAcl: ACL entry classification (trusted/world/group)
- inspectWindowsAcl: async ACL inspection with mocked exec
- formatWindowsAclSummary: summary string formatting
- formatIcaclsResetCommand: reset command string generation
- createIcaclsResetCommand: structured reset command generation

All 26 tests passing.

Co-Authored-By: Claude Opus 4.5 <[email protected]>
(cherry picked from commit f26cc60)

* chore: bump version to 2026.2.4

(cherry picked from commit 5031b28)

# Conflicts:
#	CHANGELOG.md
#	appcast.xml
#	apps/android/app/build.gradle.kts
#	apps/ios/Sources/Info.plist
#	apps/ios/Tests/Info.plist
#	apps/ios/project.yml
#	apps/macos/Sources/OpenClaw/Resources/Info.plist
#	docs/platforms/mac/release.md
#	extensions/bluebubbles/package.json
#	extensions/copilot-proxy/package.json
#	extensions/diagnostics-otel/package.json
#	extensions/discord/package.json
#	extensions/feishu/package.json
#	extensions/google-antigravity-auth/package.json
#	extensions/google-gemini-cli-auth/package.json
#	extensions/googlechat/package.json
#	extensions/imessage/package.json
#	extensions/line/package.json
#	extensions/llm-task/package.json
#	extensions/lobster/package.json
#	extensions/matrix/CHANGELOG.md
#	extensions/matrix/package.json
#	extensions/mattermost/package.json
#	extensions/memory-core/package.json
#	extensions/memory-lancedb/package.json
#	extensions/minimax-portal-auth/package.json
#	extensions/msteams/CHANGELOG.md
#	extensions/msteams/package.json
#	extensions/nextcloud-talk/package.json
#	extensions/nostr/CHANGELOG.md
#	extensions/nostr/package.json
#	extensions/open-prose/package.json
#	extensions/signal/package.json
#	extensions/slack/package.json
#	extensions/telegram/package.json
#	extensions/tlon/package.json
#	extensions/twitch/CHANGELOG.md
#	extensions/twitch/package.json
#	extensions/voice-call/CHANGELOG.md
#	extensions/voice-call/package.json
#	extensions/whatsapp/package.json
#	extensions/zalo/CHANGELOG.md
#	extensions/zalo/package.json
#	extensions/zalouser/CHANGELOG.md
#	extensions/zalouser/package.json
#	package.json

* Update deps.

(cherry picked from commit 460808e)

# Conflicts:
#	package.json

* feat: add Claude Opus 4.6 to built-in model catalog (openclaw#9853)

* feat: add Claude Opus 4.6 to built-in model catalog

- Update default model from claude-opus-4-5 to claude-opus-4-6
- Add opus-4.6 model ID normalization
- Add claude-opus-4-6 to live model filter prefixes
- Update image tool to prefer claude-opus-4-6 for vision
- Add CLI backend alias for opus-4.6
- Update onboard auth default selections to include opus-4.6
- Update model picker placeholder

Closes openclaw#9811

* test: update tests for claude-opus-4-6 default

- Fix model-alias-defaults test to use claude-opus-4-6
- Fix image-tool test to expect claude-opus-4-6 in fallbacks

* feat: support claude-opus-4-6

* docs: update changelog for opus 4.6 (openclaw#9853) (thanks @TinyTb)

* chore: bump pi to 0.52.0

---------

Co-authored-by: Slurpy <[email protected]>
Co-authored-by: Peter Steinberger <[email protected]>
(cherry picked from commit eb80b9a)

# Conflicts:
#	CHANGELOG.md
#	src/agents/model-selection.ts
#	src/agents/tools/image-tool.ts

* fix(runtime): bump minimum Node.js version to 22.12.0 (openclaw#5370)

* fix(runtime): bump minimum Node.js version to 22.12.0

Aligns the runtime guard with the declared package.json engines requirement.

The Matrix plugin (and potentially others) requires Node >= 22.12.0,
but the runtime guard previously allowed 22.0.0+. This caused confusing
errors like 'Cannot find module @vector-im/matrix-bot-sdk' when the real
issue was an unsupported Node version.

- Update MIN_NODE from 22.0.0 to 22.12.0
- Update error message to reflect the correct version
- Update tests to use 22.12.0 as the minimum valid version

Fixes openclaw#5292

* fix: update test versions to match MIN_NODE=22.12.0

---------

Co-authored-by: Markus Glucksberg <[email protected]>
(cherry picked from commit 2ca78a8)

* chore: apply local workspace updates (openclaw#9911)

* chore: apply local workspace updates

* fix: resolve prep findings after rebase (openclaw#9898) (thanks @gumadeiras)

* refactor: centralize model allowlist normalization (openclaw#9898) (thanks @gumadeiras)

* fix: guard model allowlist initialization (openclaw#9911)

* docs: update changelog scope for openclaw#9911

* docs: remove model names from changelog entry (openclaw#9911)

* fix: satisfy type-aware lint in model allowlist (openclaw#9911)

(cherry picked from commit 4629054)

# Conflicts:
#	README.md
#	docs/bedrock.md
#	docs/concepts/model-providers.md
#	docs/concepts/models.md
#	docs/concepts/multi-agent.md
#	docs/gateway/cli-backends.md
#	docs/gateway/configuration-examples.md
#	docs/gateway/configuration.md
#	docs/gateway/heartbeat.md
#	docs/gateway/local-models.md
#	docs/help/faq.md
#	docs/providers/anthropic.md
#	docs/providers/index.md
#	docs/providers/minimax.md
#	docs/providers/models.md
#	docs/providers/openai.md
#	docs/providers/opencode.md
#	docs/providers/vercel-ai-gateway.md
#	docs/start/wizard-cli-reference.md
#	scripts/docs-i18n/util.go
#	src/agents/model-fallback.ts
#	src/agents/model-selection.ts
#	src/commands/auth-choice.apply.openai.ts
#	src/commands/onboard-non-interactive/local/auth-choice.ts

* docs: improve DM security guidance with concrete example

Add a more prominent security warning for multi-user DM setups:
- Add blockquote security warning about context leakage
- Include concrete example showing the privacy risk
- Add "When to enable this" checklist
- Clarify that default is fine for single-user setups

Co-Authored-By: Claude Opus 4.5 <[email protected]>
(cherry picked from commit b8004a2)

# Conflicts:
#	docs/concepts/session.md

* Agents: bump pi-mono to 0.52.5 (openclaw#9949)

* Agents: bump pi-mono to 0.52.5

* Changelog: add PR reference for pi bump

(cherry picked from commit 3299aeb)

# Conflicts:
#	CHANGELOG.md

* security: add skill/plugin code safety scanner (openclaw#9806)

* security: add skill/plugin code safety scanner module

* security: integrate skill scanner into security audit

* security: add pre-install code safety scan for plugins

* style: fix curly brace lint errors in skill-scanner.ts

* docs: add changelog entry for skill code safety scanner

* style: append ellipsis to truncated evidence strings

* fix(security): harden plugin code safety scanning

* fix: scan skills on install and report code-safety details

* fix: dedupe audit-extra import

* fix(security): make code safety scan failures observable

* fix(test): stabilize smoke + gateway timeouts (openclaw#9806) (thanks @abdelsfane)

---------

Co-authored-by: Darshil <[email protected]>
Co-authored-by: Darshil <[email protected]>
Co-authored-by: George Pickett <[email protected]>
(cherry picked from commit bc88e58)

# Conflicts:
#	src/commands/onboard-skills.ts
#	src/gateway/test-helpers.server.ts
#	src/plugins/install.test.ts
#	src/plugins/install.ts
#	src/security/audit-extra.ts
#	src/security/audit.test.ts

* chore: Update deps.

(cherry picked from commit 6f4665d)

# Conflicts:
#	extensions/memory-lancedb/package.json

* chore: update pnpm-lock.yaml for feishu extension deps

Add lockfile entries for:
- @larksuiteoapi/node-sdk@^1.56.1
- @sinclair/[email protected]
- zod@^4.3.6

Co-Authored-By: Claude Opus 4.5 <[email protected]>
(cherry picked from commit 7e005ac)

* security: redact credentials from config.get gateway responses (openclaw#9858)

* security: add skill/plugin code safety scanner module

* security: integrate skill scanner into security audit

* security: add pre-install code safety scan for plugins

* style: fix curly brace lint errors in skill-scanner.ts

* docs: add changelog entry for skill code safety scanner

* security: redact credentials from config.get gateway responses

The config.get gateway method returned the full config snapshot
including channel credentials (Discord tokens, Slack botToken/appToken,
Telegram botToken, Feishu appSecret, etc.), model provider API keys,
and gateway auth tokens in plaintext.

Any WebSocket client—including the unauthenticated Control UI when
dangerouslyDisableDeviceAuth is set—could read every secret.

This adds redactConfigSnapshot() which:
- Deep-walks the config object and masks any field whose key matches
  token, password, secret, or apiKey patterns
- Uses the existing redactSensitiveText() to scrub the raw JSON5 source
- Preserves the hash for change detection
- Includes 15 test cases covering all channel types

* security: make gateway config writes return redacted values

* test: disable control UI by default in gateway server tests

* fix: redact credentials in gateway config APIs (openclaw#9858) (thanks @abdelsfane)

---------

Co-authored-by: George Pickett <[email protected]>
(cherry picked from commit 0c7fa2b)

# Conflicts:
#	CHANGELOG.md
#	src/gateway/server.config-patch.e2e.test.ts

* chore(release): bump version to 2026.2.6

(cherry picked from commit 677450c)

# Conflicts:
#	apps/android/app/build.gradle.kts
#	apps/ios/Sources/Info.plist
#	apps/ios/Tests/Info.plist
#	apps/ios/project.yml
#	apps/macos/Sources/OpenClaw/Resources/Info.plist
#	docs/platforms/mac/release.md
#	extensions/bluebubbles/package.json
#	extensions/copilot-proxy/package.json
#	extensions/diagnostics-otel/package.json
#	extensions/discord/package.json
#	extensions/feishu/package.json
#	extensions/google-antigravity-auth/package.json
#	extensions/google-gemini-cli-auth/package.json
#	extensions/googlechat/package.json
#	extensions/imessage/package.json
#	extensions/line/package.json
#	extensions/llm-task/package.json
#	extensions/lobster/package.json
#	extensions/matrix/CHANGELOG.md
#	extensions/matrix/package.json
#	extensions/mattermost/package.json
#	extensions/memory-core/package.json
#	extensions/memory-lancedb/package.json
#	extensions/minimax-portal-auth/package.json
#	extensions/msteams/CHANGELOG.md
#	extensions/msteams/package.json
#	extensions/nextcloud-talk/package.json
#	extensions/nostr/CHANGELOG.md
#	extensions/nostr/package.json
#	extensions/open-prose/package.json
#	extensions/signal/package.json
#	extensions/slack/package.json
#	extensions/telegram/package.json
#	extensions/tlon/package.json
#	extensions/twitch/CHANGELOG.md
#	extensions/twitch/package.json
#	extensions/voice-call/CHANGELOG.md
#	extensions/voice-call/package.json
#	extensions/whatsapp/package.json
#	extensions/zalo/CHANGELOG.md
#	extensions/zalo/package.json
#	extensions/zalouser/CHANGELOG.md
#	extensions/zalouser/package.json
#	package.json

* chore(deps): update deps

(cherry picked from commit dca8cf9)

# Conflicts:
#	extensions/feishu/package.json
#	extensions/memory-lancedb/package.json
#	package.json

* chore(deps): bump carbon beta

(cherry picked from commit 94b2fc1)

* chore(lockfile): fix pnpm-lock

(cherry picked from commit 0dd7033)

* chore: bump pi to 0.52.8

(cherry picked from commit ff80646)

* chore: project hygiene — fix workspace:*, sandbox USER, dead config (openclaw#11289)

* chore: project hygiene fixes (workspace:*, sandbox USER, dead config)

* chore: also fix workspace:* in zalouser dependencies

(cherry picked from commit 28e1a65)

# Conflicts:
#	CHANGELOG.md
#	extensions/zalouser/package.json
#	package.json
#	pnpm-workspace.yaml

* docs: add security & trust documentation

Add threat model (MITRE ATLAS), contribution guide, and security
directory README. Update SECURITY.md with trust page reporting
instructions and Jamieson O'Reilly as Security & Trust.

Co-Authored-By: theonejvo <[email protected]>
(cherry picked from commit 74fbbda)

---------

Co-authored-by: Peter Steinberger <[email protected]>
Co-authored-by: Hisleren <[email protected]>
Co-authored-by: Evan Otero <[email protected]>
Co-authored-by: Mario Zechner <[email protected]>
Co-authored-by: cpojer <[email protected]>
Co-authored-by: Glucksberg <[email protected]>
Co-authored-by: Evan Otero <[email protected]>
Co-authored-by: Leszek Szpunar <[email protected]>
Co-authored-by: VACInc <[email protected]>
Co-authored-by: Hasan FLeyah <[email protected]>
Co-authored-by: David Iach <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
Co-authored-by: Josh Palmer <[email protected]>
Co-authored-by: Gustavo Madeira Santana <[email protected]>
Co-authored-by: M00N7682 <[email protected]>
Co-authored-by: Claude Opus 4.5 <[email protected]>
Co-authored-by: Michael Lee <[email protected]>
Co-authored-by: Markus Glucksberg <[email protected]>
Co-authored-by: Shrinija Kummari <[email protected]>
Co-authored-by: Abdel Sy Fane <[email protected]>
Co-authored-by: Yifeng Wang <[email protected]>
Co-authored-by: Gustavo Madeira Santana <[email protected]>
Co-authored-by: max <[email protected]>
Co-authored-by: theonejvo <[email protected]>
Co-authored-by: hughdidit <[email protected]>
hughdidit pushed a commit to hughdidit/DAISy-Agency that referenced this pull request Mar 3, 2026
…openclaw#6639)

* Security: cap Slack media downloads and validate Slack file URLs

* Security: relax web media fetch cap for compression

* Fixes: sync pi-coding-agent options

* Fixes: align system prompt override type

* Slack: clarify fetchImpl assumptions

* fix: respect raw media fetch cap (openclaw#6639) (thanks @davidiach)

---------

Co-authored-by: Peter Steinberger <[email protected]>
(cherry picked from commit 4e4ed2e)

# Conflicts:
#	CHANGELOG.md
zooqueen pushed a commit to hanzoai/bot that referenced this pull request Mar 6, 2026
…openclaw#6639)

* Security: cap Slack media downloads and validate Slack file URLs

* Security: relax web media fetch cap for compression

* Fixes: sync pi-coding-agent options

* Fixes: align system prompt override type

* Slack: clarify fetchImpl assumptions

* fix: respect raw media fetch cap (openclaw#6639) (thanks @davidiach)

---------

Co-authored-by: Peter Steinberger <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling channel: slack Channel integration: slack channel: whatsapp-web Channel integration: whatsapp-web

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants