Skip to content

fix(roms): enforce parent ROM visibility on direct file endpoints#3703

Merged
gantoine merged 1 commit into
masterfrom
posthog-code/fix-romfile-visibility-bypass
Jul 7, 2026
Merged

fix(roms): enforce parent ROM visibility on direct file endpoints#3703
gantoine merged 1 commit into
masterfrom
posthog-code/fix-romfile-visibility-bypass

Conversation

@gantoine

@gantoine gantoine commented Jul 7, 2026

Copy link
Copy Markdown
Member

Description

The direct ROM-file endpoints in backend/endpoints/roms/files.py resolved a RomFile purely by its user-supplied id and never mapped it back to the parent Rom, so they skipped the hidden ROM/platform visibility policy:

  • GET /api/roms/{id}/files/content/{file_name} (get_romfile_content) served the file bytes (via nginx X-Accel-Redirect in production).
  • GET /api/roms/{id}/files (get_romfile) returned the file metadata.

An authenticated user with only roms.read could download or inspect a file belonging to a ROM hidden from them by knowing or guessing the RomFile.id, even though the ROM-level endpoints (/api/roms/{id}, /api/roms/{id}/content/...) correctly return 404 for hidden ROMs.

Fix

Both handlers now resolve the parent Rom and call assert_rom_visible(request, rom, not_found_detail="File not found") before returning anything. This is the same 404-masking guard the ROM-level content endpoints use, and it matches the pattern already present in patch.py (_resolve_library_patch). assert_rom_visible no-ops for unauthenticated callers, so the DISABLE_DOWNLOAD_ENDPOINT_AUTH download path is unaffected.

Tests

Added three regression tests in tests/endpoints/roms/test_rom.py:

  • test_get_romfile_content_visible_rom - baseline, a viewer can download a visible ROM's file by RomFile.id (200 + X-Accel-Redirect).
  • test_get_romfile_content_hidden_rom_returns_404 - a hidden ROM's file bytes now 404 by direct RomFile.id.
  • test_get_romfile_hidden_rom_returns_404 - the metadata endpoint no longer leaks a hidden ROM's file.

All 137 tests in the roms + permissions-resolver suites pass, and trunk check is clean.

AI assistance disclosure

This change was authored with AI assistance (PostHog Code / Claude): investigation of the affected endpoints, the fix, and the regression tests were AI-generated and human-reviewed.

Checklist

  • I've tested the changes locally
  • I've updated relevant comments
  • I've assigned reviewers for this PR
  • I've added unit tests that cover the changes

Created with PostHog Code

The direct ROM-file endpoints (`get_romfile` and `get_romfile_content`)
resolved a RomFile purely by its user-supplied id and never mapped it
back to the parent Rom, so an authenticated user with roms.read could
read or download a file of a ROM hidden from them by knowing/guessing
the RomFile.id, bypassing the hidden ROM/platform policy.

Resolve the parent Rom and apply assert_rom_visible (404-masking) before
returning any file bytes or metadata, matching the ROM-level content
endpoints and the existing check in patch.py.

Generated-By: PostHog Code
Task-Id: 149c191c-7a22-4cf6-aafd-4dcf53f4fba0
Copilot AI review requested due to automatic review settings July 7, 2026 13:28
@greptile-apps

greptile-apps Bot commented Jul 7, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds parent-ROM visibility checks to direct ROM file endpoints. The main changes are:

  • Direct file metadata now resolves the parent ROM before returning data.
  • Direct file downloads now apply the parent ROM visibility guard before serving bytes.
  • Tests cover visible direct downloads and hidden-ROM 404 responses.

Confidence Score: 4/5

The authenticated path looks fixed, but anonymous download mode can still serve hidden ROM files by direct RomFile ID.

  • The new guard works for authenticated callers because permissions can be resolved from the request user.
  • With download auth disabled, the route can run without an authenticated user and the visibility guard has no permission context to check.
  • Deployments using that mode can still expose hidden ROM file bytes through the direct content endpoint.

backend/endpoints/roms/files.py

Security Review

The authenticated direct-file bypass is addressed, but the download endpoint still skips visibility for anonymous requests when download endpoint auth is disabled.

Important Files Changed

Filename Overview
backend/endpoints/roms/files.py Adds parent ROM lookup and visibility checks before direct file metadata and content responses.
backend/tests/endpoints/roms/test_rom.py Adds tests for visible and hidden ROM behavior on direct RomFile endpoints.

Fix All in Claude Code

Reviews (1): Last reviewed commit: "fix(roms): enforce parent ROM visibility..." | Re-trigger Greptile

Comment thread backend/endpoints/roms/files.py

Copilot AI left a comment

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.

Pull request overview

This pull request closes a visibility bypass in the ROM file endpoints by ensuring requests for a RomFile are gated by the parent Rom’s hidden/platform visibility policy (404-masked), aligning behavior with the ROM-level endpoints.

Changes:

  • Resolve the parent Rom for direct ROM-file endpoints and enforce assert_rom_visible(..., not_found_detail="File not found") before returning metadata or content.
  • Add regression tests to confirm hidden ROMs’ files return 404 for both content and metadata endpoints.
  • Add a small test helper to mark a ROM hidden for a specific user via HiddenEntity.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
backend/endpoints/roms/files.py Enforces parent ROM visibility (404-masked) on direct RomFile ID endpoints before serving metadata/content.
backend/tests/endpoints/roms/test_rom.py Adds regression tests ensuring hidden ROM file content/metadata endpoints return 404; includes helper to hide a ROM for a user.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@gantoine gantoine merged commit d4bdfef into master Jul 7, 2026
12 checks passed
@gantoine gantoine deleted the posthog-code/fix-romfile-visibility-bypass branch July 7, 2026 14:02
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