From 2f210d3387fcd1b60fad79475220b020bbeb4a23 Mon Sep 17 00:00:00 2001 From: Nicolas Humblot Date: Wed, 4 Mar 2026 20:24:59 +0100 Subject: [PATCH 1/3] test: #8140 reproduce current behavior --- .../analyzer/AssemblyAnalyzer.java | 2 +- .../analyzer/AssemblyAnalyzerTest.java | 117 ++++++++++++++++++ 2 files changed, 118 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/owasp/dependencycheck/analyzer/AssemblyAnalyzer.java b/core/src/main/java/org/owasp/dependencycheck/analyzer/AssemblyAnalyzer.java index 64408cb2cc0..d18e7512b5c 100644 --- a/core/src/main/java/org/owasp/dependencycheck/analyzer/AssemblyAnalyzer.java +++ b/core/src/main/java/org/owasp/dependencycheck/analyzer/AssemblyAnalyzer.java @@ -194,7 +194,7 @@ public void analyzeDependency(Dependency dependency, Engine engine) throws Analy * @param data the assembly data * @param dependency the dependency to update */ - private void updateDependency(final AssemblyData data, Dependency dependency) { + void updateDependency(final AssemblyData data, Dependency dependency) { final StringBuilder sb = new StringBuilder(); if (!StringUtils.isBlank(data.getFileDescription())) { sb.append(data.getFileDescription()); diff --git a/core/src/test/java/org/owasp/dependencycheck/analyzer/AssemblyAnalyzerTest.java b/core/src/test/java/org/owasp/dependencycheck/analyzer/AssemblyAnalyzerTest.java index 1d5fe726bef..7f8efeaf730 100644 --- a/core/src/test/java/org/owasp/dependencycheck/analyzer/AssemblyAnalyzerTest.java +++ b/core/src/test/java/org/owasp/dependencycheck/analyzer/AssemblyAnalyzerTest.java @@ -17,6 +17,9 @@ */ package org.owasp.dependencycheck.analyzer; +import com.github.packageurl.MalformedPackageURLException; +import com.github.packageurl.PackageURL; +import org.jspecify.annotations.NonNull; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -27,12 +30,15 @@ import org.owasp.dependencycheck.dependency.Dependency; import org.owasp.dependencycheck.dependency.Evidence; import org.owasp.dependencycheck.dependency.EvidenceType; +import org.owasp.dependencycheck.dependency.naming.PurlIdentifier; import org.owasp.dependencycheck.exception.InitializationException; import org.owasp.dependencycheck.utils.Settings; +import org.owasp.dependencycheck.xml.assembly.AssemblyData; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; +import java.util.Set; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -175,6 +181,117 @@ void testWithSettingMono() { } } + @Test + void testAzureIdentity() throws MalformedPackageURLException { + // Given + var data = newAzureIdentityAssemblyData(); + var dependency = newAzureIdentityDependency(); + + var expectedDescription = "Microsoft Azure.Identity Component\n\nThis is the implementation of the Azure SDK " + + "Client Library for Azure Identity"; + var expectedVersionEvidences = expectedAzureIdentityVersionEvidences(); + var expectedVersion = "1.700.22.46903"; + var expectedProductEvidences = expectedAzureIdentityProductEvidences(); + var expectedVendorEvidences = expectedAzureIdentityVendorEvidences(); + var expectedName = "Azure.Identity"; + var expectedIdentifiers = Set.of(new PurlIdentifier(new PackageURL("pkg:generic/Azure.Identity@1.700.22.46903"), + Confidence.MEDIUM)); + var expectedEcosystem = "dotnet"; + + // When + analyzer.updateDependency(data, dependency); + + // Then + assertEquals(expectedDescription, dependency.getDescription()); + assertEquals(expectedVersionEvidences, dependency.getEvidence(EvidenceType.VERSION)); + assertEquals(expectedVersion, dependency.getVersion()); + assertEquals(expectedProductEvidences, dependency.getEvidence(EvidenceType.PRODUCT)); + assertEquals(expectedVendorEvidences, dependency.getEvidence(EvidenceType.VENDOR)); + assertEquals(expectedName, dependency.getName()); + assertEquals(expectedIdentifiers, dependency.getSoftwareIdentifiers()); + assertEquals(expectedEcosystem, dependency.getEcosystem()); + } + + private static @NonNull AssemblyData newAzureIdentityAssemblyData() { + var data = new AssemblyData(); + data.setCompanyName("Microsoft Corporation"); + data.setProductName("Azure .NET SDK"); + data.setProductVersion("1.7.0+3627e3cbc75c628f659d033ed9270c9d02ab9038"); + data.setComments("This is the implementation of the Azure SDK Client Library for Azure Identity"); + data.setFileDescription("Microsoft Azure.Identity Component"); + data.setFileName("/home/jdoe/ScanFolder/Azure.Identity.dll"); + data.setFileVersion("1.700.22.46903"); + data.setInternalName("Azure.Identity.dll"); + data.setOriginalFilename("Azure.Identity.dll"); + data.setFullName("Azure.Identity, Version=1.7.0.0, Culture=neutral, PublicKeyToken=92742159e12e44c8"); + + data.addNamespace("Microsoft.CodeAnalysis"); + data.addNamespace("System.Runtime.CompilerServices"); + data.addNamespace("Azure.Core"); + data.addNamespace("Azure.Core.Pipeline"); + data.addNamespace("Azure.Core.Diagnostics"); + // The following duplication is on purpose, this use case has one + data.addNamespace("Azure.Identitiy"); + data.addNamespace("Azure.Identitiy"); + return data; + } + + private static @NonNull Dependency newAzureIdentityDependency() { + var dependency = new Dependency(); + dependency.setActualFilePath("/home/jdoe/ScanFolder/Azure.Identity.dll"); + dependency.setFilePath("/home/jdoe/ScanFolder/Azure.Identity.dll"); + dependency.setFileName("Azure.Identity.dll"); + dependency.setPackagePath("/home/jdoe/ScanFolder/Azure.Identity.dll"); + dependency.setMd5sum("19f72346b3952c135c121e30235d4064"); + dependency.setSha1sum("1ac0e967367aa7679a89b2eb652a7996870d9043"); + dependency.setSha256sum("666973af908cf82a495530b2ea23074004dead445e1bb46ef75a5e3c879a6321"); + + var nameEvidence = new Evidence("file", "name", "Azure.Identity", Confidence.HIGH); + + dependency.addEvidence(EvidenceType.VENDOR, nameEvidence); + dependency.addEvidence(EvidenceType.PRODUCT, nameEvidence); + + return dependency; + } + + private static @NonNull Set expectedAzureIdentityVersionEvidences() { + var fileVersionEvidence = new Evidence("grokassembly", "FileVersion", "1.700.22.46903", Confidence.HIGH); + var productVersionEvidence = new Evidence("grokassembly", "ProductVersion", "1.7.0+3627e3cbc75c628f659d033ed9270c9d02ab9038", Confidence.HIGHEST); + + return Set.of(fileVersionEvidence, productVersionEvidence); + } + + private static @NonNull Set expectedAzureIdentityProductEvidences() { + var nameEvidence = new Evidence("file", "name", "Azure.Identity", Confidence.HIGH); + var companyNameLowEvidence = new Evidence("grokassembly", "CompanyName", "Microsoft Corporation", Confidence.LOW); + var fileDescriptionHighEvidence = new Evidence("grokassembly", "FileDescription", + "Microsoft Azure.Identity Component", Confidence.HIGH); + var internalNameMediumEvidence = new Evidence("grokassembly", "InternalName", "Azure.Identity.dll", + Confidence.MEDIUM); + var originalFilenameMediumEvidence = new Evidence("grokassembly", "OriginalFilename", "Azure.Identity.dll", + Confidence.MEDIUM); + var productNameHighestEvidence = new Evidence("grokassembly", "ProductName", "Azure .NET SDK", Confidence.HIGHEST); + + return Set.of(nameEvidence, companyNameLowEvidence, fileDescriptionHighEvidence, + internalNameMediumEvidence, originalFilenameMediumEvidence, productNameHighestEvidence); + } + + private static @NonNull Set expectedAzureIdentityVendorEvidences() { + var nameEvidence = new Evidence("file", "name", "Azure.Identity", Confidence.HIGH); + var companyNameHighestEvidence = new Evidence("grokassembly", "CompanyName", "Microsoft Corporation", + Confidence.HIGHEST); + var fileDescriptionLowEvidence = new Evidence("grokassembly", "FileDescription", + "Microsoft Azure.Identity Component", Confidence.LOW); + var internalNameLowEvidence = new Evidence("grokassembly", "InternalName", "Azure.Identity.dll", + Confidence.LOW); + var originalFilenameLowEvidence = new Evidence("grokassembly", "OriginalFilename", "Azure.Identity.dll", + Confidence.LOW); + var productNameMediumEvidence = new Evidence("grokassembly", "ProductName", "Azure .NET SDK", + Confidence.MEDIUM); + return Set.of(nameEvidence, companyNameHighestEvidence, fileDescriptionLowEvidence, + internalNameLowEvidence, originalFilenameLowEvidence, productNameMediumEvidence); + } + @AfterEach @Override public void tearDown() throws Exception { From 1fb840ba7d94cc894f5a4fb92dfa8ed2f384adfd Mon Sep 17 00:00:00 2001 From: Nicolas Humblot Date: Wed, 4 Mar 2026 20:29:17 +0100 Subject: [PATCH 2/3] fix: #8140 fix version resolution Consider the parsed version bringing the most fine-grained information if the smaller one fully corresponds to the longer one and consider ProductVersion has a higher confidence value --- .../analyzer/AssemblyAnalyzer.java | 21 +++++++------------ .../analyzer/AssemblyAnalyzerTest.java | 4 ++-- 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/core/src/main/java/org/owasp/dependencycheck/analyzer/AssemblyAnalyzer.java b/core/src/main/java/org/owasp/dependencycheck/analyzer/AssemblyAnalyzer.java index d18e7512b5c..c99e6a5333e 100644 --- a/core/src/main/java/org/owasp/dependencycheck/analyzer/AssemblyAnalyzer.java +++ b/core/src/main/java/org/owasp/dependencycheck/analyzer/AssemblyAnalyzer.java @@ -253,30 +253,23 @@ void updateDependency(final AssemblyData data, Dependency dependency) { } } if (dependency.getVersion() == null) { - if (data.getFileVersion() != null && data.getProductVersion() != null - && data.getFileVersion().length() >= data.getProductVersion().length()) { - if (fileVersion != null && fileVersion.toString().length() == data.getFileVersion().length()) { + if (fileVersion != null && productVersion != null) { + if (fileVersion.toString().startsWith(productVersion.toString())) { dependency.setVersion(fileVersion.toString()); - } else if (productVersion != null && productVersion.toString().length() == data.getProductVersion().length()) { + } else if (productVersion.toString().startsWith(fileVersion.toString())) { dependency.setVersion(productVersion.toString()); } - } else { - if (productVersion != null && productVersion.toString().length() == data.getProductVersion().length()) { - dependency.setVersion(productVersion.toString()); - } else if (fileVersion != null && fileVersion.toString().length() == data.getFileVersion().length()) { - dependency.setVersion(fileVersion.toString()); - } } } } - if (dependency.getVersion() == null && data.getFileVersion() != null) { - final DependencyVersion version = DependencyVersionUtil.parseVersion(data.getFileVersion(), true); + if (dependency.getVersion() == null && data.getProductVersion() != null) { + final DependencyVersion version = DependencyVersionUtil.parseVersion(data.getProductVersion(), true); if (version != null) { dependency.setVersion(version.toString()); } } - if (dependency.getVersion() == null && data.getProductVersion() != null) { - final DependencyVersion version = DependencyVersionUtil.parseVersion(data.getProductVersion(), true); + if (dependency.getVersion() == null && data.getFileVersion() != null) { + final DependencyVersion version = DependencyVersionUtil.parseVersion(data.getFileVersion(), true); if (version != null) { dependency.setVersion(version.toString()); } diff --git a/core/src/test/java/org/owasp/dependencycheck/analyzer/AssemblyAnalyzerTest.java b/core/src/test/java/org/owasp/dependencycheck/analyzer/AssemblyAnalyzerTest.java index 7f8efeaf730..b8cde11ace8 100644 --- a/core/src/test/java/org/owasp/dependencycheck/analyzer/AssemblyAnalyzerTest.java +++ b/core/src/test/java/org/owasp/dependencycheck/analyzer/AssemblyAnalyzerTest.java @@ -190,11 +190,11 @@ void testAzureIdentity() throws MalformedPackageURLException { var expectedDescription = "Microsoft Azure.Identity Component\n\nThis is the implementation of the Azure SDK " + "Client Library for Azure Identity"; var expectedVersionEvidences = expectedAzureIdentityVersionEvidences(); - var expectedVersion = "1.700.22.46903"; + var expectedVersion = "1.7.0"; var expectedProductEvidences = expectedAzureIdentityProductEvidences(); var expectedVendorEvidences = expectedAzureIdentityVendorEvidences(); var expectedName = "Azure.Identity"; - var expectedIdentifiers = Set.of(new PurlIdentifier(new PackageURL("pkg:generic/Azure.Identity@1.700.22.46903"), + var expectedIdentifiers = Set.of(new PurlIdentifier(new PackageURL("pkg:generic/Azure.Identity@1.7.0"), Confidence.MEDIUM)); var expectedEcosystem = "dotnet"; From 9f58d2f2c4fcde3c8e3df36837efcee10f972234 Mon Sep 17 00:00:00 2001 From: Nicolas Humblot Date: Fri, 6 Mar 2026 13:25:29 +0100 Subject: [PATCH 3/3] fix: #8140 hint azure_identity_library_for_.net --- core/src/main/resources/dependencycheck-base-hint.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/core/src/main/resources/dependencycheck-base-hint.xml b/core/src/main/resources/dependencycheck-base-hint.xml index 4f3f2d2d520..87c02fe5f42 100644 --- a/core/src/main/resources/dependencycheck-base-hint.xml +++ b/core/src/main/resources/dependencycheck-base-hint.xml @@ -479,5 +479,16 @@ + + + + + + + + +