Skip to content

PRP: Fix dotnet MSBuild parser to support the <Version> child-element form of PackageReference (currently drops those packages) #2288

Description

@h1-mrz
  • Software distribution method or binary type: NuGet packages declared in MSBuild project files (.csproj, .vbproj, .fsproj) via <PackageReference> elements. All three file types share one parser: extractor/filesystem/language/dotnet/common/common.go (ExtractPackagesFromMSBuildXML). Packages map to the NuGet OSV ecosystem (purl type nuget).

  • Popularity of distribution method: SDK-style MSBuild project files are the dominant dependency-declaration format for modern .NET (Core / .NET 5+). <PackageReference> is the default mechanism used by dotnet, Visual Studio, and Rider across millions of C#/VB/F# projects.

  • Any critical, emergent vulnerability associated with software from the distribution method: Packages map directly to the OSV NuGet feed (https://osv.dev/list?ecosystem=NuGet). Any <PackageReference> dropped by the parser (e.g. a vulnerable Newtonsoft.Json, System.Text.Json, or an Azure/AWS SDK) is never queried against OSV, producing a silent false-negative in the scan.

  • Gap coverage / what the existing extractor misses:

    The shared parser models a package version as an XML attribute only:

    // common.go:28-31
    type PackageReference struct {
        Include string `xml:"Include,attr"`
        Version string `xml:"Version,attr"`   // <-- attribute-only
    }

    MSBuild documents PackageReference metadata as expressible either as an attribute or as a child element, and both are equivalent. When the version is given as a child <Version> element, pkg.Version is empty, so the guard at common.go:58 (if pkg.Include == "" || pkg.Version == "") skips the package entirely.

    Concrete valid input that is silently dropped today:

    <Project Sdk="Microsoft.NET.Sdk">
      <ItemGroup>
        <PackageReference Include="Newtonsoft.Json">
          <Version>13.0.1</Version>
          <PrivateAssets>all</PrivateAssets>
        </PackageReference>
      </ItemGroup>
    </Project>

    Expected: emit pkg:nuget/Newtonsoft.Json@13.0.1. Actual: nothing is emitted. The child-element form is common in projects migrated from packages.config and in any project that pairs the version with asset-control child elements (<PrivateAssets>, <IncludeAssets>, <ExcludeAssets>), so real-world projects hit this and lose NuGet vuln coverage.

    This is distinct from the open wildcard/floating-version issue No vulnerabilities detected in packages with version containing * #1958 (Version="3.6.*" resolution) and from Central Package Management (handled separately by dotnet/nugetcpm). Here the version is fully specified — just in element form — and is dropped.

    Suggested fix (non-trivial): extend PackageReference to also capture a child <Version> element and fall back to it when the attribute is absent, with unit tests over both forms. This is a targeted accuracy improvement to an existing extractor, in the spirit of the accepted PRP: Fix swift/packageresolved extractor to support SwiftURL ecosystem (currently uses wrong purl type) #1966 (swift purl-type fix) and PRP: Extractor for RPM packages (Improvements) #2063 (RPM improvements).

  • Resources:

Metadata

Metadata

Assignees

Labels

PRPPatch Reward Program: This label is added to all PRP related issues for easy filteringPRP:RequestPatch Reward Program: This issue is a PRP contribution request and is being reviewed by the panel.

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions