commit 3cc2337cdca35104f7c25ac4941bef4aeb350d61
parent f7d23c37f57d55e2355ea8f8162ab3630d6d0bf2
Author: Christian Grothoff <christian@grothoff.org>
Date: Thu, 13 Aug 2026 20:26:03 +0200
improve payto:// URI validation logic
Diffstat:
1 file changed, 28 insertions(+), 0 deletions(-)
diff --git a/src/util/payto.c b/src/util/payto.c
@@ -81,6 +81,16 @@ TALER_full_payto_normalize_and_hash (const struct TALER_FullPayto in,
normalized_payto_uri
= TALER_payto_normalize (in);
+ if (NULL == normalized_payto_uri.normalized_payto)
+ {
+ /* Callers must have validated @a in; never crash on a URI that
+ slipped through. */
+ GNUNET_break (0);
+ memset (out,
+ 0,
+ sizeof (*out));
+ return;
+ }
TALER_normalized_payto_hash (normalized_payto_uri,
out);
GNUNET_free (normalized_payto_uri.normalized_payto);
@@ -250,6 +260,24 @@ validate_payto_iban (const char *payto_uri)
q = memchr (payto_uri,
'?',
slen);
+ /* RFC 8905, Section 7.3: the path is either "$IBAN" or "$BIC/$IBAN".
+ Reject anything else here, so that normalize_payto_iban() -- which
+ enforces the same rule by returning NULL -- can never be handed a
+ URI that passed validation. */
+ {
+ unsigned int sc = 0;
+ size_t plen = (NULL == q)
+ ? slen
+ : (size_t) (q - payto_uri);
+
+ for (size_t i = 0; i < plen; i++)
+ if ('/' == payto_uri[i])
+ sc++;
+ if ( (sc < 3) ||
+ (sc > 4) )
+ return GNUNET_strdup (
+ "'iban' payto:// URI must have one or two path components");
+ }
/* Find the last '/' that is part of the path, i.e. before any '?'
query part ('/' is a legal character in a query value and must
not be mistaken for the path separator). */