Any idea to fix it ?
Prefix the remote name with the word safe
$ git remote rename {,safe}-myremotename
You can then use it again
$ git pull safe-myremotename
Successfully rebased and updated refs/heads/develop
As remote names land in the file-system and also are prone to injection as your question shows, please consider the following:
Use only characters from the 3.282 Portable Filename Character Set
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
a b c d e f g h i j k l m n o p q r s t u v w x y z
0 1 2 3 4 5 6 7 8 9 . _ -
Do not use the dash -
as first character. (ref)
Do not use any of the digits 0-9
and letters a-f
/A-F
within the remote name only (if the name is longer than three characters). Otherwise a remote name may become refused by git(1)
in the future of your repository. (ref)
And additional and more in general:
- Consider to not start names with a digit
0-9
.
- Consider to not start nor end names with punctuation, here
.
, _
or -
.
- Consider to use only one case, either lower
a-z
or upper A-Z
.
- Consider to keep the remote name as long as needed while as short as possible, not shorter than three letters. Eight characters is normally a good maximum.
And thanks for asking. It is exactly as you wrote that git-pull(1)
allows to specify the remote name after --
while that in the git-fetch(1)
invocation by it, the remote name is passed verbatim into the arguments list.
It does not look like an ordinary injection that allows to get ownage of the whole bakery. The only thing that can be injected to git-fetch(1)
is a single parameter by the configured remote.<name>
.
E.g. with a single remote named --all
we can send git-pull(1)
(and, via), git-fetch(1)
into child recursion. That is fun but also spams tty
Example
Name of the remote: --all
Process tree of git pull -- --all
(limited to 6 lines):
121540 Ss+ 00:00:00 -/bin/sh
122011 T 00:00:00 \_ git pull -- --all
122012 T 00:00:00 \_ /usr/lib/git-core/git fetch --update-head-ok --all
122023 T 00:00:00 \_ /usr/lib/git-core/git fetch --append --no-auto-gc --no-write-commit-graph --update-head-ok --all
122034 T 00:00:00 \_ /usr/lib/git-core/git fetch --append --no-auto-gc --no-write-commit-graph --update-head-ok --all
122045 T 00:00:00 \_ /usr/lib/git-core/git fetch --append --no-auto-gc --no-write-commit-graph --update-head-ok --all
Does git-fetch(1)
tricks itself here already? Sort of, but only if --jobs=1
. With --jobs=2
or higher than 2
, git-fetch(2)
does process the option more sequentially and not all-over and again and again. But only if there are at least two remotes.
121540 Ss+ 00:00:00 -/bin/sh
127528 T 00:00:00 \_ git fetch --all
127539 T 00:00:00 \_ /usr/lib/git-core/git fetch --append --no-auto-gc --no-write-commit-graph --all
127550 T 00:00:00 \_ /usr/lib/git-core/git fetch --append --no-auto-gc --no-write-commit-graph --all
127561 T 00:00:00 \_ /usr/lib/git-core/git fetch --append --no-auto-gc --no-write-commit-graph --all
127572 T 00:00:00 \_ /usr/lib/git-core/git fetch --append --no-auto-gc --no-write-commit-graph --all
127583 T 00:00:00 \_ /usr/lib/git-core/git fetch --append --no-auto-gc --no-write-commit-graph --all
127594 T 00:00:00 \_ /usr/lib/git-core/git fetch --append --no-auto-gc --no-write-commit-graph --all
127605 T 00:00:00 \_ /usr/lib/git-core/git fetch --append --no-auto-gc --no-write-commit-graph --all
127616 T 00:00:00 \_ /usr/lib/git-core/git fetch --append --no-auto-gc --no-write-commit-graph --all
Well, looks like. git-fetch --all
has no sanity check to detect if it is re-entrant for the same remote name nor seems to have an option with its own argument to denote the remote (either by name or URL) which could prevent that.
(git version 2.25.1)