harden URI validation logic

This commit is contained in:
Christian Grothoff 2020-03-16 16:13:21 +01:00
parent 84ccc79881
commit 7fee395bb6
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
3 changed files with 46 additions and 14 deletions

View File

@ -111,7 +111,7 @@ load_account (void *cls,
if (NULL == (url = TALER_JSON_wire_to_payto (wire_s))) if (NULL == (url = TALER_JSON_wire_to_payto (wire_s)))
{ {
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Wire response file `%s' lacks `url' entry\n", "Wire response file `%s' lacks `payto_uri' entry\n",
ai->wire_response_filename); ai->wire_response_filename);
json_decref (wire_s); json_decref (wire_s);
*ret = GNUNET_SYSERR; *ret = GNUNET_SYSERR;

View File

@ -202,7 +202,7 @@ TALER_JSON_wire_to_method (const json_t *wire_s);
/** /**
* Obtain the payto://-URL associated with the given * Obtain the payto://-URL associated with the given
* wire account details. @a wire_s must contain a payto://-URL * wire account details. @a wire_s must contain a payto://-URL
* under 'url'. * under 'payto_uri'.
* *
* @return NULL on error * @return NULL on error
*/ */

View File

@ -321,7 +321,7 @@ validate_iban (const char *iban)
* @param account_url URL to parse * @param account_url URL to parse
* @return #GNUNET_YES if @a account_url is a valid payto://iban URI, * @return #GNUNET_YES if @a account_url is a valid payto://iban URI,
* #GNUNET_NO if @a account_url is a payto URI of a different type, * #GNUNET_NO if @a account_url is a payto URI of a different type,
* #GNUNET_SYSERR if the IBAN (checksum) is incorrect * #GNUNET_SYSERR if the IBAN (checksum) is incorrect or this is not a payto://-URI
*/ */
static int static int
validate_payto_iban (const char *account_url) validate_payto_iban (const char *account_url)
@ -330,13 +330,13 @@ validate_payto_iban (const char *account_url)
const char *q; const char *q;
char *result; char *result;
#define PREFIX "payto://iban/" #define IBAN_PREFIX "payto://iban/"
if (0 != strncasecmp (account_url, if (0 != strncasecmp (account_url,
PREFIX, IBAN_PREFIX,
strlen (PREFIX))) strlen (IBAN_PREFIX)))
return GNUNET_NO; return GNUNET_NO;
iban = &account_url[strlen (PREFIX)]; iban = &account_url[strlen (IBAN_PREFIX)];
#undef PREFIX #undef IBAN_PREFIX
q = strchr (iban, q = strchr (iban,
'?'); '?');
if (NULL != q) if (NULL != q)
@ -359,6 +359,33 @@ validate_payto_iban (const char *account_url)
} }
/**
* Validate payto:// account URL (only account information,
* wire subject and amount are ignored).
*
* @param account_url URL to parse
* @return #GNUNET_YES if @a account_url is a valid payto://iban URI
* #GNUNET_NO if @a account_url is a payto URI of an unsupported type (but may be valid)
* #GNUNET_SYSERR if the account incorrect or this is not a payto://-URI at all
*/
static int
validate_payto (const char *account_url)
{
int ret;
#define PAYTO_PREFIX "payto://"
if (0 != strncasecmp (account_url,
PAYTO_PREFIX,
strlen (PAYTO_PREFIX)))
return GNUNET_SYSERR; /* not payto */
#undef PAYTO_PREFIX
if (GNUNET_NO != (ret = validate_payto_iban (account_url)))
return ret; /* got a definitive answer */
/* Insert other bank account validation methods here later! */
return GNUNET_NO;
}
/** /**
* Compute the hash of the given wire details. The resulting * Compute the hash of the given wire details. The resulting
* hash is what is put into the contract. * hash is what is put into the contract.
@ -424,8 +451,7 @@ TALER_JSON_exchange_wire_signature_check (const json_t *wire_s,
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
/* Note: this check does nothing if this is not an IBAN */ if (GNUNET_SYSERR == validate_payto (payto_uri))
if (GNUNET_SYSERR == validate_payto_iban (payto_uri))
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
return GNUNET_SYSERR; return GNUNET_SYSERR;
@ -451,8 +477,7 @@ TALER_JSON_exchange_wire_signature_make (const char *payto_uri,
{ {
struct TALER_MasterSignatureP master_sig; struct TALER_MasterSignatureP master_sig;
/* Note: this check does nothing if this is not an IBAN */ if (GNUNET_SYSERR == validate_payto (payto_uri))
if (GNUNET_SYSERR == validate_payto_iban (payto_uri))
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
return NULL; return NULL;
@ -470,7 +495,7 @@ TALER_JSON_exchange_wire_signature_make (const char *payto_uri,
/** /**
* Obtain the wire method associated with the given * Obtain the wire method associated with the given
* wire account details. @a wire_s must contain a payto://-URL * wire account details. @a wire_s must contain a payto://-URL
* under 'url'. * under 'payto_uri'.
* *
* @return NULL on error * @return NULL on error
*/ */
@ -486,7 +511,14 @@ TALER_JSON_wire_to_payto (const json_t *wire_s)
(NULL == (payto_str = json_string_value (payto_o))) ) (NULL == (payto_str = json_string_value (payto_o))) )
{ {
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Fatally malformed wire record encountered: lacks payto://-url\n"); "Malformed wire record encountered: lacks payto://-url\n");
return NULL;
}
if (GNUNET_SYSERR == validate_payto (payto_str))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Malformed wire record encountered: payto URI `%s' invalid\n",
payto_str);
return NULL; return NULL;
} }
return GNUNET_strdup (payto_str); return GNUNET_strdup (payto_str);