Skip to content

fix: limit outgoing webhook response size to prevent memory exhaustion#38760

Merged
kodiakhq[bot] merged 5 commits intoRocketChat:developfrom
Khizarshah01:fix/webhook-response-size-limit
Feb 22, 2026
Merged

fix: limit outgoing webhook response size to prevent memory exhaustion#38760
kodiakhq[bot] merged 5 commits intoRocketChat:developfrom
Khizarshah01:fix/webhook-response-size-limit

Conversation

@Khizarshah01
Copy link
Copy Markdown
Contributor

@Khizarshah01 Khizarshah01 commented Feb 17, 2026

Proposed changes (including videos or screenshots)

Enforced a 10MB size limit on the fetch request for Outgoing Webhooks in triggerHandler.ts
Currently, the triggerHandler.ts fetches webhook responses without specifying a size limit. If an integration endpoint returns an unexpectedly large response (e.g., infinite stream or large file), the Node.js process attempts to buffer the entire content into memory using res.text(). This leads to a (OOM) crash and terminates the server.

Before (Buggy)

Screencast.from.2026-02-18.02-34-22.mp4

After (fixed)

Screencast.from.2026-02-18.02-27-25.mp4

Issue(s)

Fixes #38758
COMM-144

Further comments

I chose 10MB as the limit because standard JSON payloads for webhooks are typically much smaller (<1MB). This limit allows for legitimate large responses while sufficiently protecting the server from OOM exploits or misconfigurations.

Summary by CodeRabbit

  • Improvements
    • Outgoing webhook responses are now limited to 10 MB.
  • Chores
    • Added a patch release changelog entry for the update.

@Khizarshah01 Khizarshah01 requested a review from a team as a code owner February 17, 2026 21:11
@dionisio-bot
Copy link
Copy Markdown
Contributor

dionisio-bot bot commented Feb 17, 2026

Looks like this PR is not ready to merge, because of the following issues:

  • This PR is targeting the wrong base branch. It should target 8.3.0, but it targets 8.2.0

Please fix the issues and try again

If you have any trouble, please check the PR guidelines

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Feb 17, 2026

🦋 Changeset detected

Latest commit: c78fc78

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 41 packages
Name Type
@rocket.chat/meteor Patch
@rocket.chat/core-typings Patch
@rocket.chat/rest-typings Patch
@rocket.chat/uikit-playground Patch
@rocket.chat/api-client Patch
@rocket.chat/apps Patch
@rocket.chat/core-services Patch
@rocket.chat/cron Patch
@rocket.chat/ddp-client Patch
@rocket.chat/fuselage-ui-kit Patch
@rocket.chat/gazzodown Patch
@rocket.chat/http-router Patch
@rocket.chat/livechat Patch
@rocket.chat/model-typings Patch
@rocket.chat/ui-avatar Patch
@rocket.chat/ui-client Patch
@rocket.chat/ui-contexts Patch
@rocket.chat/ui-voip Patch
@rocket.chat/web-ui-registration Patch
@rocket.chat/account-service Patch
@rocket.chat/authorization-service Patch
@rocket.chat/ddp-streamer Patch
@rocket.chat/omnichannel-transcript Patch
@rocket.chat/presence-service Patch
@rocket.chat/queue-worker Patch
@rocket.chat/abac Patch
@rocket.chat/federation-matrix Patch
@rocket.chat/license Patch
@rocket.chat/media-calls Patch
@rocket.chat/omnichannel-services Patch
@rocket.chat/pdf-worker Patch
@rocket.chat/presence Patch
rocketchat-services Patch
@rocket.chat/models Patch
@rocket.chat/network-broker Patch
@rocket.chat/omni-core-ee Patch
@rocket.chat/mock-providers Patch
@rocket.chat/ui-video-conf Patch
@rocket.chat/instance-status Patch
@rocket.chat/omni-core Patch
@rocket.chat/server-fetch Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Feb 17, 2026

Walkthrough

Added a 10MB (10 * 1024 * 1024) response-size limit to the outgoing webhook fetch call in the integrations trigger handler to cap buffered response bodies.

Changes

