mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Improve handling of malformed JSON-RPC requests
This commit is contained in:
@@ -567,7 +567,7 @@ ServerHandlerImp::processRequest (Port const& port,
|
||||
if ((request.size () > RPC::Tuning::maxRequestSize) ||
|
||||
! reader.parse (request, jsonOrig) ||
|
||||
! jsonOrig ||
|
||||
! (jsonOrig.isObject () || jsonOrig.isArray()))
|
||||
! jsonOrig.isObject ())
|
||||
{
|
||||
HTTPReply (400, "Unable to parse request: " +
|
||||
reader.getFormatedErrorMessages(), output, rpcJ);
|
||||
@@ -576,27 +576,41 @@ ServerHandlerImp::processRequest (Port const& port,
|
||||
}
|
||||
|
||||
bool batch = false;
|
||||
unsigned size = 1;
|
||||
if (jsonOrig.isMember(jss::method) && jsonOrig[jss::method] == "batch")
|
||||
{
|
||||
batch = true;
|
||||
auto size = batch ? jsonOrig[jss::params].size() : 1;
|
||||
if(!jsonOrig.isMember(jss::params) || !jsonOrig[jss::params].isArray())
|
||||
{
|
||||
HTTPReply (400, "Malformed batch request", output, rpcJ);
|
||||
return;
|
||||
}
|
||||
size = jsonOrig[jss::params].size();
|
||||
}
|
||||
|
||||
Json::Value reply(batch ? Json::arrayValue : Json::objectValue);
|
||||
auto const start (std::chrono::high_resolution_clock::now ());
|
||||
for (unsigned i = 0; i < size; ++i)
|
||||
{
|
||||
Json::Value const& jsonRPC = batch ? jsonOrig[jss::params][i] : jsonOrig;
|
||||
/* ---------------------------------------------------------------------- */
|
||||
// Determine role/usage so we can charge for invalid requests
|
||||
Json::Value const& method = jsonRPC [jss::method];
|
||||
|
||||
Json::Value const& jsonRPC =
|
||||
batch ? jsonOrig[jss::params][i] : jsonOrig;
|
||||
/* ------------------------------------------------------------------ */
|
||||
auto role = Role::FORBID;
|
||||
auto required = RPC::roleRequired(method.asString());
|
||||
auto required = Role::FORBID;
|
||||
if (jsonRPC.isMember(jss::method) && jsonRPC[jss::method].isString())
|
||||
required = RPC::roleRequired(jsonRPC[jss::method].asString());
|
||||
|
||||
if (jsonRPC.isMember(jss::params) &&
|
||||
jsonRPC[jss::params].isArray() &&
|
||||
jsonRPC[jss::params].size() > 0 &&
|
||||
jsonRPC[jss::params][Json::UInt(0)].isObject())
|
||||
{
|
||||
role = requestRole(required, port, jsonRPC[jss::params][Json::UInt(0)],
|
||||
remoteIPAddress, user);
|
||||
role = requestRole(
|
||||
required,
|
||||
port,
|
||||
jsonRPC[jss::params][Json::UInt(0)],
|
||||
remoteIPAddress,
|
||||
user);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -641,7 +655,7 @@ ServerHandlerImp::processRequest (Port const& port,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (method.isNull())
|
||||
if (!jsonRPC.isMember(jss::method) || jsonRPC[jss::method].isNull())
|
||||
{
|
||||
usage.charge(Resource::feeInvalidRPC);
|
||||
if (!batch)
|
||||
@@ -655,6 +669,7 @@ ServerHandlerImp::processRequest (Port const& port,
|
||||
continue;
|
||||
}
|
||||
|
||||
Json::Value const& method = jsonRPC[jss::method];
|
||||
if (! method.isString ())
|
||||
{
|
||||
usage.charge(Resource::feeInvalidRPC);
|
||||
|
||||
@@ -896,6 +896,56 @@ class ServerStatus_test :
|
||||
BEAST_EXPECT(resp.body == "Unable to parse request: \r\n");
|
||||
}
|
||||
|
||||
{
|
||||
beast::http::response<beast::http::string_body> resp;
|
||||
Json::Value jv;
|
||||
jv["invalid"] = 1;
|
||||
doHTTPRequest(env, yield, false, resp, ec, to_string(jv));
|
||||
BEAST_EXPECT(resp.result() == beast::http::status::bad_request);
|
||||
BEAST_EXPECT(resp.body == "Null method\r\n");
|
||||
}
|
||||
|
||||
{
|
||||
beast::http::response<beast::http::string_body> resp;
|
||||
Json::Value jv(Json::arrayValue);
|
||||
jv.append("invalid");
|
||||
doHTTPRequest(env, yield, false, resp, ec, to_string(jv));
|
||||
BEAST_EXPECT(resp.result() == beast::http::status::bad_request);
|
||||
BEAST_EXPECT(resp.body == "Unable to parse request: \r\n");
|
||||
}
|
||||
|
||||
{
|
||||
beast::http::response<beast::http::string_body> resp;
|
||||
Json::Value jv(Json::arrayValue);
|
||||
Json::Value j;
|
||||
j["invalid"] = 1;
|
||||
jv.append(j);
|
||||
doHTTPRequest(env, yield, false, resp, ec, to_string(jv));
|
||||
BEAST_EXPECT(resp.result() == beast::http::status::bad_request);
|
||||
BEAST_EXPECT(resp.body == "Unable to parse request: \r\n");
|
||||
}
|
||||
|
||||
{
|
||||
beast::http::response<beast::http::string_body> resp;
|
||||
Json::Value jv;
|
||||
jv[jss::method] = "batch";
|
||||
jv[jss::params] = 2;
|
||||
doHTTPRequest(env, yield, false, resp, ec, to_string(jv));
|
||||
BEAST_EXPECT(resp.result() == beast::http::status::bad_request);
|
||||
BEAST_EXPECT(resp.body == "Malformed batch request\r\n");
|
||||
}
|
||||
|
||||
{
|
||||
beast::http::response<beast::http::string_body> resp;
|
||||
Json::Value jv;
|
||||
jv[jss::method] = "batch";
|
||||
jv[jss::params] = Json::objectValue;
|
||||
jv[jss::params]["invalid"] = 3;
|
||||
doHTTPRequest(env, yield, false, resp, ec, to_string(jv));
|
||||
BEAST_EXPECT(resp.result() == beast::http::status::bad_request);
|
||||
BEAST_EXPECT(resp.body == "Malformed batch request\r\n");
|
||||
}
|
||||
|
||||
Json::Value jv;
|
||||
{
|
||||
beast::http::response<beast::http::string_body> resp;
|
||||
|
||||
Reference in New Issue
Block a user