harden(ssh): scope bulk sync tar extraction to .hermes - #10205
Conversation
b240162 to
08aa37f
Compare
46fc5a0 to
b302f3c
Compare
|
Follow-up context after rebasing this PR onto latest main: The original #17767 failure mode has already been addressed upstream by #17898, which added This PR is now intended as a narrower security hardening follow-up rather than the primary #17767 fix. Current main still builds the local tar staging tree from absolute remote paths via The change here scopes the tar stream to the remote Hermes directory itself:
So the remaining value is defense-in-depth: avoid archiving or extracting parent home-directory path components at all, and constrain bulk upload to the directory Hermes owns. |
|
I am seeing this issue in my logs and this PR looks like the solution. |
Summary
Fix a regression in SSH bulk file sync where tar extraction was performed at
/, allowing archive path components likehome/<user>/...to touch the remote home directory. This can break SSH access after a seemingly successful one-shot command.The user-visible failure mode is:
775StrictModesrejects the home directory permissionsThis change keeps SSH bulk upload scoped to
~/.hermes:.hermesbase instead of the absolute remote path~/.hermesinstead of/home/<user>path componentsRoot Cause
The bulk uploader mirrored absolute remote paths in the temporary staging directory and then extracted the archive with
tar xf - -C /. That meant the archive could contain parent directories such ashome/<user>, and tar would apply those directory entries while unpacking.If the local staging directories are created under a permissive umask, the archive can carry directory modes like
775forhome/andhome/<user>/. When those entries are extracted at/on the remote host, the existing remote home directory can be widened as a side effect, causing later SSH authentication failures.Why This May Reproduce Only In Some Environments
This regression depends on both the buggy extraction behavior and the surrounding local/remote permission model.
In the reported environment:
002775StrictModes yesThat combination makes the bug much easier to reproduce:
umask=002means staging directories underhome/<user>/...default to group-writable modes like775/can then apply those modes to the real remote home directoryStrictModes yeschecks the user's home directory and files before accepting login, so the next SSH attempt may be rejected immediatelyThis means the bug is still in the code regardless of environment, but hosts with
umask=002locally andStrictModes=yesremotely are much more likely to see it as a hard SSH failure rather than a silent permission drift.Testing
source venv/bin/activate && uv run pytest tests/tools/test_ssh_bulk_upload.py tests/tools/test_ssh_environment.py -q