Sync from SUSE:SLFO:Main git revision 3db6954da868a17e5b9076cd4ef49f66
This commit is contained in:
parent
df3c7d5158
commit
a9f7335aa9
98
CVE-2024-50349-1.patch
Normal file
98
CVE-2024-50349-1.patch
Normal file
@ -0,0 +1,98 @@
|
||||
From c903985bf7e772e2d08275c1a95c8a55ab011577 Mon Sep 17 00:00:00 2001
|
||||
From: Johannes Schindelin <johannes.schindelin@gmx.de>
|
||||
Date: Thu, 7 Nov 2024 08:57:52 +0100
|
||||
Subject: [PATCH 1/2] credential_format(): also encode <host>[:<port>]
|
||||
|
||||
An upcoming change wants to sanitize the credential password prompt
|
||||
where a URL is displayed that may potentially come from a `.gitmodules`
|
||||
file. To this end, the `credential_format()` function is employed.
|
||||
|
||||
To sanitize the host name (and optional port) part of the URL, we need a
|
||||
new mode of the `strbuf_add_percentencode()` function because the
|
||||
current mode is both too strict and too lenient: too strict because it
|
||||
encodes `:`, `[` and `]` (which should be left unencoded in
|
||||
`<host>:<port>` and in IPv6 addresses), and too lenient because it does
|
||||
not encode invalid host name characters `/`, `_` and `~`.
|
||||
|
||||
So let's introduce and use a new mode specifically to encode the host
|
||||
name and optional port part of a URI, leaving alpha-numerical
|
||||
characters, periods, colons and brackets alone and encoding all others.
|
||||
|
||||
This only leads to a change of behavior for URLs that contain invalid
|
||||
host names.
|
||||
|
||||
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
|
||||
---
|
||||
credential.c | 3 ++-
|
||||
strbuf.c | 4 +++-
|
||||
strbuf.h | 1 +
|
||||
t/t0300-credentials.sh | 13 +++++++++++++
|
||||
4 files changed, 19 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/credential.c b/credential.c
|
||||
index f32011343f..572f1785da 100644
|
||||
--- a/credential.c
|
||||
+++ b/credential.c
|
||||
@@ -164,7 +164,8 @@ static void credential_format(struct credential *c, struct strbuf *out)
|
||||
strbuf_addch(out, '@');
|
||||
}
|
||||
if (c->host)
|
||||
- strbuf_addstr(out, c->host);
|
||||
+ strbuf_add_percentencode(out, c->host,
|
||||
+ STRBUF_ENCODE_HOST_AND_PORT);
|
||||
if (c->path) {
|
||||
strbuf_addch(out, '/');
|
||||
strbuf_add_percentencode(out, c->path, 0);
|
||||
diff --git a/strbuf.c b/strbuf.c
|
||||
index c383f41a3c..756b96c561 100644
|
||||
--- a/strbuf.c
|
||||
+++ b/strbuf.c
|
||||
@@ -492,7 +492,9 @@ void strbuf_add_percentencode(struct strbuf *dst, const char *src, int flags)
|
||||
unsigned char ch = src[i];
|
||||
if (ch <= 0x1F || ch >= 0x7F ||
|
||||
(ch == '/' && (flags & STRBUF_ENCODE_SLASH)) ||
|
||||
- strchr(URL_UNSAFE_CHARS, ch))
|
||||
+ ((flags & STRBUF_ENCODE_HOST_AND_PORT) ?
|
||||
+ !isalnum(ch) && !strchr("-.:[]", ch) :
|
||||
+ !!strchr(URL_UNSAFE_CHARS, ch)))
|
||||
strbuf_addf(dst, "%%%02X", (unsigned char)ch);
|
||||
else
|
||||
strbuf_addch(dst, ch);
|
||||
diff --git a/strbuf.h b/strbuf.h
|
||||
index f6dbb9681e..f9f8bb0381 100644
|
||||
--- a/strbuf.h
|
||||
+++ b/strbuf.h
|
||||
@@ -380,6 +380,7 @@ size_t strbuf_expand_dict_cb(struct strbuf *sb,
|
||||
void strbuf_addbuf_percentquote(struct strbuf *dst, const struct strbuf *src);
|
||||
|
||||
#define STRBUF_ENCODE_SLASH 1
|
||||
+#define STRBUF_ENCODE_HOST_AND_PORT 2
|
||||
|
||||
/**
|
||||
* Append the contents of a string to a strbuf, percent-encoding any characters
|
||||
diff --git a/t/t0300-credentials.sh b/t/t0300-credentials.sh
|
||||
index c66d91e82d..cb91be1427 100755
|
||||
--- a/t/t0300-credentials.sh
|
||||
+++ b/t/t0300-credentials.sh
|
||||
@@ -514,6 +514,19 @@ test_expect_success 'match percent-encoded values in username' '
|
||||
EOF
|
||||
'
|
||||
|
||||
+test_expect_success 'match percent-encoded values in hostname' '
|
||||
+ test_config "credential.https://a%20b%20c/.helper" "$HELPER" &&
|
||||
+ check fill <<-\EOF
|
||||
+ url=https://a b c/
|
||||
+ --
|
||||
+ protocol=https
|
||||
+ host=a b c
|
||||
+ username=foo
|
||||
+ password=bar
|
||||
+ --
|
||||
+ EOF
|
||||
+'
|
||||
+
|
||||
test_expect_success 'fetch with multiple path components' '
|
||||
test_unconfig credential.helper &&
|
||||
test_config credential.https://example.com/foo/repo.git.helper "verbatim foo bar" &&
|
||||
--
|
||||
2.47.1
|
314
CVE-2024-50349-2.patch
Normal file
314
CVE-2024-50349-2.patch
Normal file
@ -0,0 +1,314 @@
|
||||
From 7725b8100ffbbff2750ee4d61a0fcc1f53a086e8 Mon Sep 17 00:00:00 2001
|
||||
From: Johannes Schindelin <johannes.schindelin@gmx.de>
|
||||
Date: Wed, 30 Oct 2024 13:26:10 +0100
|
||||
Subject: [PATCH 2/2] credential: sanitize the user prompt
|
||||
|
||||
When asking the user interactively for credentials, we want to avoid
|
||||
misleading them e.g. via control sequences that pretend that the URL
|
||||
targets a trusted host when it does not.
|
||||
|
||||
While Git learned, over the course of the preceding commits, to disallow
|
||||
URLs containing URL-encoded control characters by default, credential
|
||||
helpers are still allowed to specify values very freely (apart from Line
|
||||
Feed and NUL characters, anything is allowed), and this would allow,
|
||||
say, a username containing control characters to be specified that would
|
||||
then be displayed in the interactive terminal prompt asking the user for
|
||||
the password, potentially sending those control characters directly to
|
||||
the terminal. This is undesirable because control characters can be used
|
||||
to mislead users to divulge secret information to untrusted sites.
|
||||
|
||||
To prevent such an attack vector, let's add a `git_prompt()` that forces
|
||||
the displayed text to be sanitized, i.e. displaying question marks
|
||||
instead of control characters.
|
||||
|
||||
Note: While this commit's diff changes a lot of `user@host` strings to
|
||||
`user%40host`, which may look suspicious on the surface, there is a good
|
||||
reason for that: this string specifies a user name, not a
|
||||
<username>@<hostname> combination! In the context of t5541, the actual
|
||||
combination looks like this: `user%40@127.0.0.1:5541`. Therefore, these
|
||||
string replacements document a net improvement introduced by this
|
||||
commit, as `user@host@127.0.0.1` could have left readers wondering where
|
||||
the user name ends and where the host name begins.
|
||||
|
||||
Hinted-at-by: Jeff King <peff@peff.net>
|
||||
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
|
||||
---
|
||||
Documentation/config/credential.txt | 6 ++++++
|
||||
credential.c | 7 ++++++-
|
||||
credential.h | 4 +++-
|
||||
t/t0300-credentials.sh | 20 ++++++++++++++++++++
|
||||
t/t5541-http-push-smart.sh | 6 +++---
|
||||
t/t5550-http-fetch-dumb.sh | 14 +++++++-------
|
||||
t/t5551-http-fetch-smart.sh | 16 ++++++++--------
|
||||
7 files changed, 53 insertions(+), 20 deletions(-)
|
||||
|
||||
Index: b/Documentation/config/credential.txt
|
||||
===================================================================
|
||||
--- a/Documentation/config/credential.txt
|
||||
+++ b/Documentation/config/credential.txt
|
||||
@@ -14,6 +14,12 @@ credential.useHttpPath::
|
||||
or https URL to be important. Defaults to false. See
|
||||
linkgit:gitcredentials[7] for more information.
|
||||
|
||||
+credential.sanitizePrompt::
|
||||
+ By default, user names and hosts that are shown as part of the
|
||||
+ password prompt are not allowed to contain control characters (they
|
||||
+ will be URL-encoded by default). Configure this setting to `false` to
|
||||
+ override that behavior.
|
||||
+
|
||||
credential.username::
|
||||
If no username is set for a network authentication, use this username
|
||||
by default. See credential.<context>.* below, and
|
||||
Index: b/credential.c
|
||||
===================================================================
|
||||
--- a/credential.c
|
||||
+++ b/credential.c
|
||||
@@ -125,6 +125,8 @@ static int credential_config_callback(co
|
||||
}
|
||||
else if (!strcmp(key, "usehttppath"))
|
||||
c->use_http_path = git_config_bool(var, value);
|
||||
+ else if (!strcmp(key, "sanitizeprompt"))
|
||||
+ c->sanitize_prompt = git_config_bool(var, value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -237,7 +239,10 @@ static char *credential_ask_one(const ch
|
||||
struct strbuf prompt = STRBUF_INIT;
|
||||
char *r;
|
||||
|
||||
- credential_describe(c, &desc);
|
||||
+ if (c->sanitize_prompt)
|
||||
+ credential_format(c, &desc);
|
||||
+ else
|
||||
+ credential_describe(c, &desc);
|
||||
if (desc.len)
|
||||
strbuf_addf(&prompt, "%s for '%s': ", what, desc.buf);
|
||||
else
|
||||
Index: b/credential.h
|
||||
===================================================================
|
||||
--- a/credential.h
|
||||
+++ b/credential.h
|
||||
@@ -168,7 +168,8 @@ struct credential {
|
||||
multistage: 1,
|
||||
quit:1,
|
||||
use_http_path:1,
|
||||
- username_from_proto:1;
|
||||
+ username_from_proto:1,
|
||||
+ sanitize_prompt:1;
|
||||
|
||||
struct credential_capability capa_authtype;
|
||||
struct credential_capability capa_state;
|
||||
@@ -195,6 +196,7 @@ struct credential {
|
||||
.wwwauth_headers = STRVEC_INIT, \
|
||||
.state_headers = STRVEC_INIT, \
|
||||
.state_headers_to_send = STRVEC_INIT, \
|
||||
+ .sanitize_prompt = 1, \
|
||||
}
|
||||
|
||||
/* Initialize a credential structure, setting all fields to empty. */
|
||||
Index: b/t/t0300-credentials.sh
|
||||
===================================================================
|
||||
--- a/t/t0300-credentials.sh
|
||||
+++ b/t/t0300-credentials.sh
|
||||
@@ -77,6 +77,10 @@ test_expect_success 'setup helper script
|
||||
test -z "$pexpiry" || echo password_expiry_utc=$pexpiry
|
||||
EOF
|
||||
|
||||
+ write_script git-credential-cntrl-in-username <<-\EOF &&
|
||||
+ printf "username=\\007latrix Lestrange\\n"
|
||||
+ EOF
|
||||
+
|
||||
PATH="$PWD:$PATH"
|
||||
'
|
||||
|
||||
@@ -1008,4 +1012,20 @@ test_expect_success 'credential config w
|
||||
test_grep "skipping credential lookup for key" stderr
|
||||
'
|
||||
|
||||
+BEL="$(printf '\007')"
|
||||
+
|
||||
+test_expect_success 'interactive prompt is sanitized' '
|
||||
+ check fill cntrl-in-username <<-EOF
|
||||
+ protocol=https
|
||||
+ host=example.org
|
||||
+ --
|
||||
+ protocol=https
|
||||
+ host=example.org
|
||||
+ username=${BEL}latrix Lestrange
|
||||
+ password=askpass-password
|
||||
+ --
|
||||
+ askpass: Password for ${SQ}https://%07latrix%20Lestrange@example.org${SQ}:
|
||||
+ EOF
|
||||
+'
|
||||
+
|
||||
test_done
|
||||
Index: b/t/t5541-http-push-smart.sh
|
||||
===================================================================
|
||||
--- a/t/t5541-http-push-smart.sh
|
||||
+++ b/t/t5541-http-push-smart.sh
|
||||
@@ -343,7 +343,7 @@ test_expect_success 'push over smart htt
|
||||
git push "$HTTPD_URL"/auth/smart/test_repo.git &&
|
||||
git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git" \
|
||||
log -1 --format=%s >actual &&
|
||||
- expect_askpass both user@host &&
|
||||
+ expect_askpass both user%40host &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
@@ -355,7 +355,7 @@ test_expect_success 'push to auth-only-f
|
||||
git push "$HTTPD_URL"/auth-push/smart/test_repo.git &&
|
||||
git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git" \
|
||||
log -1 --format=%s >actual &&
|
||||
- expect_askpass both user@host &&
|
||||
+ expect_askpass both user%40host &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
@@ -385,7 +385,7 @@ test_expect_success 'push into half-auth
|
||||
git push "$HTTPD_URL/half-auth-complete/smart/half-auth.git" &&
|
||||
git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/half-auth.git" \
|
||||
log -1 --format=%s >actual &&
|
||||
- expect_askpass both user@host &&
|
||||
+ expect_askpass both user%40host &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
Index: b/t/t5550-http-fetch-dumb.sh
|
||||
===================================================================
|
||||
--- a/t/t5550-http-fetch-dumb.sh
|
||||
+++ b/t/t5550-http-fetch-dumb.sh
|
||||
@@ -111,13 +111,13 @@ test_expect_success 'http auth can use u
|
||||
test_expect_success 'http auth can use just user in URL' '
|
||||
set_askpass wrong pass@host &&
|
||||
git clone "$HTTPD_URL_USER/auth/dumb/repo.git" clone-auth-pass &&
|
||||
- expect_askpass pass user@host
|
||||
+ expect_askpass pass user%40host
|
||||
'
|
||||
|
||||
test_expect_success 'http auth can request both user and pass' '
|
||||
set_askpass user@host pass@host &&
|
||||
git clone "$HTTPD_URL/auth/dumb/repo.git" clone-auth-both &&
|
||||
- expect_askpass both user@host
|
||||
+ expect_askpass both user%40host
|
||||
'
|
||||
|
||||
test_expect_success 'http auth respects credential helper config' '
|
||||
@@ -135,14 +135,14 @@ test_expect_success 'http auth can get u
|
||||
test_config_global "credential.$HTTPD_URL.username" user@host &&
|
||||
set_askpass wrong pass@host &&
|
||||
git clone "$HTTPD_URL/auth/dumb/repo.git" clone-auth-user &&
|
||||
- expect_askpass pass user@host
|
||||
+ expect_askpass pass user%40host
|
||||
'
|
||||
|
||||
test_expect_success 'configured username does not override URL' '
|
||||
test_config_global "credential.$HTTPD_URL.username" wrong &&
|
||||
set_askpass wrong pass@host &&
|
||||
git clone "$HTTPD_URL_USER/auth/dumb/repo.git" clone-auth-user2 &&
|
||||
- expect_askpass pass user@host
|
||||
+ expect_askpass pass user%40host
|
||||
'
|
||||
|
||||
test_expect_success 'set up repo with http submodules' '
|
||||
@@ -163,7 +163,7 @@ test_expect_success 'cmdline credential
|
||||
set_askpass wrong pass@host &&
|
||||
git -c "credential.$HTTPD_URL.username=user@host" \
|
||||
clone --recursive super super-clone &&
|
||||
- expect_askpass pass user@host
|
||||
+ expect_askpass pass user%40host
|
||||
'
|
||||
|
||||
test_expect_success 'cmdline credential config passes submodule via fetch' '
|
||||
@@ -174,7 +174,7 @@ test_expect_success 'cmdline credential
|
||||
git -C super-clone \
|
||||
-c "credential.$HTTPD_URL.username=user@host" \
|
||||
fetch --recurse-submodules &&
|
||||
- expect_askpass pass user@host
|
||||
+ expect_askpass pass user%40host
|
||||
'
|
||||
|
||||
test_expect_success 'cmdline credential config passes submodule update' '
|
||||
@@ -191,7 +191,7 @@ test_expect_success 'cmdline credential
|
||||
git -C super-clone \
|
||||
-c "credential.$HTTPD_URL.username=user@host" \
|
||||
submodule update &&
|
||||
- expect_askpass pass user@host
|
||||
+ expect_askpass pass user%40host
|
||||
'
|
||||
|
||||
test_expect_success 'fetch changes via http' '
|
||||
Index: b/t/t5551-http-fetch-smart.sh
|
||||
===================================================================
|
||||
--- a/t/t5551-http-fetch-smart.sh
|
||||
+++ b/t/t5551-http-fetch-smart.sh
|
||||
@@ -181,7 +181,7 @@ test_expect_success 'clone from password
|
||||
echo two >expect &&
|
||||
set_askpass user@host pass@host &&
|
||||
git clone --bare "$HTTPD_URL/auth/smart/repo.git" smart-auth &&
|
||||
- expect_askpass both user@host &&
|
||||
+ expect_askpass both user%40host &&
|
||||
git --git-dir=smart-auth log -1 --format=%s >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
@@ -199,7 +199,7 @@ test_expect_success 'clone from auth-onl
|
||||
echo two >expect &&
|
||||
set_askpass user@host pass@host &&
|
||||
git clone --bare "$HTTPD_URL/auth-fetch/smart/repo.git" half-auth &&
|
||||
- expect_askpass both user@host &&
|
||||
+ expect_askpass both user%40host &&
|
||||
git --git-dir=half-auth log -1 --format=%s >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
@@ -224,14 +224,14 @@ test_expect_success 'redirects send auth
|
||||
set_askpass user@host pass@host &&
|
||||
git -c credential.useHttpPath=true \
|
||||
clone $HTTPD_URL/smart-redir-auth/repo.git repo-redir-auth &&
|
||||
- expect_askpass both user@host auth/smart/repo.git
|
||||
+ expect_askpass both user%40host auth/smart/repo.git
|
||||
'
|
||||
|
||||
test_expect_success 'GIT_TRACE_CURL redacts auth details' '
|
||||
rm -rf redact-auth trace &&
|
||||
set_askpass user@host pass@host &&
|
||||
GIT_TRACE_CURL="$(pwd)/trace" git clone --bare "$HTTPD_URL/auth/smart/repo.git" redact-auth &&
|
||||
- expect_askpass both user@host &&
|
||||
+ expect_askpass both user%40host &&
|
||||
|
||||
# Ensure that there is no "Basic" followed by a base64 string, but that
|
||||
# the auth details are redacted
|
||||
@@ -243,7 +243,7 @@ test_expect_success 'GIT_CURL_VERBOSE re
|
||||
rm -rf redact-auth trace &&
|
||||
set_askpass user@host pass@host &&
|
||||
GIT_CURL_VERBOSE=1 git clone --bare "$HTTPD_URL/auth/smart/repo.git" redact-auth 2>trace &&
|
||||
- expect_askpass both user@host &&
|
||||
+ expect_askpass both user%40host &&
|
||||
|
||||
# Ensure that there is no "Basic" followed by a base64 string, but that
|
||||
# the auth details are redacted
|
||||
@@ -256,7 +256,7 @@ test_expect_success 'GIT_TRACE_CURL does
|
||||
set_askpass user@host pass@host &&
|
||||
GIT_TRACE_REDACT=0 GIT_TRACE_CURL="$(pwd)/trace" \
|
||||
git clone --bare "$HTTPD_URL/auth/smart/repo.git" redact-auth &&
|
||||
- expect_askpass both user@host &&
|
||||
+ expect_askpass both user%40host &&
|
||||
|
||||
grep -i "Authorization: Basic [0-9a-zA-Z+/]" trace
|
||||
'
|
||||
@@ -570,7 +570,7 @@ test_expect_success 'http auth remembers
|
||||
# the first request prompts the user...
|
||||
set_askpass user@host pass@host &&
|
||||
git ls-remote "$HTTPD_URL/auth/smart/repo.git" >/dev/null &&
|
||||
- expect_askpass both user@host &&
|
||||
+ expect_askpass both user%40host &&
|
||||
|
||||
# ...and the second one uses the stored value rather than
|
||||
# prompting the user.
|
||||
@@ -601,7 +601,7 @@ test_expect_success 'http auth forgets b
|
||||
# us to prompt the user again.
|
||||
set_askpass user@host pass@host &&
|
||||
git ls-remote "$HTTPD_URL/auth/smart/repo.git" >/dev/null &&
|
||||
- expect_askpass both user@host
|
||||
+ expect_askpass both user%40host
|
||||
'
|
||||
|
||||
test_expect_success 'client falls back from v2 to v0 to match server' '
|
193
CVE-2024-52006.patch
Normal file
193
CVE-2024-52006.patch
Normal file
@ -0,0 +1,193 @@
|
||||
From b01b9b81d36759cdcd07305e78765199e1bc2060 Mon Sep 17 00:00:00 2001
|
||||
From: Johannes Schindelin <johannes.schindelin@gmx.de>
|
||||
Date: Mon, 4 Nov 2024 14:48:22 +0100
|
||||
Subject: [PATCH] credential: disallow Carriage Returns in the protocol by
|
||||
default
|
||||
|
||||
While Git has documented that the credential protocol is line-based,
|
||||
with newlines as terminators, the exact shape of a newline has not been
|
||||
documented.
|
||||
|
||||
From Git's perspective, which is firmly rooted in the Linux ecosystem,
|
||||
it is clear that "a newline" means a Line Feed character.
|
||||
|
||||
However, even Git's credential protocol respects Windows line endings
|
||||
(a Carriage Return character followed by a Line Feed character, "CR/LF")
|
||||
by virtue of using `strbuf_getline()`.
|
||||
|
||||
There is a third category of line endings that has been used originally
|
||||
by MacOS, and that is respected by the default line readers of .NET and
|
||||
node.js: bare Carriage Returns.
|
||||
|
||||
Git cannot handle those, and what is worse: Git's remedy against
|
||||
CVE-2020-5260 does not catch when credential helpers are used that
|
||||
interpret bare Carriage Returns as newlines.
|
||||
|
||||
Git Credential Manager addressed this as CVE-2024-50338, but other
|
||||
credential helpers may still be vulnerable. So let's not only disallow
|
||||
Line Feed characters as part of the values in the credential protocol,
|
||||
but also disallow Carriage Return characters.
|
||||
|
||||
In the unlikely event that a credential helper relies on Carriage
|
||||
Returns in the protocol, introduce an escape hatch via the
|
||||
`credential.protectProtocol` config setting.
|
||||
|
||||
This addresses CVE-2024-52006.
|
||||
|
||||
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
|
||||
---
|
||||
Documentation/config/credential.txt | 5 +++++
|
||||
credential.c | 21 ++++++++++++++-------
|
||||
credential.h | 4 +++-
|
||||
t/t0300-credentials.sh | 16 ++++++++++++++++
|
||||
4 files changed, 38 insertions(+), 8 deletions(-)
|
||||
|
||||
Index: b/Documentation/config/credential.txt
|
||||
===================================================================
|
||||
--- a/Documentation/config/credential.txt
|
||||
+++ b/Documentation/config/credential.txt
|
||||
@@ -20,6 +20,11 @@ credential.sanitizePrompt::
|
||||
will be URL-encoded by default). Configure this setting to `false` to
|
||||
override that behavior.
|
||||
|
||||
+credential.protectProtocol::
|
||||
+ By default, Carriage Return characters are not allowed in the protocol
|
||||
+ that is used when Git talks to a credential helper. This setting allows
|
||||
+ users to override this default.
|
||||
+
|
||||
credential.username::
|
||||
If no username is set for a network authentication, use this username
|
||||
by default. See credential.<context>.* below, and
|
||||
Index: b/credential.c
|
||||
===================================================================
|
||||
--- a/credential.c
|
||||
+++ b/credential.c
|
||||
@@ -127,6 +127,8 @@ static int credential_config_callback(co
|
||||
c->use_http_path = git_config_bool(var, value);
|
||||
else if (!strcmp(key, "sanitizeprompt"))
|
||||
c->sanitize_prompt = git_config_bool(var, value);
|
||||
+ else if (!strcmp(key, "protectprotocol"))
|
||||
+ c->protect_protocol = git_config_bool(var, value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -361,7 +363,8 @@ int credential_read(struct credential *c
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static void credential_write_item(FILE *fp, const char *key, const char *value,
|
||||
+static void credential_write_item(const struct credential *c,
|
||||
+ FILE *fp, const char *key, const char *value,
|
||||
int required)
|
||||
{
|
||||
if (!value && required)
|
||||
@@ -370,6 +373,10 @@ static void credential_write_item(FILE *
|
||||
return;
|
||||
if (strchr(value, '\n'))
|
||||
die("credential value for %s contains newline", key);
|
||||
+ if (c->protect_protocol && strchr(value, '\r'))
|
||||
+ die("credential value for %s contains carriage return\n"
|
||||
+ "If this is intended, set `credential.protectProtocol=false`",
|
||||
+ key);
|
||||
fprintf(fp, "%s=%s\n", key, value);
|
||||
}
|
||||
|
||||
@@ -377,34 +384,34 @@ void credential_write(const struct crede
|
||||
enum credential_op_type op_type)
|
||||
{
|
||||
if (credential_has_capability(&c->capa_authtype, op_type))
|
||||
- credential_write_item(fp, "capability[]", "authtype", 0);
|
||||
+ credential_write_item(c, fp, "capability[]", "authtype", 0);
|
||||
if (credential_has_capability(&c->capa_state, op_type))
|
||||
- credential_write_item(fp, "capability[]", "state", 0);
|
||||
+ credential_write_item(c, fp, "capability[]", "state", 0);
|
||||
|
||||
if (credential_has_capability(&c->capa_authtype, op_type)) {
|
||||
- credential_write_item(fp, "authtype", c->authtype, 0);
|
||||
- credential_write_item(fp, "credential", c->credential, 0);
|
||||
+ credential_write_item(c, fp, "authtype", c->authtype, 0);
|
||||
+ credential_write_item(c, fp, "credential", c->credential, 0);
|
||||
if (c->ephemeral)
|
||||
- credential_write_item(fp, "ephemeral", "1", 0);
|
||||
+ credential_write_item(c, fp, "ephemeral", "1", 0);
|
||||
}
|
||||
- credential_write_item(fp, "protocol", c->protocol, 1);
|
||||
- credential_write_item(fp, "host", c->host, 1);
|
||||
- credential_write_item(fp, "path", c->path, 0);
|
||||
- credential_write_item(fp, "username", c->username, 0);
|
||||
- credential_write_item(fp, "password", c->password, 0);
|
||||
- credential_write_item(fp, "oauth_refresh_token", c->oauth_refresh_token, 0);
|
||||
+ credential_write_item(c, fp, "protocol", c->protocol, 1);
|
||||
+ credential_write_item(c, fp, "host", c->host, 1);
|
||||
+ credential_write_item(c, fp, "path", c->path, 0);
|
||||
+ credential_write_item(c, fp, "username", c->username, 0);
|
||||
+ credential_write_item(c, fp, "password", c->password, 0);
|
||||
+ credential_write_item(c, fp, "oauth_refresh_token", c->oauth_refresh_token, 0);
|
||||
if (c->password_expiry_utc != TIME_MAX) {
|
||||
char *s = xstrfmt("%"PRItime, c->password_expiry_utc);
|
||||
- credential_write_item(fp, "password_expiry_utc", s, 0);
|
||||
+ credential_write_item(c, fp, "password_expiry_utc", s, 0);
|
||||
free(s);
|
||||
}
|
||||
for (size_t i = 0; i < c->wwwauth_headers.nr; i++)
|
||||
- credential_write_item(fp, "wwwauth[]", c->wwwauth_headers.v[i], 0);
|
||||
+ credential_write_item(c, fp, "wwwauth[]", c->wwwauth_headers.v[i], 0);
|
||||
if (credential_has_capability(&c->capa_state, op_type)) {
|
||||
if (c->multistage)
|
||||
- credential_write_item(fp, "continue", "1", 0);
|
||||
+ credential_write_item(c, fp, "continue", "1", 0);
|
||||
for (size_t i = 0; i < c->state_headers_to_send.nr; i++)
|
||||
- credential_write_item(fp, "state[]", c->state_headers_to_send.v[i], 0);
|
||||
+ credential_write_item(c, fp, "state[]", c->state_headers_to_send.v[i], 0);
|
||||
}
|
||||
}
|
||||
|
||||
Index: b/credential.h
|
||||
===================================================================
|
||||
--- a/credential.h
|
||||
+++ b/credential.h
|
||||
@@ -169,7 +169,8 @@ struct credential {
|
||||
quit:1,
|
||||
use_http_path:1,
|
||||
username_from_proto:1,
|
||||
- sanitize_prompt:1;
|
||||
+ sanitize_prompt:1,
|
||||
+ protect_protocol:1;
|
||||
|
||||
struct credential_capability capa_authtype;
|
||||
struct credential_capability capa_state;
|
||||
@@ -197,6 +198,7 @@ struct credential {
|
||||
.state_headers = STRVEC_INIT, \
|
||||
.state_headers_to_send = STRVEC_INIT, \
|
||||
.sanitize_prompt = 1, \
|
||||
+ .protect_protocol = 1, \
|
||||
}
|
||||
|
||||
/* Initialize a credential structure, setting all fields to empty. */
|
||||
Index: b/t/t0300-credentials.sh
|
||||
===================================================================
|
||||
--- a/t/t0300-credentials.sh
|
||||
+++ b/t/t0300-credentials.sh
|
||||
@@ -903,6 +903,22 @@ test_expect_success 'url parser rejects
|
||||
test_cmp expect stderr
|
||||
'
|
||||
|
||||
+test_expect_success 'url parser rejects embedded carriage returns' '
|
||||
+ test_config credential.helper "!true" &&
|
||||
+ test_must_fail git credential fill 2>stderr <<-\EOF &&
|
||||
+ url=https://example%0d.com/
|
||||
+ EOF
|
||||
+ cat >expect <<-\EOF &&
|
||||
+ fatal: credential value for host contains carriage return
|
||||
+ If this is intended, set `credential.protectProtocol=false`
|
||||
+ EOF
|
||||
+ test_cmp expect stderr &&
|
||||
+ GIT_ASKPASS=true \
|
||||
+ git -c credential.protectProtocol=false credential fill <<-\EOF
|
||||
+ url=https://example%0d.com/
|
||||
+ EOF
|
||||
+'
|
||||
+
|
||||
test_expect_success 'host-less URLs are parsed as empty host' '
|
||||
check fill "verbatim foo bar" <<-\EOF
|
||||
url=cert:///path/to/cert.pem
|
10
git.changes
10
git.changes
@ -1,3 +1,13 @@
|
||||
-------------------------------------------------------------------
|
||||
Thu Jan 16 22:29:07 UTC 2025 - Antonio Teixeira <antonio.teixeira@suse.com>
|
||||
|
||||
- Add CVE-2024-50349-1.patch, CVE-2024-50349-2.patch
|
||||
* CVE-2024-50349: passwords for trusted sites could be sent to untrusted
|
||||
sites (bsc#1235600)
|
||||
- Add CVE-2024-52006.patch
|
||||
* CVE-2024-52006: Carriage Returns via the credential protocol to credential
|
||||
helpers (bsc#1235601)
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Sep 20 08:18:30 UTC 2024 - Dominique Leuenberger <dimstar@opensuse.org>
|
||||
|
||||
|
7
git.spec
7
git.spec
@ -70,6 +70,13 @@ Patch8: git-asciidoc.patch
|
||||
Patch10: setup-don-t-fail-if-commondir-reference-is-deleted.patch
|
||||
# PATCH-FIX-OPENSUSE CVE-2024-24577.patch boo#1219660 antonio.teixeira@suse.com
|
||||
Patch11: CVE-2024-24577.patch
|
||||
# PATCH-FIX-UPSTREAM antonio.teixeira@suse.com bsc#1235600
|
||||
# passwords for trusted sites could be sent to untrusted sites
|
||||
Patch12: CVE-2024-50349-1.patch
|
||||
Patch13: CVE-2024-50349-2.patch
|
||||
# PATCH-FIX-UPSTREAM antonio.teixeira@suse.com bsc#1235601
|
||||
# Carriage Returns via the credential protocol to credential helpers
|
||||
Patch14: CVE-2024-52006.patch
|
||||
BuildRequires: fdupes
|
||||
BuildRequires: gpg2
|
||||
BuildRequires: libcurl-devel
|
||||
|
Loading…
x
Reference in New Issue
Block a user