Skip to content

Commit

Permalink
fix: not forward admin API (#1629)
Browse files Browse the repository at this point in the history
To merge to 2.2.3 branch.
It is different from the #1628 . I think this branch still forward
feature API to rippled.
  • Loading branch information
cindyyan317 authored Sep 6, 2024
1 parent 9fe9e7c commit 0054e4b
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 1 deletion.
8 changes: 7 additions & 1 deletion src/rpc/RPCEngine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "data/BackendInterface.hpp"
#include "rpc/Counters.hpp"
#include "rpc/Errors.hpp"
#include "rpc/RPCHelpers.hpp"
#include "rpc/WorkQueue.hpp"
#include "rpc/common/HandlerProvider.hpp"
#include "rpc/common/Types.hpp"
Expand Down Expand Up @@ -134,8 +135,13 @@ class RPCEngine {
Result
buildResponse(web::Context const& ctx)
{
if (forwardingProxy_.shouldForward(ctx))
if (forwardingProxy_.shouldForward(ctx)) {
// Disallow forwarding of the admin api, only user api is allowed for security reasons.
if (isAdminCmd(ctx.method, ctx.params))
return Result{Status{RippledError::rpcNO_PERMISSION}};

return forwardingProxy_.forward(ctx);
}

if (backend_->isTooBusy()) {
LOG(log_.error()) << "Database is too busy. Rejecting request";
Expand Down
17 changes: 17 additions & 0 deletions src/rpc/RPCHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1273,6 +1273,23 @@ specifiesCurrentOrClosedLedger(boost::json::object const& request)
return false;
}

bool
isAdminCmd(std::string const& method, boost::json::object const& request)
{
auto const isFieldSet = [&request](auto const field) {
return request.contains(field) and request.at(field).is_bool() and request.at(field).as_bool();
};

if (method == JS(ledger)) {
if (isFieldSet(JS(full)) or isFieldSet(JS(accounts)) or isFieldSet(JS(type)))
return true;
}

if (method == JS(feature) and request.contains(JS(vetoed)))
return true;
return false;
}

std::variant<ripple::uint256, Status>
getNFTID(boost::json::object const& request)
{
Expand Down
10 changes: 10 additions & 0 deletions src/rpc/RPCHelpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,16 @@ parseIssue(boost::json::object const& issue);
bool
specifiesCurrentOrClosedLedger(boost::json::object const& request);

/**
* @brief Check whether a request requires administrative privileges on rippled side.
*
* @param method The method name to check
* @param request The request to check
* @return true if the request requires ADMIN role
*/
bool
isAdminCmd(std::string const& method, boost::json::object const& request);

/**
* @brief Get the NFTID from the request
*
Expand Down
39 changes: 39 additions & 0 deletions tests/unit/rpc/RPCHelpersTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "rpc/common/Types.hpp"
#include "util/Fixtures.hpp"
#include "util/MockPrometheus.hpp"
#include "util/NameGenerator.hpp"
#include "util/TestObject.hpp"

#include <boost/asio/impl/spawn.hpp>
Expand Down Expand Up @@ -538,3 +539,41 @@ TEST_F(RPCHelpersTest, ParseIssue)
std::runtime_error
);
}

struct IsAdminCmdParamTestCaseBundle {
std::string testName;
std::string method;
std::string testJson;
bool expected;
};

struct IsAdminCmdParameterTest : public TestWithParam<IsAdminCmdParamTestCaseBundle> {};

static auto
generateTestValuesForParametersTest()
{
return std::vector<IsAdminCmdParamTestCaseBundle>{
{"featureVetoedTrue", "feature", R"({"vetoed": true, "feature": "foo"})", true},
{"featureVetoedFalse", "feature", R"({"vetoed": false, "feature": "foo"})", true},
{"ledgerFullTrue", "ledger", R"({"full": true})", true},
{"ledgerAccountsTrue", "ledger", R"({"accounts": true})", true},
{"ledgerTypeTrue", "ledger", R"({"type": true})", true},
{"ledgerFullFalse", "ledger", R"({"full": false})", false},
{"ledgerAccountsFalse", "ledger", R"({"accounts": false})", false},
{"ledgerTypeFalse", "ledger", R"({"type": false})", false},
{"ledgerEntry", "ledger_entry", R"({"type": false})", false}
};
}

INSTANTIATE_TEST_CASE_P(
IsAdminCmdTest,
IsAdminCmdParameterTest,
ValuesIn(generateTestValuesForParametersTest()),
tests::util::NameGenerator
);

TEST_P(IsAdminCmdParameterTest, Test)
{
auto const testBundle = GetParam();
EXPECT_EQ(isAdminCmd(testBundle.method, boost::json::parse(testBundle.testJson).as_object()), testBundle.expected);
}

0 comments on commit 0054e4b

Please sign in to comment.