From e3a7aa0033849150cdc397680921959c2c986381 Mon Sep 17 00:00:00 2001 From: Nik Bougalis Date: Wed, 21 Jan 2015 05:44:39 -0800 Subject: [PATCH] Constrain valid inputs for memo fields (RIPD-712) --- src/ripple/protocol/impl/STTx.cpp | 55 ++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 4 deletions(-) diff --git a/src/ripple/protocol/impl/STTx.cpp b/src/ripple/protocol/impl/STTx.cpp index 57538454a..b6ea42c36 100644 --- a/src/ripple/protocol/impl/STTx.cpp +++ b/src/ripple/protocol/impl/STTx.cpp @@ -31,6 +31,7 @@ #include #include #include +#include namespace ripple { @@ -308,13 +309,59 @@ isMemoOkay (STObject const& st, std::string& reason) for (auto const& memoElement : *memoObj) { - if ((memoElement.getFName() != sfMemoType) && - (memoElement.getFName() != sfMemoData) && - (memoElement.getFName() != sfMemoFormat)) + auto const& name = memoElement.getFName(); + + if (name != sfMemoType && + name != sfMemoData && + name != sfMemoFormat) { - reason = "A memo may contain only MemoType, MemoData or MemoFormat fields."; + reason = "A memo may contain only MemoType, MemoData or " + "MemoFormat fields."; return false; } + + // The raw data is stored as hex-octets, which we want to decode. + auto data = strUnHex (memoElement.getText ()); + + if (!data.second) + { + reason = "The MemoType, MemoData and MemoFormat fields may " + "only contain hex-encoded data."; + return false; + } + + if (name == sfMemoData) + continue; + + // The only allowed characters for MemoType and MemoFormat are the + // characters allowed in URLs per RFC 3986: alphanumerics and the + // following symbols: -._~:/?#[]@!$&'()*+,;=% + static std::array const allowedSymbols = [] + { + std::array a; + a.fill(0); + + std::string symbols ( + "0123456789" + "-._~:/?#[]@!$&'()*+,;=%" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz"); + + for(char c : symbols) + a[c] = 1; + return a; + }(); + + for (auto c : data.first) + { + if (!allowedSymbols[c]) + { + reason = "The MemoType and MemoFormat fields may only " + "contain characters that are allowed in URLs " + "under RFC 3986."; + return false; + } + } } }