Repository navigation
Backups: keep URL credentials out of git argv and the clone's .git/config (T332) - #267
Merged
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…auth over http, the probe, and users' helpers (T332)
…elpers; docs for org@host URLs (T332)
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
T332 (from T317). A backup URL with credentials (
https://me:TOKEN@host/x.git) was passed togit clone/ls-remote/remote set-url, so the token showed inpswhile git ran and was written to the clone's.git/configunderbackup-repos/.What changes
Remote::of, built on the existingwithout_credentials).ls-remote) add-c credential.helper=(reset) and-c credential.helper=!f() {…}; f, a shell helper that printsusername/passwordfromTSK_BACKUP_USERNAME/TSK_BACKUP_PASSWORDonly when git asks forTSK_BACKUP_HOST(host:port as written). The secret travels in env only.user:TOKEN@→ user / TOKEN; bareTOKEN@→ TOKEN / empty password. Userinfo is percent-decoded as git does (%40→@).ssh://git:pw@hostreaches git asssh://git@host(ssh never took the password from git anyway).sync_clonealready ranremote set-urlon every use; it now sets the clean URL, so.git/configis rewritten on next use with no user action.config.toml,***redaction,redacted()/credentials(): untouched (PR Strip a bare https backup token when the URL does not start at the scheme #261 edits those; rebase expected).Why a shell
credential.helperand notGIT_ASKPASSshunchanged: no backslash/space quoting of atsk.exepath.main), and it works under the existingcredential.interactive=never(askpass is a prompt; a helper is not).Username-only URLs (owner decision: option A)
https://alice@host/x.gitis treated as a login like any other: git gets alice with an empty password, and the user's helpers are reset (never asked, never store).storage.mdtells Azure DevOps / Bitbucket users withorg@hostURLs to leave theorg@part out so their credential manager logs them in.Tests
Each new test was checked by reverting its fix by hand (results below).
clone_probe_fetch_and_push_log_in_through_the_helper_aloneTcpListener+git http-backend, 401 without Basicme:s3cr@et) serving a bare repo. Runs clone,backup add's probe (run_probe,ls-remote), push, then fetch of the existing clone + push. Asserts authorized upload-pack and receive-pack requests, two commits, no recorded git argv holds the token, no file underbackup-repos/holds it.git();sync_clonefetch viagit_command; clone viagit_command; probe giventarget.location(all four verified)a_login_with_a_line_break_never_reaches_git%0A,%0D,%00in the login: run and probe refuse with "line break or NUL", noTAILin either error, and no git call is made.the_users_own_helpers_answer_only_for_a_url_without_a_logingit credential fillwith a user helper set ascredential.helperand ascredential.https://example.com.helper: a plain URL gets the user's login; a tokened URL gets only ours; a username-only URL getsalice+ empty password, never the user's helper.the_credential_helper_gives_the_login_to_its_host_onlya_backup_never_puts_the_token_in_git_arguments_or_the_cloneinsteadOfto a local repo (git never asks for a login here): argv andbackup-repos/token-free.an_old_clone_holding_the_token_is_rewritten_on_next_use.git/configrewritten.a_remote_keeps_its_login_out_of_the_urlCommand::get_argsinrun_git, a#[cfg(test)]thread-local likegit_base's override), not a fake git on PATH: PATH is process-global under parallel lib tests.credential.helper=(empty) clears URL-scopedcredential.<url>.helperentries too: checked with git 2.54 and covered by the test above.backup_to_git's push-race retry (runs only after a rejected push); Windows (tests run on ubuntu and macOS; windows-gnu clippy passes); GitHub itself.a_stored_error_never_holds_a_tokennow expectsme@127.0.0.1(git never sees the token).cli_backup::credentials_in_a_target_url_are_never_printedmaps the clean URL withinsteadOf.Live smoke (macOS, isolated
TSK_STATE_DIR)Local
git http-backendbehind Basic auth (python, scratch), URLhttp://me:p%40ss%3AwTOKEN@127.0.0.1:18763/b.git:tsk backup add,tsk backup,tsk restoreall succeed; server log shows 401 then auth=ok on every ref and pack request; two commits pushed.pssampled every 20 ms during the run: the token appears only on the user's owntsk backup add …line; git,git-remote-http, andsend-packlines carryhttp://127.0.0.1:18763/b.git.grep -r TOKEN backup-repos/: nothing. Origin is the clean URL.Not run: Windows live (Git for Windows
!helpers are standard; windows-gnu clippy passes). GitHub live (brief forbids creating a repo), so bareTOKEN@→ empty password is untested against GitHub. Residual: an old clone'sFETCH_HEAD/reflogs were not checked for a token (git anonymizes URLs there;backup-repos/is 0700).Checks
cargo fmt --check && cargo clippy --all-targets -- -D warnings && cargo testgreen;cargo clippy --all-targets --target x86_64-pc-windows-gnu -- -D warningsgreen.Docs:
storage.mdCredentials section; CHANGELOG Unreleased → Fixed.