Low severity3.1NVD Advisory· Published Sep 15, 2025· Updated Apr 15, 2026
CVE-2025-59398
CVE-2025-59398
Description
The OCPP implementation in libocpp before 0.26.2 allows a denial of service (EVerest crash) via JSON input larger than 255 characters, because a CiString<255> object is created with StringTooLarge set to Throw.
Affected products
1Patches
4253432ae7458Update to libocpp v0.26.2
1 file changed · +1 −1
dependencies.yaml+1 −1 modified@@ -68,7 +68,7 @@ libevse-security: # OCPP libocpp: git: https://github.com/EVerest/libocpp.git - git_tag: fb391b4ff16a0a07150e5a8eebf0856fb6623cbe + git_tag: v0.26.2 cmake_condition: "EVEREST_DEPENDENCY_ENABLED_LIBOCPP" # Josev Josev:
ec4949cc8d28refactor(ocpp16): Remove the call to stop during a reset (#1057)
3 files changed · +5 −4
config/v16/config-full.json+1 −1 modified@@ -83,7 +83,7 @@ "MeterValuesSampledData": "Energy.Active.Import.Register", "MeterValuesSampledDataMaxLength": 1024, "MeterValueSampleInterval": 300, - "MinimumStatusDuration": 2, + "MinimumStatusDuration": 1, "NumberOfConnectors": 2, "ResetRetries": 1, "StopTransactionOnEVSideDisconnect": true,
doc/v16/getting_started.md+1 −1 modified@@ -197,7 +197,7 @@ Some general notes: the "connector" parameter of some of the callbacks refers to - register_reset_callback - used to perform a reset of the requested type + used to perform a reset of the requested type, it is up to the user to properly stop the charge point when this callback is used - register_connection_state_changed_callback
lib/ocpp/v16/charge_point_impl.cpp+3 −2 modified@@ -2229,14 +2229,15 @@ void ChargePointImpl::handleResetRequest(ocpp::Call<ResetRequest> call) { lk, std::chrono::seconds(this->configuration->getWaitForStopTransactionsOnResetTimeout()), [this] { for (int32_t connector = 1; connector <= this->configuration->getNumberOfConnectors(); connector++) { - if (this->transaction_handler->transaction_active(connector)) { + if (this->transaction_handler->transaction_active(connector) or + this->status->get_state(connector) == ChargePointStatus::Charging) { return false; } } return true; }); // this is executed after all transactions have been stopped - this->stop(); + // it is expected that the user properly shuts down the software, including calling stop() this->reset_callback(reset_type); }); if (call.msg.type == ResetType::Soft) {
253432ae7458Update to libocpp v0.26.2
1 file changed · +1 −1
dependencies.yaml+1 −1 modified@@ -68,7 +68,7 @@ libevse-security: # OCPP libocpp: git: https://github.com/EVerest/libocpp.git - git_tag: fb391b4ff16a0a07150e5a8eebf0856fb6623cbe + git_tag: v0.26.2 cmake_condition: "EVEREST_DEPENDENCY_ENABLED_LIBOCPP" # Josev Josev:
fb391b4ff16aFix handling and reporting of more invalid messages (#1052)
3 files changed · +35 −1
CMakeLists.txt+1 −1 modified@@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.14) project(ocpp - VERSION 0.26.1 + VERSION 0.26.2 DESCRIPTION "A C++ implementation of the Open Charge Point Protocol" LANGUAGES CXX )
include/ocpp/common/message_queue.hpp+7 −0 modified@@ -90,6 +90,10 @@ enum class MessageTransmissionPriority { Discard // message shall be discarded and not be sent }; +class MalformedRpcMessage : public std::runtime_error { + using std::runtime_error::runtime_error; +}; + /// \brief Helper function to handle messages that shall be send inline MessageTransmissionPriority get_message_transmission_priority(bool is_boot_notification_message, bool triggered, bool registration_already_accepted, @@ -208,6 +212,9 @@ template <typename M> class MessageQueue { start_transaction_message_retry_callback; MessageId getMessageId(const json::array_t& json_message) { + if (json_message.size() < 2) { + throw MalformedRpcMessage("Message has too few elements, could not get message id."); + } return MessageId(json_message.at(MESSAGE_ID).get<std::string>()); } MessageTypeId getMessageTypeId(const json::array_t& json_message) {
lib/ocpp/v2/charge_point.cpp+27 −0 modified@@ -863,6 +863,26 @@ void ChargePoint::message_callback(const std::string& message) { CiString<255>(message, StringTooLarge::Truncate), true, utils::is_critical(security_event)); return; + } catch (const MalformedRpcMessage& e) { + EVLOG_error << "MalformedRpcMessage exception during handling of message: " << e.what(); + auto call_error = CallError(MessageId("-1"), "RpcFrameworkError", e.what(), json({})); + this->message_dispatcher->dispatch_call_error(call_error); + const auto& security_event = ocpp::security_events::INVALIDMESSAGES; + this->security->security_event_notification_req(CiString<50>(security_event, StringTooLarge::Truncate), + CiString<255>(message, StringTooLarge::Truncate), true, + utils::is_critical(security_event)); + return; + } + + if (enhanced_message.messageTypeId == MessageTypeId::UNKNOWN) { + EVLOG_error << "Cannot handle message with an unknown message type"; + auto call_error = CallError(MessageId("-1"), "MessageTypeNotSupported", "", json({})); + this->message_dispatcher->dispatch_call_error(call_error); + const auto& security_event = ocpp::security_events::INVALIDMESSAGES; + this->security->security_event_notification_req(CiString<50>(security_event, StringTooLarge::Truncate), + CiString<255>(message, StringTooLarge::Truncate), true, + utils::is_critical(security_event)); + return; } enhanced_message.message_size = message.size(); @@ -946,6 +966,13 @@ void ChargePoint::message_callback(const std::string& message) { } auto call_error = CallError(enhanced_message.uniqueId, "OccurrenceConstraintViolation", e.what(), json({})); this->message_dispatcher->dispatch_call_error(call_error); + } catch (const StringConversionException& e) { + EVLOG_error << "StringConversionException during handling of message: " << e.what(); + if (enhanced_message.messageTypeId != MessageTypeId::CALL) { + return; // CALLERROR shall only follow on a CALL message + } + auto call_error = CallError(enhanced_message.uniqueId, "FormationViolation", e.what(), json({})); + this->message_dispatcher->dispatch_call_error(call_error); } catch (const EnumConversionException& e) { EVLOG_error << "EnumConversionException during handling of message: " << e.what(); if (enhanced_message.messageTypeId != MessageTypeId::CALL) {
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5News mentions
0No linked articles in our index yet.