Add secure SSH profiles and remote asset fetching - #46
matchaboar wants to merge 1 commit into
Conversation
|
Please keep this in draft for now. The image root check still has a gap: SSHTransport.swift validates the path with realpath, then scp opens it in a separate operation. Someone who can change the remote tree can swap the file or a parent directory for a symlink between those steps. A local test using the production fetchReferencedImages path reproduced this with an injected runner: it ran the actual resolver command, swapped the validated image for a symlink, then simulated the later read. The cache ended up with bytes from outside the root, with one successful fetch and no reported failures. No real SSH host was involved. Please make confinement apply to the file actually opened and transferred, rather than relying on an earlier path check, and add a regression test for that swap. We also need limits on bytes and transfer time; the 32-image cap doesn't cover either. There are two other fixes needed. In openRemote, image fetching adds an await after the duplicate-tab check, so two opens of the same document can both get through and create tabs. Recheck after the last await, immediately before finishOpen, or share the in-flight open, and test with delayed image fetching. RemoteMarkdownAssets also decodes percent escapes repeatedly while reader.js decodes once. For example, image%2523.png gets fetched as image#.png, but the reader looks for image%23.png. Please use the same decoding rules throughout and add a test that fetches and renders a filename containing a literal percent escape. The 95 supplied logic checks pass locally, but they miss these cases. Once they're covered, please rebase onto current main, preserve the v3.2 reader changes, and get the build and reader tests passing on the rebased commit. A real-host SSH check would help too, since the current evidence uses local fixtures and fake runners. |
Summary
Focused SSH, remote document, and local/remote asset split from #43, rebased onto current
main.?/#filenames.Review fixes
encodeImagePathinto callable scope; a bad image is isolated to a placeholder instead of abortingapplyAll()before annotations, search, or Mermaid setup.avif,gif,jpeg,jpg,png,svg, andwebpassets.realpathand reject symlink escapes outside the root.$HOMEfallback or whole-home scan.hostname: testdefault.Red/green evidence
Against the original #43 implementation, the focused regression harness exposed five SSH/asset security failures and the reader harness reproduced the
encodeImagePathReferenceError. The final implementation passes:Manual image pass
A WKWebView fixture rendered a relative
sample.svgthroughmindle-file://at 120×80 and verified the reader pipeline continued. No real SSH host was available, so remote listing, root/symlink confinement, fetch limits, and failure handling are automated rather than manually exercised. Hosts withoutrealpathfail remote image fetching loudly rather than weakening confinement.Validation
./run-tests.sh— passes Swift and reader/WKWebView harnesses./build.sh— passes