जमा करें #857012: open62541 Project open62541 master (commit ca356b088ada7dee824d1b4acd07c1ff07ce242b) Heap-based Buffer Overflow (Out-of-Bounds Read)जानकारी

शीर्षकopen62541 Project open62541 master (commit ca356b088ada7dee824d1b4acd07c1ff07ce242b) Heap-based Buffer Overflow (Out-of-Bounds Read)
विवरणopen62541 contains a client-side heap-buffer-overflow in the high-level attribute reading path when processing a malicious ReadResponse for the NodeClass attribute. The issue is reproducible on commit ca356b088ada7dee824d1b4acd07c1ff07ce242b. A malicious or compromised OPC UA server can complete a real OPC UA TCP interaction with the victim client and then return a syntactically valid but semantically inconsistent DataValue for NodeClass. Instead of returning a Variant whose type matches NodeClass, the server returns a scalar Boolean payload. The client successfully decodes that response, but the high-level helper __Client_readAttribute() contains a special-case branch for UA_ATTRIBUTEID_NODECLASS that copies sizeof(UA_NodeClass) bytes from res->value.data without enforcing the same type and scalar checks that are applied to other attributes. As a result, the client reads 4 bytes from an object that was decoded as a 1-byte Boolean value, causing an out-of-bounds heap read and a reliable AddressSanitizer crash. The vulnerability is client-side and remotely reachable by an untrusted OPC UA server. It is not a parser-only issue and does not require direct invocation of internal decode helpers. The reproduced path is a real network service chain: the victim client opens a TCP connection, negotiates a SecureChannel, validates the endpoint, selects the endpoint, and then invokes UA_Client_readNodeClassAttribute(). In the benign baseline mode, the custom test server returns a correct NodeClass value and the client prints "readNodeClass=Good value=1" before closing the channel normally. In the malicious mode, the server still completes the same interaction and answers the Read request, but the response payload for NodeClass is encoded as a Boolean. The client then crashes inside the shared open62541 client library with AddressSanitizer reporting a heap-buffer-overflow read in src/client/ua_client_highlevel.c:850. The affected logic resides in the high-level attribute reader. The relevant entry point is UA_Client_readNodeClassAttribute(), which calls __Client_readAttribute() with attributeId set to UA_ATTRIBUTEID_NODECLASS and outDataType set to the expected NodeClass type. For most non-Value attributes, __Client_readAttribute() performs defensive validation before copying the decoded Variant into the caller-provided output buffer. In particular, it checks whether the returned Variant is scalar and whether res->value.type matches the expected outDataType. However, NodeClass is handled differently. There is a dedicated branch that executes memcpy(out, (UA_NodeClass*)res->value.data, sizeof(UA_NodeClass)) directly. That branch does not verify that the Variant is scalar and does not verify that the runtime type of the decoded Variant equals UA_TYPES[UA_TYPES_NODECLASS]. This type confusion is the root cause. The dynamic evidence matches the source-level analysis. The client-side crash log shows a real heap-buffer-overflow with "READ of size 4" at __Client_readAttribute in src/client/ua_client_highlevel.c:850, reached from UA_Client_readNodeClassAttribute() and then from the minimal trigger client. The allocation trace points back to ctxCalloc(), Variant_decodeBinary(), DataValue_decodeBinary(), UA_decodeBinaryInternal(), processMSGResponse(), processServiceResponse(), and UA_Client_Service_read(), which proves that the out-of-bounds source object was allocated by the library while decoding the malicious network response. The lower-level inspection output and GDB observations further confirm that the response is decoded successfully before the crash. In the dedicated inspection client, the Read service returns serviceResult=Good, resultsSize=1, status=Good, hasValue=1, hasStatus=0, arrayLength=0, type=Boolean, memSize=1, and dataBytes=00. GDB on the same path shows response.results[0].value.type->typeName = "Boolean", response.results[0].value.type->memSize = 1, response.results[0].value.data = 0x6020000001d0, and sizeof(UA_NodeClass) = 4. Those values establish the precise mismatch that causes the memory violation: the payload has been decoded as a legal scalar Boolean object of size 1, while the high-level NodeClass branch forcefully reads 4 bytes from that allocation. The decoder does not fail; the bug occurs afterwards, when the library trusts the semantic meaning of the requested attribute instead of the actual runtime type of the returned Variant. The custom malicious server output also supports the reachability argument. In the good mode, the server accepts HEL, OPN, and MSG requests and replies normally, after which the client receives a valid NodeClass and exits cleanly. In the malicious mode, the server accepts the same message flow, receives a final MSG with requestId=4 and type=631 for the Read service exchange, and then sends a shorter response carrying the malformed NodeClass payload. The client proceeds through the same connection and endpoint selection sequence and only fails when the high-level attribute helper processes the decoded result. From a security perspective, the primary impact is remote denial of service against applications embedding the open62541 client and using high-level attribute readers against an untrusted server. A malicious OPC UA server can crash the client process reliably when the application reads NodeClass via UA_Client_readNodeClassAttribute(). Because the demonstrated primitive is an out-of-bounds read rather than an out-of-bounds write, the currently proven impact is process termination and loss of availability, not demonstrated code execution. Even so, this is security-relevant in industrial environments. OPC UA clients are often embedded into monitoring tools, gateways, engineering stations, and diagnostic utilities. If such a component connects to a malicious or impersonated endpoint, the flaw allows a remote attacker to terminate the client or disrupt upstream operational workflows by making a standards-looking Read request return a type-confused DataValue. This issue should qualify for a CVE because it is a concrete memory-safety flaw in a widely used open-source OPC UA implementation, it is remotely triggerable across a real protocol session, and it affects the library’s shared client code rather than only an example program. The fact that the proof of concept uses a small custom trigger client does not reduce the validity of the issue. The trigger client merely exercises the public API UA_Client_readNodeClassAttribute(). The official stock examples do not currently contain a ready-made binary that invokes this exact API, but any third-party program using the same public high-level function inherits the vulnerable behavior. A reliable reproduction setup was established with two builds. The library was first built with sanitizers enabled using a Debug configuration, clang/clang++, UA_NAMESPACE_ZERO=FULL, UA_BUILD_EXAMPLES=ON, and address/undefined sanitizers in the compile and linker flags. A second driver build was created without sanitizers for linking the custom malicious server against a non-ASan static library. The proof-of-concept binaries were then compiled as separate server, trigger client, and inspection client programs. Running the server in good mode and then launching the trigger client yields the expected successful output, "readNodeClass=Good value=1". Running the same client against the default malicious mode yields an ASan crash with "ERROR: AddressSanitizer: heap-buffer-overflow", "READ of size 4", and a backtrace ending at __Client_readAttribute in src/client/ua_client_highlevel.c:850. Running the inspection client against the malicious mode confirms that the network response was decoded as a Boolean before the crash path is taken. The most direct fix is to remove the unsafe NodeClass special case and apply the same type validation policy that already exists for the generic high-level attribute path. Specifically, the library should reject a NodeClass read result unless the returned Variant is scalar and its runtime type equals the expected NodeClass type. If maintainers want to preserve a dedicated NodeClass branch, that branch must still enforce UA_Variant_isScalar(&res->value), res->value.type != NULL, and res->value.type == outDataType before copying. In summary, this is a real, reproducible, client-side heap-buffer-overflow read in open62541 at commit ca356b088ada7dee824d1b4acd07c1ff07ce242b. The bug is rooted in __Client_readAttribute() treating UA_ATTRIBUTEID_NODECLASS as a trusted special case and copying four bytes from res->value.data without verifying that the server actually returned a scalar NodeClass Variant. A malicious server can instead return a Boolean value, which the client decodes successfully and then over-reads in the high-level helper, producing a deterministic sanitizer crash during a legitimate network session.
स्रोत⚠️ https://github.com/gff-cw/information/issues/11
उपयोगकर्ता
 VULL (UID 98817)
सबमिशन12/06/2026 03:05 PM (2 महीनों पहले)
संयम04/08/2026 10:30 AM (2 months later)
स्थितिस्वीकृत
VulDB प्रविष्टि385786 [o6 open62541 तक 1.5.5 ua_client_highlevel.c UA_Client_readNodeClassAttribute बफ़र ओवरफ़्लो]
अंक20

Do you know our Splunk app?

Download it now for free!