XModem: reject path-traversal filenames in the transfer handler#11037
XModem: reject path-traversal filenames in the transfer handler#11037caveman99 wants to merge 2 commits into
Conversation
The SOH/STX control frame carries a client-supplied filename that was passed straight to FSCom open/remove/exists, so a ".." component could write, read, or delete outside the filesystem root. On embedded LittleFS this is largely inert (no parent of the partition root); on the Portduino daemon FSCom is the host filesystem under a mountpoint, so it is a real arbitrary-path write/read/delete. Validate the filename before any FS access: reject empty and any ".." path component, and NAK the transfer. Absolute and subdirectory paths are still accepted - the file manager transfers them from the manifest and PortduinoFS confines them to its mountpoint - so only traversal out of the root is blocked. Reachable only from a local client connection (PhoneAPI: BLE/USB/serial/TCP), not over the RF mesh; on the daemon the TCP API makes it network-reachable. native-suite-count goes to 34: +1 for the new test_xmodem suite and +1 correcting a pre-existing miscount (it read 32 for 33 suite directories).
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (4)
📝 WalkthroughWalkthroughAdds XMODEM filename validation to reject null, empty, and ChangesXMODEM filename validation
Estimated code review effort: 3 (Moderate) | ~20 minutes Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
⚡ Try this PR in the Web FlasherNote Building this pull request… the flash button, badges and supported-board |
The XModem SOH/STX control frame carries a client-supplied destination filename that was used
directly for filesystem access with no validation:
A
..component lets the filename escape the filesystem root - arbitrary file write, read(exfiltration), and delete (the CAN control also
FSCom.remove(filename)).Impact by target. On embedded LittleFS this is largely inert: the partition root has no
parent to traverse into. On the Portduino /
meshtasticddaemon,FSComisPortduinoFS,which maps onto the host filesystem under a mountpoint, so
..traverses out of the mountpointinto real host paths. That build is where this matters.
Reachability.
handlePacketis called only fromPhoneAPI::handleToRadio(thexmodemPacketToRadio case), i.e. from a local client connection - BLE, USB/serial, or the TCPAPI. It is not reachable over the RF mesh. On the daemon the TCP API is network-reachable, so on a
networked
meshtasticdan unauthenticated API client can trigger it (lockdown builds already dropxmodem from unauthorized connections).
Fix. Validate the filename before any FS access: reject empty and any
..path component, andNAK the transfer. Absolute paths and subdirectories are still accepted - the file manager transfers
them straight from the manifest (
getFiles("/", ...)), and PortduinoFS confines them to itsmountpoint - so only traversal out of the root is blocked, not legitimate transfers.
Test (test_xmodem):
..,../secret,/prefs/../../etc/passwd,a/../bare rejected; empty/nullrejected;
/prefs/config.proto,dir/sub/file.txt, and a name that merely contains..(my..file)are accepted.
native-suite-countis bumped to 34: +1 for the new suite and +1 correcting a pre-existingoff-by-one (the file read 32 against 33 existing suite directories).
Summary by CodeRabbit
Bug Fixes
Tests