From ade1afe1b00e83a26c9cd70e0cfddf2cf83414d4 Mon Sep 17 00:00:00 2001 From: Mark Travis Date: Wed, 4 Sep 2019 01:38:32 -0700 Subject: [PATCH] Support multiple proxies in X-Forwarded-For header --- src/ripple/rpc/impl/Role.cpp | 33 +++++++++++++++++++++------------ src/test/rpc/Roles_test.cpp | 5 +++++ 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/src/ripple/rpc/impl/Role.cpp b/src/ripple/rpc/impl/Role.cpp index 6f8e97f5d90..278f3c55bc0 100644 --- a/src/ripple/rpc/impl/Role.cpp +++ b/src/ripple/rpc/impl/Role.cpp @@ -19,6 +19,9 @@ #include #include +#include +#include +#include #include namespace ripple { @@ -108,14 +111,7 @@ requestInboundEndpoint (Resource::Manager& manager, boost::string_view forwardedFor(http_request_type const& request) { - auto it = request.find("X-Forwarded-For"); - if (it != request.end()) - { - return boost::beast::http::ext_list{ - it->value()}.begin()->first; - } - - it = request.find("Forwarded"); + auto it = request.find(boost::beast::http::field::forwarded); if (it != request.end()) { auto ascii_tolower = [](char c) -> char @@ -137,10 +133,23 @@ forwardedFor(http_request_type const& request) return {}; found += forStr.size(); - auto pos{it->value().find(';', forStr.size())}; - if (pos != boost::string_view::npos) - return {found, pos + 1}; - return {found, it->value().size() - forStr.size()}; + std::size_t const pos ([&]() + { + std::size_t const pos{boost::string_view( + found, it->value().end() - found).find(';')}; + if (pos == boost::string_view::npos) + return it->value().size() - forStr.size(); + return pos; + }()); + + return *boost::beast::http::token_list( + boost::string_view(found, pos)).begin(); + } + + it = request.find("X-Forwarded-For"); + if (it != request.end()) + { + return *boost::beast::http::token_list(it->value()).begin(); } return {}; diff --git a/src/test/rpc/Roles_test.cpp b/src/test/rpc/Roles_test.cpp index 012bec328da..b76b951e1aa 100644 --- a/src/test/rpc/Roles_test.cpp +++ b/src/test/rpc/Roles_test.cpp @@ -82,6 +82,11 @@ class Roles_test : public beast::unit_test::suite rpcRes = env.rpc(headers, "ping")["result"]; BEAST_EXPECT(rpcRes["ip"] == "55.66.77.88"); + headers["Forwarded"] = "what=where;for=55.66.77.88, 99.00.11.22;" + "who=3"; + rpcRes = env.rpc(headers, "ping")["result"]; + BEAST_EXPECT(rpcRes["ip"] == "55.66.77.88"); + wsRes = makeWSClient( env.app().config(), true, 2, headers)->invoke("ping")["result"]; BEAST_EXPECT(