From c1489ca0e101a81df6f8b1ba8d8a9afd9ebc6412 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 25 Jul 2022 09:46:41 +0200 Subject: [PATCH] wkd: Fix path traversal attack on gpg-wks-server. * tools/gpg-wks-server.c (check_and_publish): Check for invalid characters in sender controlled data. * tools/wks-util.c (wks_fname_from_userid): Ditto. (wks_compute_hu_fname): Ditto. (ensure_policy_file): Ditto. --- tools/gpg-wks-server.c | 9 +++++++++ tools/wks-util.c | 16 ++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/tools/gpg-wks-server.c b/tools/gpg-wks-server.c index 96f0a03a0..144580247 100644 --- a/tools/gpg-wks-server.c +++ b/tools/gpg-wks-server.c @@ -1378,6 +1378,15 @@ check_and_publish (server_ctx_t ctx, const char *address, const char *nonce) domain = strchr (address, '@'); log_assert (domain && domain[1]); domain++; + if (strchr (domain, '/') || strchr (domain, '\\') + || strchr (nonce, '/') || strchr (nonce, '\\')) + { + log_info ("invalid domain or nonce received ('%s', '%s')\n", + domain, nonce); + err = gpg_error (GPG_ERR_NOT_FOUND); + goto leave; + } + fname = make_filename_try (opt.directory, domain, "pending", nonce, NULL); if (!fname) { diff --git a/tools/wks-util.c b/tools/wks-util.c index 025b1b7ae..4fa28bb9f 100644 --- a/tools/wks-util.c +++ b/tools/wks-util.c @@ -790,6 +790,12 @@ wks_fname_from_userid (const char *userid, int hash_only, domain = strchr (addrspec, '@'); log_assert (domain); domain++; + if (strchr (domain, '/') || strchr (domain, '\\')) + { + log_info ("invalid domain detected ('%s')\n", domain); + err = gpg_error (GPG_ERR_NOT_FOUND); + goto leave; + } /* Hash user ID and create filename. */ s = strchr (addrspec, '@'); @@ -845,6 +851,11 @@ wks_compute_hu_fname (char **r_fname, const char *addrspec) if (!domain || !domain[1] || domain == addrspec) return gpg_error (GPG_ERR_INV_ARG); domain++; + if (strchr (domain, '/') || strchr (domain, '\\')) + { + log_info ("invalid domain detected ('%s')\n", domain); + return gpg_error (GPG_ERR_NOT_FOUND); + } gcry_md_hash_buffer (GCRY_MD_SHA1, sha1buf, addrspec, domain - addrspec - 1); hash = zb32_encode (sha1buf, 8*20); @@ -893,6 +904,11 @@ ensure_policy_file (const char *addrspec) if (!domain || !domain[1] || domain == addrspec) return gpg_error (GPG_ERR_INV_ARG); domain++; + if (strchr (domain, '/') || strchr (domain, '\\')) + { + log_info ("invalid domain detected ('%s')\n", domain); + return gpg_error (GPG_ERR_NOT_FOUND); + } /* Create the filename. */ fname = make_filename_try (opt.directory, domain, "policy", NULL);