You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
There is a type confusion in libxmljs when parsing a specially crafted XML while invoking the namespaces() function (which invokes _wrap__xmlNode_nsDef_get()) on a grand-child of a node that refers to an entity. This vulnerability can lead to denial of service and remote code execution.
Details
A type confusion exists in the SWIG generated function _wrap__xmlNode_nsDef_get():
This function is being called from namespaces() function if onlyLocal parameter is set to true:
/** * Get an array of namespaces that appy to the current node * * @param onlyLocal whether to include inherited namespaces * @returns {XMLNamespace[]} an array of namespaces for the current node */publicnamespaces(onlyLocal: boolean=false){constnamespaces: XMLNamespace[]=[];const_ref=this.getNativeReference();if(onlyLocal===true){letnamespace=_ref.nsDef;while(namespace!==null){namespaces.push(createXMLReferenceOrThrow(XMLNamespace,namespace,XMLNodeError.NO_REF));namespace=namespace.next;}}else{xmlGetNsList(_ref.doc,_ref).forEach((namespace)=>{namespaces.push(createXMLReferenceOrThrow(XMLNamespace,namespace,XMLNodeError.NO_REF));});}returnnamespaces;}
In 32-bit system, the field “nsDef” of xmlNode has the same offset as the field “etype” of xmlEntity, which is a number between 1 to 6.
But in a 64-bit system, the field “nsDef” of xmlNode has the same offset as the field “ExternalID” of xmlEntity.
The entity syntax is defined as:
<!ENTITY [%] name [SYSTEM|PUBLIC publicID] resource [NDATA notation] >
Passing a PUBLIC clause with publicID will eventually cause nsDef to point to the publicID string.
Next, createWrapNs() will be called with ns points to the publicID string:
Causing that ns->_private is controllable (as long as it is a printable string). Which makes the handle pointer controllable by an attacker which can later execute code when one of the functions of the namespace are being called.
Summary
There is a type confusion in libxmljs when parsing a specially crafted XML while invoking the namespaces() function (which invokes _wrap__xmlNode_nsDef_get()) on a grand-child of a node that refers to an entity. This vulnerability can lead to denial of service and remote code execution.
Details
A type confusion exists in the SWIG generated function _wrap__xmlNode_nsDef_get():
This function is being called from namespaces() function if onlyLocal parameter is set to true:
In 32-bit system, the field “nsDef” of xmlNode has the same offset as the field “etype” of xmlEntity, which is a number between 1 to 6.
But in a 64-bit system, the field “nsDef” of xmlNode has the same offset as the field “ExternalID” of xmlEntity.
The entity syntax is defined as:
Passing a PUBLIC clause with publicID will eventually cause nsDef to point to the publicID string.
Next, createWrapNs() will be called with ns points to the publicID string:
Causing that ns->_private is controllable (as long as it is a printable string). Which makes the handle pointer controllable by an attacker which can later execute code when one of the functions of the namespace are being called.
PoC
Write the following into DoS.js:
Run it with the following command:
Impact
This vulnerability leads to an RCE, data leak and DoS on 64-bit systems, and DoS on 32-bit systems.
Fix suggestion
_wrap__xmlNode_nsDef_get() should verify that arg10 is an xmlNode.
The text was updated successfully, but these errors were encountered: