From 977e5a7dbaa19834a9b273bea4fb16687bbe94e7 Mon Sep 17 00:00:00 2001 From: Sergey Kuznetsov Date: Wed, 13 May 2026 17:03:57 +0100 Subject: [PATCH] fix: Check network ID in `transactionSignFor` (#7102) --- include/xrpl/basics/Expected.h | 24 ++++++++++++----- src/xrpld/rpc/detail/TransactionSign.cpp | 33 ++++++++++++++++++++++-- 2 files changed, 49 insertions(+), 8 deletions(-) diff --git a/include/xrpl/basics/Expected.h b/include/xrpl/basics/Expected.h index 74a0e76eef..3796151777 100644 --- a/include/xrpl/basics/Expected.h +++ b/include/xrpl/basics/Expected.h @@ -148,17 +148,23 @@ public: } [[nodiscard]] constexpr E const& - error() const + error() const& { return Base::error(); } - constexpr E& - error() + [[nodiscard]] constexpr E& + error() & { return Base::error(); } + [[nodiscard]] constexpr E&& + error() && + { + return std::move(Base::error()); + } + constexpr explicit operator bool() const { @@ -215,17 +221,23 @@ public: } [[nodiscard]] constexpr E const& - error() const + error() const& { return Base::error(); } - constexpr E& - error() + [[nodiscard]] constexpr E& + error() & { return Base::error(); } + [[nodiscard]] constexpr E&& + error() && + { + return std::move(Base::error()); + } + constexpr explicit operator bool() const { diff --git a/src/xrpld/rpc/detail/TransactionSign.cpp b/src/xrpld/rpc/detail/TransactionSign.cpp index f745bd9e1b..0fdc1bfdc7 100644 --- a/src/xrpld/rpc/detail/TransactionSign.cpp +++ b/src/xrpld/rpc/detail/TransactionSign.cpp @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -54,6 +55,7 @@ #include #include +#include #include #include #include @@ -405,6 +407,25 @@ checkTxJsonFields( return ret; } +static Expected +checkNetworkID(json::Value const& txJson, uint32_t appNetworkId) +{ + if (appNetworkId > 1024) + { + if (!txJson.isMember(jss::NetworkID)) + { + return Unexpected( + RPC::makeError(RpcInvalidParams, RPC::missingFieldMessage("tx_json.NetworkID"))); + } + if (!txJson[jss::NetworkID].isIntegral() || txJson[jss::NetworkID].asUInt() != appNetworkId) + { + return Unexpected( + RPC::makeError(RpcInvalidParams, RPC::invalidFieldMessage("tx_json.NetworkID"))); + } + } + return Expected(); +} + //------------------------------------------------------------------------------ // A move-only struct that makes it easy to return either a json::Value or a @@ -1165,8 +1186,16 @@ transactionSignFor( if (!txJson.isObject()) return RPC::objectFieldError(jss::tx_json); - // If the tx_json.SigningPubKey field is missing, - // insert an empty one. + if (auto checkResult = + detail::checkNetworkID(txJson, app.getNetworkIDService().getNetworkID()); + !checkResult) + { + return std::move(checkResult).error(); + } + + // If the tx_json.SigningPubKey field is missing, insert an empty one, + // in order for the `checkMultiSignFields` to not return an error + // for non-multisign transactions. if (!txJson.isMember(sfSigningPubKey.getJsonName())) txJson[sfSigningPubKey.getJsonName()] = ""; }