{"record":{"id":"481e7b0501586efd","repo":"dotnet/wpf","slug":"sr-duplicateobjectid","errorCode":null,"errorMessage":"SR.DuplicateObjectId","messagePattern":"SR\\.DuplicateObjectId","errorType":"exception","errorClass":"XmlException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CustomSignedXml.cs","lineNumber":80,"sourceCode":"        /// Locate and return the node identified by idValue\n        /// </summary>\n        /// <param name=\"signature\"></param>\n        /// <param name=\"idValue\"></param>\n        /// <returns>node if found - else null</returns>\n        /// <remarks>Tries to match each object in the Object list.</remarks>\n        private static XmlElement SelectNodeByIdFromObjects(Signature signature, string idValue)\n        {\n            XmlElement node = null;\n\n            // enumerate the objects\n            foreach (DataObject dataObject in signature.ObjectList)\n            {\n                // direct reference to Object id - supported for all reference typs\n                if (string.Equals(idValue, dataObject.Id, StringComparison.Ordinal))\n                {\n                    // anticipate duplicate ID's and throw if any found\n                    if (node != null)\n                        throw new XmlException(SR.DuplicateObjectId);\n\n                    node = dataObject.GetXml();\n                }\n            }\n\n            // now search for XAdES specific references\n            if (node == null)\n            {\n                // For XAdES we implement special case where the reference may\n                // be to an internal tag with matching \"Id\" attribute.\n                node = SelectSubObjectNodeForXAdES(signature, idValue);\n            }\n\n            return node;\n        }\n\n        /// <summary>\n        /// Locate any signed Object tag that matches the XAdES \"target type\"","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CustomSignedXml.cs#L62-L98","documentation":"CustomSignedXml.SelectNodeByIdFromEnemies/FromObjects resolves a reference ID by scanning SignedXml Object elements. If two Objects carry the same Id matching the requested value, the document is ambiguous and an XmlException (SR.DuplicateObjectId) is thrown rather than silently picking one.","triggerScenarios":"Calling GetIdElement on a CustomSignedXml whose signature contains two or more <Object Id=\"same-id\"> elements, typically during signature verification of a crafted or badly generated signature.","commonSituations":"XML signatures produced by buggy generators that reuse Object IDs; maliciously crafted signatures attempting reference ambiguity (signature wrapping); manual merging of signature documents.","solutions":["Fix the signature generator so each <Object> has a unique Id.","Remove or rename duplicate Object elements before verification.","Catch XmlException during verification and reject the signature as invalid.","Validate signature XML for duplicate IDs with an XML schema/ID uniqueness check before processing."],"exampleFix":"// before: verifying a signature that may contain duplicate Object Ids\nbool ok = signedXml.CheckSignature();\n// after\ntry { bool ok = signedXml.CheckSignature(); }\ncatch (XmlException)\n{ rejectSignature(\"Duplicate Object Id in signature\"); }","handlingStrategy":"validation","validationCode":"// pre-check uniqueness of Object Ids in the signature XML before verification\nvar ids = sigDoc.SelectNodes(\"//*[local-name()='Object' and @Id]\")\n                .Cast<XmlNode>().Select(n => n.Attributes[\"Id\"].Value);\nif (ids.GroupBy(x => x, StringComparer.Ordinal).Any(g => g.Count() > 1))\n    throw new InvalidDataException(\"Signature contains duplicate Object Ids\");","typeGuard":"bool HasUniqueObjectIds(XmlDocument doc) =>\n    doc.SelectNodes(\"//*[local-name()='Object' and @Id]\")\n       .Cast<XmlNode>().Select(n => n.Attributes[\"Id\"].Value)\n       .GroupBy(x => x, StringComparer.Ordinal).All(g => g.Count() == 1);","tryCatchPattern":"try { bool ok = customSignedXml.CheckSignature(); }\ncatch (XmlException e) { RejectSignature($\"Malformed or ambiguous signature: {e.Message}\"); }","preventionTips":["Ensure signature generators assign unique Object Ids","Validate ID uniqueness before verification (defends against signature-wrapping tricks)","Treat duplicate-ID signatures as invalid, never resolve them heuristically"],"tags":["wpf","xml-signature","signedxml","duplicate-id","security"],"backgroundTag":"schema-validation-failed","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}