rpc: add a sanity limit to a few RPC in restricted mode
This commit is contained in:
parent
77a008f714
commit
4d3c2d0b7b
|
@ -68,6 +68,11 @@ using namespace epee;
|
|||
#define DEFAULT_PAYMENT_DIFFICULTY 1000
|
||||
#define DEFAULT_PAYMENT_CREDITS_PER_HASH 100
|
||||
|
||||
#define RESTRICTED_BLOCK_HEADER_RANGE 1000
|
||||
#define RESTRICTED_TRANSACTIONS_COUNT 100
|
||||
#define RESTRICTED_SPENT_KEY_IMAGES_COUNT 5000
|
||||
#define RESTRICTED_BLOCK_COUNT 1000
|
||||
|
||||
#define RPC_TRACKER(rpc) \
|
||||
PERF_TIMER(rpc); \
|
||||
RPCTracker tracker(#rpc, PERF_TIMER_NAME(rpc))
|
||||
|
@ -639,6 +644,13 @@ namespace cryptonote
|
|||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_BLOCKS_BY_HEIGHT>(invoke_http_mode::BIN, "/getblocks_by_height.bin", req, res, r))
|
||||
return r;
|
||||
|
||||
const bool restricted = m_restricted && ctx;
|
||||
if (restricted && req.heights.size() > RESTRICTED_BLOCK_COUNT)
|
||||
{
|
||||
res.status = "Too many blocks requested in restricted mode";
|
||||
return true;
|
||||
}
|
||||
|
||||
res.status = "Failed";
|
||||
res.blocks.clear();
|
||||
res.blocks.reserve(req.heights.size());
|
||||
|
@ -793,11 +805,17 @@ namespace cryptonote
|
|||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_TRANSACTIONS>(invoke_http_mode::JON, "/gettransactions", req, res, ok))
|
||||
return ok;
|
||||
|
||||
CHECK_PAYMENT_MIN1(req, res, req.txs_hashes.size() * COST_PER_TX, false);
|
||||
|
||||
const bool restricted = m_restricted && ctx;
|
||||
const bool request_has_rpc_origin = ctx != NULL;
|
||||
|
||||
if (restricted && req.txs_hashes.size() > RESTRICTED_TRANSACTIONS_COUNT)
|
||||
{
|
||||
res.status = "Too many transactions requested in restricted mode";
|
||||
return true;
|
||||
}
|
||||
|
||||
CHECK_PAYMENT_MIN1(req, res, req.txs_hashes.size() * COST_PER_TX, false);
|
||||
|
||||
std::vector<crypto::hash> vh;
|
||||
for(const auto& tx_hex_str: req.txs_hashes)
|
||||
{
|
||||
|
@ -1027,11 +1045,17 @@ namespace cryptonote
|
|||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_IS_KEY_IMAGE_SPENT>(invoke_http_mode::JON, "/is_key_image_spent", req, res, ok))
|
||||
return ok;
|
||||
|
||||
CHECK_PAYMENT_MIN1(req, res, req.key_images.size() * COST_PER_KEY_IMAGE, false);
|
||||
|
||||
const bool restricted = m_restricted && ctx;
|
||||
const bool request_has_rpc_origin = ctx != NULL;
|
||||
|
||||
if (restricted && req.key_images.size() > RESTRICTED_SPENT_KEY_IMAGES_COUNT)
|
||||
{
|
||||
res.status = "Too many key images queried in restricted mode";
|
||||
return true;
|
||||
}
|
||||
|
||||
CHECK_PAYMENT_MIN1(req, res, req.key_images.size() * COST_PER_KEY_IMAGE, false);
|
||||
|
||||
std::vector<crypto::key_image> key_images;
|
||||
for(const auto& ki_hex_str: req.key_images)
|
||||
{
|
||||
|
@ -2034,6 +2058,14 @@ namespace cryptonote
|
|||
|
||||
CHECK_PAYMENT_MIN1(req, res, COST_PER_BLOCK_HEADER, false);
|
||||
|
||||
const bool restricted = m_restricted && ctx;
|
||||
if (restricted && req.hashes.size() > RESTRICTED_BLOCK_COUNT)
|
||||
{
|
||||
error_resp.code = CORE_RPC_ERROR_CODE_RESTRICTED;
|
||||
error_resp.message = "Too many block headers requested in restricted mode";
|
||||
return false;
|
||||
}
|
||||
|
||||
auto get = [this](const std::string &hash, bool fill_pow_hash, block_header_response &block_header, bool restricted, epee::json_rpc::error& error_resp) -> bool {
|
||||
crypto::hash block_hash;
|
||||
bool hash_parsed = parse_hash256(hash, block_hash);
|
||||
|
@ -2069,7 +2101,6 @@ namespace cryptonote
|
|||
return true;
|
||||
};
|
||||
|
||||
const bool restricted = m_restricted && ctx;
|
||||
if (!req.hash.empty())
|
||||
{
|
||||
if (!get(req.hash, req.fill_pow_hash, res.block_header, restricted, error_resp))
|
||||
|
@ -2101,6 +2132,14 @@ namespace cryptonote
|
|||
error_resp.message = "Invalid start/end heights.";
|
||||
return false;
|
||||
}
|
||||
const bool restricted = m_restricted && ctx;
|
||||
if (restricted && req.end_height - req.start_height > RESTRICTED_BLOCK_HEADER_RANGE)
|
||||
{
|
||||
error_resp.code = CORE_RPC_ERROR_CODE_RESTRICTED;
|
||||
error_resp.message = "Too many block headers requested.";
|
||||
return false;
|
||||
}
|
||||
|
||||
CHECK_PAYMENT_MIN1(req, res, (req.end_height - req.start_height + 1) * COST_PER_BLOCK_HEADER, false);
|
||||
for (uint64_t h = req.start_height; h <= req.end_height; ++h)
|
||||
{
|
||||
|
@ -2127,7 +2166,6 @@ namespace cryptonote
|
|||
return false;
|
||||
}
|
||||
res.headers.push_back(block_header_response());
|
||||
const bool restricted = m_restricted && ctx;
|
||||
bool response_filled = fill_block_header_response(blk, false, block_height, block_hash, res.headers.back(), req.fill_pow_hash && !restricted);
|
||||
if (!response_filled)
|
||||
{
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#define CORE_RPC_ERROR_CODE_PAYMENT_TOO_LOW -16
|
||||
#define CORE_RPC_ERROR_CODE_DUPLICATE_PAYMENT -17
|
||||
#define CORE_RPC_ERROR_CODE_STALE_PAYMENT -18
|
||||
#define CORE_RPC_ERROR_CODE_RESTRICTED -19
|
||||
|
||||
static inline const char *get_rpc_server_error_message(int64_t code)
|
||||
{
|
||||
|
@ -70,6 +71,7 @@ static inline const char *get_rpc_server_error_message(int64_t code)
|
|||
case CORE_RPC_ERROR_CODE_PAYMENT_TOO_LOW: return "Payment too low";
|
||||
case CORE_RPC_ERROR_CODE_DUPLICATE_PAYMENT: return "Duplicate payment";
|
||||
case CORE_RPC_ERROR_CODE_STALE_PAYMENT: return "Stale payment";
|
||||
case CORE_RPC_ERROR_CODE_RESTRICTED: return "Parameters beyond restricted allowance";
|
||||
default: MERROR("Unknown error: " << code); return "Unknown error";
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue