Skip to content

Comments

Security: Prevent room ID enumeration#2518

Merged
samuelwei merged 8 commits intodevelopfrom
sec-prevent-room-enumeration
Feb 20, 2026
Merged

Security: Prevent room ID enumeration#2518
samuelwei merged 8 commits intodevelopfrom
sec-prevent-room-enumeration

Conversation

@samuelwei
Copy link
Collaborator

@samuelwei samuelwei commented Oct 9, 2025

Type

  • Bugfix
  • Feature
  • Documentation
  • Refactoring (e.g. Style updates, Test implementation, etc.)
  • Other (please describe)

Checklist

  • Code updated to current develop branch head
  • Passes CI checks
  • Is a part of an issue
  • Tests added for the bugfix or newly implemented feature, describe below why if not
  • Changelog is updated
  • Documentation of code and features exists

Changes

  • Add rate limiting to room API endpoints to mitigate room ID enumeration attacks

Other information

All API requests resulting in a 404 response due to an invalid room ID are counted. If the limit exceeds the threshold all room api calls are blocked.

Summary by CodeRabbit

  • New Features

    • Rate limiting added for room-related endpoints: counts only 404 responses, limited to 10 requests/minute per user/IP; many room management, membership, files (including downloads), recordings, tokens, and streaming routes are now throttled.
  • Documentation

    • Changelog updated with an Unreleased entry referencing the new rate-limiting change.
  • Tests

    • Added tests validating 404-based rate limiting for guests and authenticated users, related routes, per-user behavior, and limit reset timing.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 9, 2025

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds a "room-enumeration" rate limiter that counts only 404 responses for unresolved room parameters, applies that throttle to many room-related API and web routes, updates the changelog, and adds a feature test validating per-user/IP 404 rate limiting and reset behavior.

Changes

Cohort / File(s) Summary
Changelog update
CHANGELOG.md
Added Unreleased entry: "Rate limiting to prevent Room-ID enumeration attacks" and referenced PR #2518; added reference in older versions list.
Rate limiter configuration
app/Providers/RouteServiceProvider.php
Introduced room-enumeration limiter (10/min per user ID or IP) and an after-callback that increments only for 404 responses when the room route parameter does not resolve to a Room; added Room and Response imports.
Routing — room throttling and reorganization
routes/api.php
Wrapped many room-related endpoints in throttle:room-enumeration, moving and grouping room CRUD, membership, files, recordings, streaming, personalized links, meetings, start/join/auth/timezone endpoints and related OPTIONS into throttled groups; applied scopeBindings and can:* middleware consistently.
Web route throttling
routes/web.php
Added throttle:room-enumeration middleware to GET room/{room}/file/{file}/{filename?} file download route.
Tests — feature coverage
tests/Backend/Feature/api/v1/Room/RoomTest.php
Added test_room_404_rate_limit() to verify that only 404 responses increment the limiter, validate guest vs authenticated scoping, ensure related-route 404s are handled, and confirm time-based reset.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Suggested reviewers

  • danielmachill
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically summarizes the main security feature: implementing rate limiting to prevent room ID enumeration attacks.
Description check ✅ Passed The description covers the required template sections, including type selection, completed checklist items, changes summary, and additional context about rate limiting behavior.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch sec-prevent-room-enumeration

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.

@samuelwei
Copy link
Collaborator Author

samuelwei commented Oct 9, 2025

TODO

  • Add tests
  • Add log entries

@codecov
Copy link

codecov bot commented Oct 9, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.77%. Comparing base (6327450) to head (40f7dbf).
⚠️ Report is 1 commits behind head on develop.

Additional details and impacted files
@@            Coverage Diff             @@
##             develop    #2518   +/-   ##
==========================================
  Coverage      96.77%   96.77%           
- Complexity      1839     1841    +2     
==========================================
  Files            444      444           
  Lines          12570    12579    +9     
  Branches        2063     2063           
==========================================
+ Hits           12164    12173    +9     
  Misses           406      406           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@cypress
Copy link

cypress bot commented Oct 9, 2025

PILOS    Run #2840

Run Properties:  status check passed Passed #2840  •  git commit 40f7dbfb42: Security: Prevent room ID enumeration
Project PILOS
Branch Review sec-prevent-room-enumeration
Run status status check passed Passed #2840
Run duration 06m 56s
Commit git commit 40f7dbfb42: Security: Prevent room ID enumeration
Committer Samuel Weirich
View all properties for this run ↗︎

Test results
Tests that failed  Failures 0
Tests that were flaky  Flaky 0
Tests that did not run due to a developer annotating a test with .skip  Pending 0
Tests that did not run due to a failure in a mocha hook  Skipped 0
Tests that passed  Passing 615
View all changes introduced in this branch ↗︎