Cohort / File(s) Summary
Webhook Response Size Limit
apps/meteor/app/integrations/server/lib/triggerHandler.ts
Added size: 10 * 1024 * 1024 to the fetch options to limit the maximum response body size for outgoing webhook requests.
Changelog
.changeset/shiny-pears-admire.md
Added changeset entry describing the patch release and the enforced 10MB limit for outgoing webhook responses.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~2 minutes

Poem

🐰 I nibble bytes, but not too many,
Ten megs is plenty—keeps servers sunny,
No giant streams to make us sigh,
A hop, a patch, the heap stays spry,
Cheers from the burrow, pitter-pie! 🥕

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and specifically describes the main change: adding a size limit to outgoing webhook responses to prevent memory exhaustion.
Linked Issues check ✅ Passed The PR implements the suggested fix by adding a size option (10MB instead of the suggested 20MB) to the fetch call in triggerHandler.ts, directly addressing issue #38758's requirement to limit response size and prevent memory exhaustion.
Out of Scope Changes check ✅ Passed All changes are directly in scope: the triggerHandler.ts modification adds the size limit to fetch, and the changeset documents this patch-level fix, with no unrelated modifications.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

No issues found across 1 file

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
apps/meteor/app/integrations/server/lib/triggerHandler.ts (1)

622-622: Extract the 20 MB magic number to a named constant.

♻️ Proposed refactor
+const MAX_WEBHOOK_RESPONSE_SIZE_BYTES = 20 * 1024 * 1024; // 20 MB

 fetch(
   opts.url,
   {
     method: opts.method,
     headers: opts.headers,
     ...(opts.timeout && { timeout: opts.timeout }),
     ...(opts.data && { body: opts.data }),
-    size: 20 * 1024 * 1024,
+    size: MAX_WEBHOOK_RESPONSE_SIZE_BYTES,
   },
   settings.get('Allow_Invalid_SelfSigned_Certs'),
 )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/meteor/app/integrations/server/lib/triggerHandler.ts` at line 622,
Replace the magic literal "20 * 1024 * 1024" used for the size option with a
named constant (e.g., MAX_ATTACHMENT_SIZE_BYTES or MAX_PAYLOAD_SIZE_BYTES)
declared at the top of the module (or an appropriate constants file) and
reference that constant where the code currently sets "size: 20 * 1024 * 1024"
in triggerHandler.ts; ensure the constant name clearly indicates bytes and
update any other identical magic-number occurrences in the file to use the same
constant.
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 508b4a1 and a67ed32.

📒 Files selected for processing (1)
  • apps/meteor/app/integrations/server/lib/triggerHandler.ts
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

**/*.{ts,tsx,js}: Write concise, technical TypeScript/JavaScript with accurate typing in Playwright tests
Avoid code comments in the implementation

Files:

  • apps/meteor/app/integrations/server/lib/triggerHandler.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: cubic · AI code reviewer
🔇 Additional comments (1)
apps/meteor/app/integrations/server/lib/triggerHandler.ts (1)

615-623: The size option is properly supported. The @rocket.chat/server-fetch package explicitly uses node-fetch v2.7.0, and the ExtendedFetchOptions type includes size?: number which is passed through to the underlying fetch call via parseRequestOptions. The fix will work as intended.

However, the generic error handler at line 786 doesn't distinguish a size limit exceeded error from other network errors. Consider adding explicit handling for the max-size error type to provide better observability:

.catch(async (err) => {
+  if (err?.type === 'max-size') {
+    outgoingLogger.warn({ msg: 'Integration response exceeded size limit', integrationName: trigger.name, url });
+  } else {
     outgoingLogger.error({ err });
+  }
   await updateHistory({
     historyId,
     step: 'after-http-call',
     httpError: err,
     httpResult: null,
   });
 });

Additionally, consider extracting the magic number 20 * 1024 * 1024 to a named constant for clarity and maintainability.

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@apps/meteor/app/integrations/server/lib/triggerHandler.ts`:
- Line 622: Replace the magic literal "20 * 1024 * 1024" used for the size
option with a named constant (e.g., MAX_ATTACHMENT_SIZE_BYTES or
MAX_PAYLOAD_SIZE_BYTES) declared at the top of the module (or an appropriate
constants file) and reference that constant where the code currently sets "size:
20 * 1024 * 1024" in triggerHandler.ts; ensure the constant name clearly
indicates bytes and update any other identical magic-number occurrences in the
file to use the same constant.

