mirror of
https://gitlab.com/buildroot.org/buildroot.git
synced 2026-09-10 08:14:09 -09:00
- GHSA-cgh5-39mg-vhfr: Path traversal in authentication via unsanitized
username allows auth bypass
https://github.com/cminyard/ser2net/security/advisories/GHSA-cgh5-39mg-vhfr
No CVE ID yet.
Signed-off-by: Mattia Narducci <mattianarducci1@gmail.com>
Signed-off-by: Julien Olivain <ju.o@free.fr>
(cherry picked from commit 9809b30290)
Signed-off-by: Titouan Christophe <titouan.christophe@mind.be>
90 lines
2.7 KiB
Diff
90 lines
2.7 KiB
Diff
From fa6c2a8840cbc8d7622e46ce12ba15ecc0fb51b7 Mon Sep 17 00:00:00 2001
|
|
From: Corey Minyard <corey@minyard.net>
|
|
Date: Thu, 23 Jul 2026 10:51:25 -0500
|
|
Subject: [PATCH] Fix authorization path handling
|
|
|
|
The username is received from the remote end and thus untrusted. Make
|
|
sure it doesn't have any characters that can cause it to escape the
|
|
directory it is supposed to be in when constructing a path.
|
|
|
|
Reported-by: TristanInSec
|
|
Signed-off-by: Corey Minyard <corey@minyard.net>
|
|
|
|
Upstream: https://github.com/cminyard/ser2net/commit/fa6c2a8840cbc8d7622e46ce12ba15ecc0fb51b7
|
|
|
|
Signed-off-by: Mattia Narducci <mattianarducci1@gmail.com>
|
|
---
|
|
auth.c | 42 ++++++++++++++++++++++++++++++++++++++----
|
|
1 file changed, 38 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/auth.c b/auth.c
|
|
index 95c80b4..53c3186 100644
|
|
--- a/auth.c
|
|
+++ b/auth.c
|
|
@@ -185,6 +185,40 @@ handle_auth_begin(struct gensio *net, const char *authdir, const char *pamauth,
|
|
return GE_NOTSUP;
|
|
}
|
|
|
|
+/*
|
|
+ * Construct a secure authorization path.
|
|
+ *
|
|
+ * filename must be at least MAX_PATH.
|
|
+ *
|
|
+ * "username" is untrusted, the rest of the data is trusted.
|
|
+ */
|
|
+static bool
|
|
+construct_auth_path(char *filename, const char *authdir, const char *username,
|
|
+ const char *format, ...)
|
|
+{
|
|
+ size_t baselen;
|
|
+ va_list ap;
|
|
+
|
|
+ /*
|
|
+ * '/', '.', and '\' are all parts of things that can modify the base
|
|
+ * path. Don't allow them in usernames.
|
|
+ */
|
|
+ if (strchr(username, '.') || strchr(username, '/')
|
|
+ || strchr(username, '\\'))
|
|
+ return false;
|
|
+
|
|
+ /* Get a good base path ending in / */
|
|
+ baselen = snprintf(filename, PATH_MAX, "%s/%s/",
|
|
+ authdir, username);
|
|
+
|
|
+ /* Now append the rest of the path. */
|
|
+ va_start(ap, format);
|
|
+ vsnprintf(filename + baselen, PATH_MAX - baselen, format, ap);
|
|
+ va_end(ap);
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
static int
|
|
handle_precert(struct gensio *net, const char *authdir)
|
|
{
|
|
@@ -228,8 +262,8 @@ handle_precert(struct gensio *net, const char *authdir)
|
|
}
|
|
}
|
|
|
|
- snprintf(filename, sizeof(filename), "%s/%s/allowed_certs/",
|
|
- authdir, s);
|
|
+ if (!construct_auth_path(filename, authdir, s, "allowed_certs/"))
|
|
+ return GE_AUTHREJECT;
|
|
err = gensio_control(net, 0, false, GENSIO_CONTROL_CERT_AUTH,
|
|
filename, &len);
|
|
if (err && err != GE_CERTNOTFOUND) {
|
|
@@ -258,8 +292,8 @@ handle_password(struct gensio *net, const char *authdir, const char *password)
|
|
return GE_AUTHREJECT;
|
|
}
|
|
|
|
- snprintf(filename, sizeof(filename), "%s/%s/password",
|
|
- authdir, username);
|
|
+ if (!construct_auth_path(filename, authdir, username, "password"))
|
|
+ return GE_AUTHREJECT;
|
|
pwfile = fopen(filename, "r");
|
|
if (!pwfile) {
|
|
syslog(LOG_ERR, "Can't open password file %s: %s", filename,
|
|
--
|
|
2.55.0
|
|
|