@samuelwei samuelwei force-pushed the sec-prevent-room-enumeration branch from 2d96ac3 to 61c5d8e Compare October 10, 2025 10:07
@samuelwei samuelwei marked this pull request as ready for review October 10, 2025 10:11
Copy link
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: 0

🧹 Nitpick comments (1)
app/Providers/RouteServiceProvider.php (1)

76-89: Limiter design is sound; make limits configurable and verify 'after' semantics

  • Counts only 404s when the room param didn’t bind to a Room model. Good approach to avoid false positives.
  • Suggest reading limits from config (e.g., perMinutes/attempts), not hard-coded 10/min.

Proposed change:

-        RateLimiter::for('room-enumeration', function (Request $request) {
-            return Limit::perMinute(10)
+        RateLimiter::for('room-enumeration', function (Request $request) {
+            $max = config('rate_limits.room_enumeration.max_attempts', 10);
+            $decay = config('rate_limits.room_enumeration.decay_minutes', 1);
+            return Limit::perMinutes($decay, $max)
                 ->by($request->user()?->id ?: $request->ip())
                 ->after(function (\Symfony\Component\HttpFoundation\Response $response) use ($request) {
                     // If the response is not a 404, do not count this request
                     if ($response->getStatusCode() !== 404) {
                         return false;
                     }
 
                     // Only count the request if the route parameter 'room' was not resolved to a Room model
                     // Prevent counting requests that are valid and return a 404 for other reasons
                     return ! ($request->route('room') instanceof Room);
                 });
         });

Please confirm the project’s Laravel version supports Limit::after with a boolean return to control counting. If not, we’ll switch to an alternative (e.g., custom middleware with RateLimiter::hit only on 404). Based on learnings

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b3ff518 and 61c5d8e.

📒 Files selected for processing (4)
  • CHANGELOG.md (2 hunks)
  • app/Providers/RouteServiceProvider.php (2 hunks)
  • routes/api.php (2 hunks)
  • tests/Backend/Feature/api/v1/Room/RoomTest.php (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
app/Providers/RouteServiceProvider.php (2)
app/Models/User.php (1)
  • User (20-349)
_ide_helper.php (2)
  • for (9551-9555)
  • ip (10222-10226)
tests/Backend/Feature/api/v1/Room/RoomTest.php (1)
app/Models/Room.php (2)
  • Room (19-464)
  • owner (214-217)
routes/api.php (7)
app/Http/Controllers/api/v1/RoomController.php (1)
  • RoomController (32-426)
app/Http/Controllers/api/v1/RoomMemberController.php (1)
  • RoomMemberController (20-215)
app/Http/Controllers/api/v1/RecordingController.php (1)
  • RecordingController (16-103)
app/Http/Controllers/api/v1/RoomStreamingController.php (1)
  • RoomStreamingController (16-135)
app/Http/Controllers/api/v1/RoomTokenController.php (1)
  • RoomTokenController (17-139)
app/Http/Controllers/api/v1/RoomFileController.php (1)
  • RoomFileController (16-163)
app/Http/Controllers/api/v1/RecordingFormatController.php (1)
  • RecordingFormatController (10-26)
⏰ 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: Docker Build
🔇 Additional comments (6)
CHANGELOG.md (2)

13-13: Changelog entry LGTM

Accurately reflects the new security feature.


561-561: Reference link added correctly

Footnote for [#2518] is consistent and valid.

tests/Backend/Feature/api/v1/Room/RoomTest.php (1)

419-470: Strong coverage for 404-based throttling

Covers guest vs auth, cross-route blocking, window reset, and excluding valid-room 404s. Nicely done.

routes/api.php (3)

77-137: Throttle scope alignment looks good; confirm intent to block writes after threshold

Wrapping all per-room endpoints means once the 404 threshold is exceeded, even valid writes (update/delete, streaming actions, membership ops, etc.) are blocked for the window. This matches the PR note (“all room API calls are blocked”). If that’s intended, LGTM.


164-165: Meetings endpoint throttled consistently

Brings meetings under the same limiter. Consistent with the threat model.


171-187: Public room routes throttled with auth middleware where needed

Good use of room.authenticate and scopeBindings alongside the throttle to keep behavior consistent for guests and users.

@samuelwei samuelwei force-pushed the develop branch 2 times, most recently from 88ee280 to bc9287a Compare October 20, 2025 15:17
@samuelwei samuelwei merged commit 6b6ddbe into develop Feb 20, 2026
21 checks passed
@samuelwei samuelwei deleted the sec-prevent-room-enumeration branch February 20, 2026 09:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants