Skip to content

Commit 6834a55

Browse files
authored
fix: #8140 AssemblyAnalyzer version resolution issue (#8352)
2 parents f310dc2 + 9f58d2f commit 6834a55

3 files changed

Lines changed: 136 additions & 15 deletions

File tree

core/src/main/java/org/owasp/dependencycheck/analyzer/AssemblyAnalyzer.java

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ public void analyzeDependency(Dependency dependency, Engine engine) throws Analy
194194
* @param data the assembly data
195195
* @param dependency the dependency to update
196196
*/
197-
private void updateDependency(final AssemblyData data, Dependency dependency) {
197+
void updateDependency(final AssemblyData data, Dependency dependency) {
198198
final StringBuilder sb = new StringBuilder();
199199
if (!StringUtils.isBlank(data.getFileDescription())) {
200200
sb.append(data.getFileDescription());
@@ -253,30 +253,23 @@ private void updateDependency(final AssemblyData data, Dependency dependency) {
253253
}
254254
}
255255
if (dependency.getVersion() == null) {
256-
if (data.getFileVersion() != null && data.getProductVersion() != null
257-
&& data.getFileVersion().length() >= data.getProductVersion().length()) {
258-
if (fileVersion != null && fileVersion.toString().length() == data.getFileVersion().length()) {
256+
if (fileVersion != null && productVersion != null) {
257+
if (fileVersion.toString().startsWith(productVersion.toString())) {
259258
dependency.setVersion(fileVersion.toString());
260-
} else if (productVersion != null && productVersion.toString().length() == data.getProductVersion().length()) {
259+
} else if (productVersion.toString().startsWith(fileVersion.toString())) {
261260
dependency.setVersion(productVersion.toString());
262261
}
263-
} else {
264-
if (productVersion != null && productVersion.toString().length() == data.getProductVersion().length()) {
265-
dependency.setVersion(productVersion.toString());
266-
} else if (fileVersion != null && fileVersion.toString().length() == data.getFileVersion().length()) {
267-
dependency.setVersion(fileVersion.toString());
268-
}
269262
}
270263
}
271264
}
272-
if (dependency.getVersion() == null && data.getFileVersion() != null) {
273-
final DependencyVersion version = DependencyVersionUtil.parseVersion(data.getFileVersion(), true);
265+
if (dependency.getVersion() == null && data.getProductVersion() != null) {
266+
final DependencyVersion version = DependencyVersionUtil.parseVersion(data.getProductVersion(), true);
274267
if (version != null) {
275268
dependency.setVersion(version.toString());
276269
}
277270
}
278-
if (dependency.getVersion() == null && data.getProductVersion() != null) {
279-
final DependencyVersion version = DependencyVersionUtil.parseVersion(data.getProductVersion(), true);
271+
if (dependency.getVersion() == null && data.getFileVersion() != null) {
272+
final DependencyVersion version = DependencyVersionUtil.parseVersion(data.getFileVersion(), true);
280273
if (version != null) {
281274
dependency.setVersion(version.toString());
282275
}

core/src/main/resources/dependencycheck-base-hint.xml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,5 +479,16 @@
479479
</remove>
480480
</hint>
481481

482+
<hint>
483+
<given>
484+
<evidence type="product" source="grokassembly" name="ProductName" value="Azure .NET SDK"
485+
confidence="HIGHEST" />
486+
<evidence type="product" source="file" name="name" value="Azure.Identity" confidence="HIGH" />
487+
</given>
488+
<add>
489+
<evidence type="product" source="hint analyzer" name="product" value="azure_identity_library_for_.net"
490+
confidence="HIGHEST"/>
491+
</add>
492+
</hint>
482493
</hints>
483494

core/src/test/java/org/owasp/dependencycheck/analyzer/AssemblyAnalyzerTest.java

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
*/
1818
package org.owasp.dependencycheck.analyzer;
1919

20+
import com.github.packageurl.MalformedPackageURLException;
21+
import com.github.packageurl.PackageURL;
22+
import org.jspecify.annotations.NonNull;
2023
import org.junit.jupiter.api.AfterEach;
2124
import org.junit.jupiter.api.BeforeEach;
2225
import org.junit.jupiter.api.Test;
@@ -27,12 +30,15 @@
2730
import org.owasp.dependencycheck.dependency.Dependency;
2831
import org.owasp.dependencycheck.dependency.Evidence;
2932
import org.owasp.dependencycheck.dependency.EvidenceType;
33+
import org.owasp.dependencycheck.dependency.naming.PurlIdentifier;
3034
import org.owasp.dependencycheck.exception.InitializationException;
3135
import org.owasp.dependencycheck.utils.Settings;
36+
import org.owasp.dependencycheck.xml.assembly.AssemblyData;
3237
import org.slf4j.Logger;
3338
import org.slf4j.LoggerFactory;
3439

3540
import java.io.File;
41+
import java.util.Set;
3642

3743
import static org.junit.jupiter.api.Assertions.assertEquals;
3844
import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -175,6 +181,117 @@ void testWithSettingMono() {
175181
}
176182
}
177183

184+
@Test
185+
void testAzureIdentity() throws MalformedPackageURLException {
186+
// Given
187+
var data = newAzureIdentityAssemblyData();
188+
var dependency = newAzureIdentityDependency();
189+
190+
var expectedDescription = "Microsoft Azure.Identity Component\n\nThis is the implementation of the Azure SDK " +
191+
"Client Library for Azure Identity";
192+
var expectedVersionEvidences = expectedAzureIdentityVersionEvidences();
193+
var expectedVersion = "1.7.0";
194+
var expectedProductEvidences = expectedAzureIdentityProductEvidences();
195+
var expectedVendorEvidences = expectedAzureIdentityVendorEvidences();
196+
var expectedName = "Azure.Identity";
197+
var expectedIdentifiers = Set.of(new PurlIdentifier(new PackageURL("pkg:generic/Azure.Identity@1.7.0"),
198+
Confidence.MEDIUM));
199+
var expectedEcosystem = "dotnet";
200+
201+
// When
202+
analyzer.updateDependency(data, dependency);
203+
204+
// Then
205+
assertEquals(expectedDescription, dependency.getDescription());
206+
assertEquals(expectedVersionEvidences, dependency.getEvidence(EvidenceType.VERSION));
207+
assertEquals(expectedVersion, dependency.getVersion());
208+
assertEquals(expectedProductEvidences, dependency.getEvidence(EvidenceType.PRODUCT));
209+
assertEquals(expectedVendorEvidences, dependency.getEvidence(EvidenceType.VENDOR));
210+
assertEquals(expectedName, dependency.getName());
211+
assertEquals(expectedIdentifiers, dependency.getSoftwareIdentifiers());
212+
assertEquals(expectedEcosystem, dependency.getEcosystem());
213+
}
214+
215+
private static @NonNull AssemblyData newAzureIdentityAssemblyData() {
216+
var data = new AssemblyData();
217+
data.setCompanyName("Microsoft Corporation");
218+
data.setProductName("Azure .NET SDK");
219+
data.setProductVersion("1.7.0+3627e3cbc75c628f659d033ed9270c9d02ab9038");
220+
data.setComments("This is the implementation of the Azure SDK Client Library for Azure Identity");
221+
data.setFileDescription("Microsoft Azure.Identity Component");
222+
data.setFileName("/home/jdoe/ScanFolder/Azure.Identity.dll");
223+
data.setFileVersion("1.700.22.46903");
224+
data.setInternalName("Azure.Identity.dll");
225+
data.setOriginalFilename("Azure.Identity.dll");
226+
data.setFullName("Azure.Identity, Version=1.7.0.0, Culture=neutral, PublicKeyToken=92742159e12e44c8");
227+
228+
data.addNamespace("Microsoft.CodeAnalysis");
229+
data.addNamespace("System.Runtime.CompilerServices");
230+
data.addNamespace("Azure.Core");
231+
data.addNamespace("Azure.Core.Pipeline");
232+
data.addNamespace("Azure.Core.Diagnostics");
233+
// The following duplication is on purpose, this use case has one
234+
data.addNamespace("Azure.Identitiy");
235+
data.addNamespace("Azure.Identitiy");
236+
return data;
237+
}
238+
239+
private static @NonNull Dependency newAzureIdentityDependency() {
240+
var dependency = new Dependency();
241+
dependency.setActualFilePath("/home/jdoe/ScanFolder/Azure.Identity.dll");
242+
dependency.setFilePath("/home/jdoe/ScanFolder/Azure.Identity.dll");
243+
dependency.setFileName("Azure.Identity.dll");
244+
dependency.setPackagePath("/home/jdoe/ScanFolder/Azure.Identity.dll");
245+
dependency.setMd5sum("19f72346b3952c135c121e30235d4064");
246+
dependency.setSha1sum("1ac0e967367aa7679a89b2eb652a7996870d9043");
247+
dependency.setSha256sum("666973af908cf82a495530b2ea23074004dead445e1bb46ef75a5e3c879a6321");
248+
249+
var nameEvidence = new Evidence("file", "name", "Azure.Identity", Confidence.HIGH);
250+
251+
dependency.addEvidence(EvidenceType.VENDOR, nameEvidence);
252+
dependency.addEvidence(EvidenceType.PRODUCT, nameEvidence);
253+
254+
return dependency;
255+
}
256+
257+
private static @NonNull Set<Evidence> expectedAzureIdentityVersionEvidences() {
258+
var fileVersionEvidence = new Evidence("grokassembly", "FileVersion", "1.700.22.46903", Confidence.HIGH);
259+
var productVersionEvidence = new Evidence("grokassembly", "ProductVersion", "1.7.0+3627e3cbc75c628f659d033ed9270c9d02ab9038", Confidence.HIGHEST);
260+
261+
return Set.of(fileVersionEvidence, productVersionEvidence);
262+
}
263+
264+
private static @NonNull Set<Evidence> expectedAzureIdentityProductEvidences() {
265+
var nameEvidence = new Evidence("file", "name", "Azure.Identity", Confidence.HIGH);
266+
var companyNameLowEvidence = new Evidence("grokassembly", "CompanyName", "Microsoft Corporation", Confidence.LOW);
267+
var fileDescriptionHighEvidence = new Evidence("grokassembly", "FileDescription",
268+
"Microsoft Azure.Identity Component", Confidence.HIGH);
269+
var internalNameMediumEvidence = new Evidence("grokassembly", "InternalName", "Azure.Identity.dll",
270+
Confidence.MEDIUM);
271+
var originalFilenameMediumEvidence = new Evidence("grokassembly", "OriginalFilename", "Azure.Identity.dll",
272+
Confidence.MEDIUM);
273+
var productNameHighestEvidence = new Evidence("grokassembly", "ProductName", "Azure .NET SDK", Confidence.HIGHEST);
274+
275+
return Set.of(nameEvidence, companyNameLowEvidence, fileDescriptionHighEvidence,
276+
internalNameMediumEvidence, originalFilenameMediumEvidence, productNameHighestEvidence);
277+
}
278+
279+
private static @NonNull Set<Evidence> expectedAzureIdentityVendorEvidences() {
280+
var nameEvidence = new Evidence("file", "name", "Azure.Identity", Confidence.HIGH);
281+
var companyNameHighestEvidence = new Evidence("grokassembly", "CompanyName", "Microsoft Corporation",
282+
Confidence.HIGHEST);
283+
var fileDescriptionLowEvidence = new Evidence("grokassembly", "FileDescription",
284+
"Microsoft Azure.Identity Component", Confidence.LOW);
285+
var internalNameLowEvidence = new Evidence("grokassembly", "InternalName", "Azure.Identity.dll",
286+
Confidence.LOW);
287+
var originalFilenameLowEvidence = new Evidence("grokassembly", "OriginalFilename", "Azure.Identity.dll",
288+
Confidence.LOW);
289+
var productNameMediumEvidence = new Evidence("grokassembly", "ProductName", "Azure .NET SDK",
290+
Confidence.MEDIUM);
291+
return Set.of(nameEvidence, companyNameHighestEvidence, fileDescriptionLowEvidence,
292+
internalNameLowEvidence, originalFilenameLowEvidence, productNameMediumEvidence);
293+
}
294+
178295
@AfterEach
179296
@Override
180297
public void tearDown() throws Exception {

0 commit comments

Comments
 (0)