Repository navigation
fix(files): open a remote PC's PDF from Android's Open button - #448
Conversation
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. Note Currently processing new changes in this PR. This may take a few minutes, please wait... ⚙️ Run configuration
📒 Files selected for processing (2)
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configuration
📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (1)
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review. 📝 SummarySummary by CodeRabbit
WalkthroughThe machine API allows GET and HEAD requests to matching machine file paths to bypass the same-origin check. Tests cover successful PDF reads and requests that still return ChangesRemote machine PDF access
Priority: ⬇️ Low Estimated code review effort: 2 (Simple) | ~10 minutes Change: Bug fix · Severity of issue fixed: Low Suggested reviewers: Merge Risk: ⚪ Minimal · up to The change enables the intended remote-file navigation while preserving authentication and read-only restrictions. No material merge-blocking issue is established. Security Architecture ReviewSecurity architecture risk: 🔵 Low · up to The exception is limited to file reads, and authentication, read-only device restrictions, and bridge credential isolation remain enforced. It covers all readable remote files, not only PDFs. No unauthorized disclosure was established, but practical exposure depends on deployment authentication and reverse-proxy configuration that was not available. Retained concerns Security review detailsSecurity Blast Radius
Security Findings and Attack Paths
Trust Boundaries and Controls
Hardening Proposals
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Full details: Docstring CoverageExplanation Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 2 files. (1 skipped: 1 unsupported.)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
# Conflicts: # CHANGELOG.md
# Conflicts: # CHANGELOG.md
|
Merged the latest |
…open # Conflicts: # CHANGELOG.md
…rigin exemption Review follow-up on devswha#448 (Codex adversarial review): the PR's test calls handleMachineRequest directly, so nothing showed that the read-only refusal in index.ts still runs ahead of the new origin exemption for GET and HEAD of /api/machines/<id>/fs/file. The device-access contract test now asserts it for both methods with a cross-site header: 403 read_only. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Merged, thank you. Before merging I had a Codex security pass look at the exemption: it confirmed the watch-device refusal and the |
|
Measured on the device: Chrome 154 on Android (Galaxy Z Fold), on a fresh HTTPS origin over Tailscale Serve, with a test page holding the same
So the request #448 lets through is a top-level, user-activated navigation. Narrowing the exemption to (A first run on a port where the phone still had an old service worker registered showed |
Bumps package.json and herdr-plugin.toml to 0.3.50 and moves the Unreleased notes under [0.3.50] - 2026-10-06, with the compare link. Adds the PR link and credit the #471 entry was missing; every other entry already carries them. Raises the remote PC bundle to 17: #470 changes the prompt answer route on the bridge, so a remote PC on bundle 16 keeps the old behaviour until its bridge is updated. Push the `remote-v17` tag and let the bundle workflow publish before running release.yml. Known limits carried into the notes: Japanese and Chinese text uses the device's fonts beside Pretendard; #469 stays open for what #470 does not cover (answers after the first committing key, identical twin prompts, screens no reader knows). Carries #422 #423 #424 #425 #426 #435 #437 #439 #446 #447 #448 #452 #454 #455 #456 #457 #458 #459 #460 #461 #462 #463 #465 #466 #467 #468 #471 #473 #474 #475 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Change
On Android, the file viewer's
<iframe>cannot draw a PDF, so Chrome shows an Open button in its place. That button's navigation is sent withSec-Fetch-Site: cross-site(Chrome treats the fallback UI as another origin, see https://issues.chromium.org/issues/374094200).For a file on the app's own PC this works:
GET /api/fs/filehas no origin check. For a file on a remote PC the URL is/api/machines/<id>/fs/file, andhandleMachineRequestrefused every request that failssameOrigin(), so the phone showed{"error":{"code":"invalid_origin","message":"Use PC controls from this app"}}instead of the PDF.handleMachineRequestnow letsGET/HEADof/api/machines/<id>/fs/filethrough without the origin check, the same rule as the local/api/fs/file. Nothing else changes:decideAccess) and the read-only device refusal for file reads inindex.tsstill run first;fs/file, still answersinvalid_originfrom another origin;Authorization;//,..and encoded slashes do not match the exemption ([^/]+for the id, exactfs/filetail), and//paths still 404 as before.Validation
/api/machines/<remote>/fs/statandfs/fileanswer 403invalid_originwithsec-fetch-site: cross-siteorsame-site, 200 withsame-origin,noneor no header; the local/api/fs/*answers 200 for all of them.server/machine-proxy.test.ts: a cross-site and a same-site GET of a PC'sfs/filestream the file, and a cross-siteHEADanswers 200; a cross-sitefs/stat,pane/conversation,POST fs/file(withx-herdr-machine: 1) and a foreign-originPUTstill answer 403invalid_origin. The new test fails onmain(403) and passes with the change.bun run generate:types --check,bun run typecheck,bun run buildpass.bun run test:uniton macOS has the same 14 failures with and without this change (Codex resume selection and pi store path tests, platform-specific); none touch this code.