@KevLehman KevLehman added the valid A valid contribution where maintainers will review based on priority label Feb 17, 2026
@Khizarshah01 Khizarshah01 force-pushed the fix/webhook-response-size-limit branch from a67ed32 to 35e0290 Compare February 20, 2026 19:54
@Khizarshah01
Copy link
Copy Markdown
Contributor Author

PR is ready for review

Copy link
Copy Markdown
Member

@KevLehman KevLehman left a comment

Choose a reason for hiding this comment

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

Pls add a changeset explaining the changes as this would need to appear on release notes.

@Khizarshah01 Khizarshah01 force-pushed the fix/webhook-response-size-limit branch from 35e0290 to 3108c1d Compare February 20, 2026 21:16
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 35e0290 and 3108c1d.

📒 Files selected for processing (2)
  • .changeset/shiny-pears-admire.md
  • apps/meteor/app/integrations/server/lib/triggerHandler.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/meteor/app/integrations/server/lib/triggerHandler.ts
🔇 Additional comments (2)
.changeset/shiny-pears-admire.md (2)

7-7: Error handling exists for the FetchError from the size limit.

The fetch call at line 615-627 is properly wrapped with a .catch() block (lines 788-796) that handles any errors thrown by node-fetch, including the FetchError with type: 'max-size' when the 10MB size limit is exceeded. The error is logged via outgoingLogger.error() and recorded in the integration history, preventing an unhandled rejection.

Likely an incorrect or invalid review comment.


7-7: The size option is properly supported. triggerHandler.ts uses @rocket.chat/server-fetch, which wraps node-fetch 2.7.0—not the Node.js global fetch (undici). The node-fetch library fully supports the size option for limiting response body size. The option is defined in ExtendedFetchOptions, passed through parseRequestOptions() without filtering, and spreads into the underlying fetch() call. The 10MB size limit in the changeset is effectively enforced.

Likely an incorrect or invalid review comment.

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.changeset/shiny-pears-admire.md:
- Around line 5-7: The changeset and code disagree on the outgoing webhook
response cap (changeset uses 10MB while the PR description/issue state 20MB);
pick the intended limit and make it consistent across the project by updating
the .changeset/shiny-pears-admire.md text and the constant/setting in
triggerHandler.ts (e.g., OUTGOING_WEBHOOK_MAX_RESPONSE_SIZE or any local numeric
literal used to enforce the limit) to the chosen value, and also update any
related comments/tests/README entries so all references match the same size
(either 10MB or 20MB).

@Khizarshah01
Copy link
Copy Markdown
Contributor Author

@KevLehman I have made the requested changes

@KevLehman KevLehman added this to the 8.3.0 milestone Feb 20, 2026
@KevLehman KevLehman added the stat: QA assured Means it has been tested and approved by a company insider label Feb 20, 2026
@dionisio-bot dionisio-bot bot added the stat: ready to merge PR tested and approved waiting for merge label Feb 20, 2026
@codecov
Copy link
Copy Markdown

codecov bot commented Feb 20, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 70.59%. Comparing base (3145c41) to head (c78fc78).
⚠️ Report is 122 commits behind head on develop.

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##           develop   #38760      +/-   ##
===========================================
+ Coverage    70.55%   70.59%   +0.03%     
===========================================
  Files         3189     3189              
  Lines       112703   112703              
  Branches     20429    20390      -39     
===========================================
+ Hits         79519    79559      +40     
+ Misses       31123    31086      -37     
+ Partials      2061     2058       -3     
Flag Coverage Δ
e2e 60.36% <ø> (+0.01%) ⬆️
e2e-api 48.91% <ø> (+1.06%) ⬆️
unit 71.55% <ø> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@kodiakhq kodiakhq bot merged commit dad0dba into RocketChat:develop Feb 22, 2026
74 of 76 checks passed
@Khizarshah01
Copy link
Copy Markdown
Contributor Author

Thanks @KevLehman for the review and getting this merged :)

@KevLehman
Copy link
Copy Markdown
Member

You're welcome, thx for the good work :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

community stat: QA assured Means it has been tested and approved by a company insider stat: ready to merge PR tested and approved waiting for merge valid A valid contribution where maintainers will review based on priority

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Improve stability of Outgoing Webhooks by limiting response size

3 participants