Skip to main content

Vulnerability Support

AvantiPoint Packages includes support for the NuGet VulnerabilityInfo v3 resource, allowing you to expose and query vulnerability information for packages in your feed.

Overview

The VulnerabilityInfo resource enables:

  • Exposing known vulnerabilities for packages in your feed
  • Integration with NuGet client auditing features (e.g., dotnet list package --vulnerable)
  • Querying vulnerabilities programmatically via the protocol client

Server Configuration

Vulnerability Support

Vulnerability support is enabled by default. The VulnerabilityInfo resource is always exposed in the service index to avoid NuGet client CLI warnings.

To disable vulnerability support (which will cause the endpoints to return empty results), set the EnableVulnerabilityInfo option to false in your configuration:

appsettings.json:

{
"EnableVulnerabilityInfo": false
}

Environment Variable:

export EnableVulnerabilityInfo=false

The service index will always expose a VulnerabilityInfo/6.7.0 resource. When disabled, the endpoint returns an empty vulnerability index to prevent NuGet client warnings.

Database Migrations

Before using vulnerability support, you must apply the database migrations that create the necessary tables:

For SQLite:

dotnet ef database update --context SqliteContext

For SQL Server:

dotnet ef database update --context SqlServerContext

The migrations create two tables:

  • VulnerabilityRecords: Stores vulnerability information (advisory URL, severity, description)
  • PackageVulnerabilities: Maps vulnerabilities to specific packages and version ranges

Populating Vulnerability Data

Vulnerability data must be populated in the database. Currently, this must be done manually or through custom tooling.

Example: Adding a Vulnerability

using var scope = app.Services.CreateScope();
var context = scope.ServiceProvider.GetRequiredService<IContext>();

// Create a vulnerability record
var vulnerability = new VulnerabilityRecord
{
AdvisoryUrl = "https://github.com/advisories/GHSA-xxxx-yyyy-zzzz",
Severity = "High",
Description = "SQL injection vulnerability in version 1.0.0",
CreatedUtc = DateTime.UtcNow,
UpdatedUtc = DateTime.UtcNow
};

context.VulnerabilityRecords.Add(vulnerability);
await context.SaveChangesAsync();

// Associate the vulnerability with a package
var packageVuln = new PackageVulnerability
{
PackageId = "MyPackage", // lowercase
VersionRange = "[1.0.0]", // NuGet version range syntax
VulnerabilityKey = vulnerability.Key
};

context.PackageVulnerabilities.Add(packageVuln);
await context.SaveChangesAsync();

Future Extensibility

The IVulnerabilityDataSource abstraction (optional future enhancement) would allow integration with:

  • NuGet.org vulnerability feeds
  • Internal security scanning systems
  • Third-party vulnerability databases

Protocol Client Usage

Discovering Vulnerability Support

The protocol client automatically discovers the VulnerabilityInfo resource from the service index:

var client = new NuGetClient("https://your-feed.example.com/v3/index.json");

// The client will automatically detect if vulnerability support is available
var vulnerabilities = await client.GetPackageVulnerabilitiesAsync("MyPackage");

Querying Vulnerabilities

Get all vulnerabilities for a specific package:

var vulnerabilities = await client.GetPackageVulnerabilitiesAsync(
"MyPackage",
cancellationToken);

foreach (var vuln in vulnerabilities)
{
Console.WriteLine($"Severity: {vuln.Severity}");
Console.WriteLine($"URL: {vuln.Url}");
Console.WriteLine($"Affected versions: {vuln.Versions}");
}

Advanced Usage with IVulnerabilityClient

For more control, use the IVulnerabilityClient directly:

var factory = new NuGetClientFactory(httpClient, serviceIndexUrl);
var vulnerabilityClient = factory.CreateVulnerabilityClient();

// Get the vulnerability index
var index = await vulnerabilityClient.GetIndexOrNullAsync();
if (index != null)
{
Console.WriteLine($"Vulnerability data version: {index.Version}");
Console.WriteLine($"Number of pages: {index.Pages.Count}");

// Get a specific page
var page = await vulnerabilityClient.GetPageOrNullAsync(
index.Pages[0].Id,
cancellationToken);
}

API Endpoints

When vulnerability support is enabled, the following endpoints are available:

Vulnerability Index

URL: /v3/vulnerabilities/index.json

Returns the vulnerability index with references to vulnerability pages.

Response:

{
"version": "6.7.0",
"pages": [
{
"@id": "vulnerabilities-base.json",
"@name": "base",
"@updated": "2025-11-17T00:00:00Z"
}
]
}

Vulnerability Page

URL: Referenced in the index (e.g., /v3/vulnerabilities/vulnerabilities-base.json)

Returns vulnerability data for one or more packages.

Response:

{
"mypackage": [
{
"url": "https://github.com/advisories/GHSA-xxxx-yyyy-zzzz",
"severity": "High",
"versions": "[1.0.0, 2.0.0)"
}
]
}

Data Model

VulnerabilityRecord

  • Key: Unique identifier (auto-generated)
  • AdvisoryUrl: URL to the vulnerability advisory (required, indexed)
  • Severity: Severity level (required, max 50 characters)
  • Description: Detailed description (optional, max 4000 characters)
  • CreatedUtc: Creation timestamp
  • UpdatedUtc: Last update timestamp (indexed)

PackageVulnerability

  • Key: Unique identifier (auto-generated)
  • PackageId: Package identifier (required, lowercase, indexed)
  • VersionRange: NuGet version range syntax (required, max 256 characters)
  • VulnerabilityKey: Foreign key to VulnerabilityRecord

Indexes

The following indexes are created for performance:

  • VulnerabilityRecords:
    • AdvisoryUrl
    • UpdatedUtc
  • PackageVulnerabilities:
    • PackageId
    • PackageId + VersionRange (composite)
    • VulnerabilityKey (foreign key)

Best Practices

  1. Version Ranges: Use NuGet version range syntax consistently (e.g., [1.0.0], [1.0.0, 2.0.0))
  2. Package IDs: Always store package IDs in lowercase for consistency
  3. Update Timestamps: Keep UpdatedUtc current when modifying vulnerabilities
  4. Severity Values: Use standard severity levels: "Low", "Moderate", "High", "Critical"
  5. Advisory URLs: Use canonical, permanent URLs for vulnerability advisories

Troubleshooting

Vulnerability resource not appearing in service index

  • Verify EnableVulnerabilityInfo is set to true in configuration
  • Check application logs for startup errors
  • Restart the application after configuration changes

No vulnerabilities returned

  • Ensure the database migrations have been applied
  • Verify vulnerability data exists in the database
  • Check that package IDs are lowercase in the database
  • Confirm version ranges are in valid NuGet syntax

Protocol client returns null

  • The server may not support vulnerability information
  • Check that the service index includes a VulnerabilityInfo resource
  • Ensure the HTTP client has network access to the server

See Also