From aec8ec45a496ad4b034bbc5cadf00f205c8e0fd3 Mon Sep 17 00:00:00 2001 From: Cave Spectre Date: Sat, 13 Jul 2019 17:39:58 -0400 Subject: [PATCH] [RPC] require valid URL scheme on budget commands --- src/rpc/budget.cpp | 5 +++-- src/utilstrencodings.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ src/utilstrencodings.h | 1 + 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/src/rpc/budget.cpp b/src/rpc/budget.cpp index e05b61ff9b272e..27d60764e7332f 100644 --- a/src/rpc/budget.cpp +++ b/src/rpc/budget.cpp @@ -56,8 +56,9 @@ void checkBudgetInputs(const UniValue& params, std::string &strProposalName, std throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid proposal name, limit of 20 characters."); strURL = SanitizeString(params[1].get_str()); - if (strURL.size() > 64) - throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid url, limit of 64 characters."); + std::string strErr; + if (!validateURL(strURL, strErr)) + throw JSONRPCError(RPC_INVALID_PARAMETER, strErr); nPaymentCount = params[2].get_int(); if (nPaymentCount < 1) diff --git a/src/utilstrencodings.cpp b/src/utilstrencodings.cpp index 16fd87aa4f3d5b..41ee86c954a668 100644 --- a/src/utilstrencodings.cpp +++ b/src/utilstrencodings.cpp @@ -39,6 +39,46 @@ std::string SanitizeString(const std::string& str, int rule) return strResult; } +/* +** bool validateURL(std::string, int [optional, defaulted to 64]) +** +** Input: +** strURL: A std::string URL to be be processed for validity. +** strErr: A std::string to be filled with any error messages. +** maxSize: An int to define the maximum size the URL can be; +** Optional, defaulting to 64. +** +** Return: +** boolean true|false result if the validation passes. +** strRrror: Filled with any error messages. +*/ +bool validateURL(std::string strURL, std::string& strErr, unsigned int maxSize) { + + // Check URL size + if (strURL.size() > maxSize) { + strErr = strprintf("Invalid URL: %d exceeds limit of %d characters.", strURL.size(), maxSize); + return false; + } + + std::vector reqPre; + + // Required initial strings; URL must contain one + reqPre.push_back("http://"); + reqPre.push_back("https://"); + + // check fronts + bool found = false; + for (int i=0; i < reqPre.size() && !found; i++) { + if (strURL.find(reqPre[i]) == 0) found = true; + } + if ((!found) && (reqPre.size() > 0)) { + strErr = "Invalid URL, check scheme (e.g. https://)"; + return false; + } + + return true; +} + const signed char p_util_hexdigit[256] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, diff --git a/src/utilstrencodings.h b/src/utilstrencodings.h index 97c3bfd91fbc93..5f7dfbc120ee80 100644 --- a/src/utilstrencodings.h +++ b/src/utilstrencodings.h @@ -40,6 +40,7 @@ enum SafeChars * @return A new string without unsafe chars */ std::string SanitizeString(const std::string& str, int rule = SAFE_CHARS_DEFAULT); +bool validateURL(std::string strURL, std::string& strErr, unsigned int maxSize = 64); std::vector ParseHex(const char* psz); std::vector ParseHex(const std::string& str); signed char HexDigit(char c);