gemnasium-maven does not consider FINAL and RELEASE versions as equal

Summary

When comparing Maven versions, gemnasium-maven does not consider the RELEASE qualifier as equal to FINAL.

This is inconsistent with the specification, which states the following:

final = ga = release < sp

As a result, gemnasium-maven might miss vulnerabilities when scanning a project that depends on a RELEASE version.

Steps to reproduce

Create an advisory file with the values shown below.

---
package_slug: "maven/some.dependency"
identifier: "CVE-2021-123"
affected_range: "[3.0.12]"

Now modify your lockfile pom.xml to include some.dependency version 3.0.12.RELEASE. 3.0.12.RELEASE cannot be matched against the range [3.0.12] since 3.0.12 and 3.0.12.RELEASE are treated as different versions. The CVE CVE-2021-123 does not show up in the vulnerability report.

What is the current bug behavior?

The version matcher that is used to match maven versions in gemnasium seems to behave differently from the rerference implementation provided by Maven.

The reference implementation seems to recognize 3.0.12, 3.0.12.FINAL and 3.0.12.RELEASE as the same versions:

        DefaultArtifactVersion normal = new DefaultArtifactVersion("3.0.1");
        DefaultArtifactVersion release = new DefaultArtifactVersion("3.0.1.RELEASE");
        DefaultArtifactVersion fin = new DefaultArtifactVersion("3.0.1.FINAL");

        if (normal.compareTo(release) == 0) {
            System.out.println(normal.toString() + " == " + release.toString());
        } else {
            System.out.println(normal.toString() + " != " + release.toString());
        }

        if (release.compareTo(fin) == 0) {
            System.out.println(release.toString() + " == " + fin.toString());
        } else {
            System.out.println(release.toString() + " != " + fin.toString());
        }
3.0.1 == 3.0.1.RELEASE
3.0.1.RELEASE == 3.0.1.FINAL

What is the expected correct behavior?

Versions suffixed with FINAL and RELEASE should be treated equal to their non-suffixed counterparts.

Possible fixes

A possible solution would be the integration of a vrange tool based on the maven reference implementation into gemansium. We could use https://gitlab.com/gitlab-org/security-products/advisory-db-curation-tools/-/tree/master/adbcurate/vadapters/maven as a starting point.

Implementation Plan

There is indeed a bug in the semver implementation in that release should be treated the same as semver when comparing the same version with or without the qualifiers: https://github.com/apache/maven/blob/master/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/ComparableVersion.java#L364

https://gitlab.com/gitlab-org/security-products/gemnasium/semver/-/blob/master/maven/segment.go#L98-106

Edited by Fabien Catteau