Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change VerifyGitHubVulnerabilities into a job #9298

Merged
merged 3 commits into from
Nov 7, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,6 @@
<Version>2.106.0</Version>
</PackageReference>
</ItemGroup>
<ItemGroup>
<Content Include="Scripts\nssm.exe" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NuGet.Services.Entities\NuGet.Services.Entities.csproj">
<Project>{6262f4fc-29be-4226-b676-db391c89d396}</Project>
Expand Down
25 changes: 16 additions & 9 deletions src/VerifyGitHubVulnerabilities/Job.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,30 @@ namespace VerifyGitHubVulnerabilities
{
class Job : JsonConfigurationJob
{
private readonly HttpClient _client = new HttpClient();

public override async Task Run()
{
Console.WriteLine("Fetching vulnerabilities from GitHub...");
var telemetryClient = _serviceProvider.GetRequiredService<NuGet.Services.Logging.ITelemetryClient>();

Logger.LogInformation("Fetching vulnerabilities from GitHub...");
var advisoryQueryService = _serviceProvider.GetRequiredService<IAdvisoryQueryService>();
var advisories = await advisoryQueryService.GetAdvisoriesSinceAsync(DateTimeOffset.MinValue, CancellationToken.None);
Console.WriteLine($" FOUND {advisories.Count} advisories.");
Logger.LogInformation("Found {Count} advisories.", advisories.Count);

Console.WriteLine("Fetching vulnerabilities from DB...");
Logger.LogInformation("Fetching vulnerabilities from DB...");
var ingestor = _serviceProvider.GetRequiredService<IAdvisoryIngestor>();
await ingestor.IngestAsync(advisories.OrderBy(x => x.DatabaseId).ToList());

var verifier = _serviceProvider.GetRequiredService<IPackageVulnerabilitiesVerifier>();
Console.WriteLine(verifier.HasErrors ?
"DB does not match GitHub API - see stderr output for details" :
"DB/metadata matches GitHub API!");
if (verifier.HasErrors)
{
Logger.LogError("DB/metadata does not match GitHub API - see error logs for details");
telemetryClient.TrackMetric(nameof(VerifyGitHubVulnerabilities) + ".DataIsInconsistent", 1);
}
else
{
Logger.LogInformation("DB/metadata matches GitHub API!");
telemetryClient.TrackMetric(nameof(VerifyGitHubVulnerabilities) + ".DataIsConsistent", 1);
}
}

protected override void ConfigureJobServices(IServiceCollection services, IConfigurationRoot configurationRoot)
Expand Down Expand Up @@ -95,7 +102,7 @@ protected void ConfigureGalleryServices(ContainerBuilder containerBuilder)
protected void ConfigureQueryServices(ContainerBuilder containerBuilder)
{
containerBuilder
.RegisterInstance(_client)
.RegisterInstance(new HttpClient())
.As<HttpClient>();

containerBuilder
Expand Down
2 changes: 1 addition & 1 deletion src/VerifyGitHubVulnerabilities/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class Program
static void Main(string[] args)
{
var job = new Job();
JobRunner.RunOnce(job, args).Wait();
JobRunner.Run(job, args).Wait();
}
}
}
15 changes: 5 additions & 10 deletions src/VerifyGitHubVulnerabilities/README.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,23 @@
## Overview

This is a run-once job for taking a current snapshot of the whole of GitHub's security advisory collection (pertaining to the `NUGET` ecosystem) and comparing it with the vulnerability records in the gallery database. It's designed to be run on an ad hoc basis (not an ongoing monitoring job), from the command line, with all status message streamed to `stdout` and all vulnerability differences streamed to `stderr`.
This is a recurring, monitoring job for taking a current snapshot of the whole of GitHub's security advisory collection (pertaining to the `NUGET` ecosystem) and comparing it with the vulnerability records in the gallery database. It's designed to interact with GitHub, the NuGet Gallery DB, and V3 metadata endpoints in a read-only manner. It just reports problems when it finds them.

## Running the job
## Running the job locally

A typical command line will look like this:

```
verifygithubvulnerabilities.exe -Configuration appsettings.json -InstrumentationKey <key> -HeartbeatIntervalSeconds 60 2>c:\errors.txt
VerifyGitHubVulnerabilities.exe -Configuration appsettings.json -InstrumentationKey <key> -HeartbeatIntervalSeconds 60
```

- the `2>` will direct `stderr` to a text file (a `1>` would similarly direct `stdout` but it's probably useful to have that print to console)
- the contents of the `appsettings.json` file will be similar (identical is fine--there are just some extra unneeded settings in them) to the settings files used for `GitHubVulnerabilities2Db`.

### Using DEV resources

The easiest way to run the tool if you are on the nuget.org team is to use the DEV environment resources:

1. Install the certificate used to authenticate as our client AAD app registration into your `CurrentUser` certificate store.
1. Clone our internal [`NuGetDeployment`](https://nuget.visualstudio.com/DefaultCollection/NuGetMicrosoft/_git/NuGetDeploymentp) repository.
1. Take a copy of the [DEV GitHubVulnerabilities2Db appsettings.json](https://nuget.visualstudio.com/NuGetMicrosoft/_git/NuGetDeployment?path=%2Fsrc%2FJobs%2FNuGet.Jobs.Cloud%2FJobs%2FGitHubVulnerabilities2Db%2FDEV%2Fnorthcentralus%2Fappsettings.json) file and place it in the same directory as the `verifygithubvulnerabilities.exe`. This will use our secrets to authenticate to the SQL server (this file also contains a reference to the secret used for the access token to GitHub).
1. Set the following property, in the `appsettings.json`, under the `"Initialization"` object: `"NuGetV3Index": "https://apidev.nugettest.org/v3/index.json"`.
1. Overwrite the Gallery DB `"ConnectionString"` property to be the connection string from [DEV USSC (read-only) gallery config](https://nuget.visualstudio.com/NuGetMicrosoft/_git/NuGetDeployment?path=/src/Gallery/ExpressV2/ServiceSpecs/Parameters.AS/DEV/USSC/NuGet.Gallery.Parameters.json&version=GBmaster). This provides an additional protection to ensure the job runs as read-only.
2. Run as per above.
1. Take a copy of the [DEV VerifyGitHubVulnerabilities appsettings.json](https://nuget.visualstudio.com/NuGetMicrosoft/_git/NuGetDeployment?path=%2Fsrc%2FJobs%2FNuGet.Jobs.Cloud%2FJobs%VerifyGitHubVulnerabilities%2FDEV%2Fnorthcentralus%2Fappsettings.json) file and place it in the same directory as the `VerifyGitHubVulnerabilities.exe`. This will use our secrets to authenticate to the SQL server (this file also contains a reference to the secret used for the access token to GitHub).
1. Run as per above.

## Algorithm

Expand Down
41 changes: 41 additions & 0 deletions src/VerifyGitHubVulnerabilities/Scripts/Functions.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
Function Uninstall-NuGetService() {
joelverhagen marked this conversation as resolved.
Show resolved Hide resolved
Param ([string]$ServiceName)

if (Get-Service $ServiceName -ErrorAction SilentlyContinue)
{
Write-Host Removing service $ServiceName...
Stop-Service $ServiceName -Force
sc.exe delete $ServiceName
Write-Host Removed service $ServiceName.
} else {
Write-Host Skipping removal of service $ServiceName - no such service exists.
}
}

Function Install-NuGetService() {
Param (
[string]$ServiceName,
[string]$ServiceTitle,
[string]$ScriptToRun,
[Parameter(Mandatory=$false)][string]$Username,
[Parameter(Mandatory=$false)][string]$Password
)

Write-Host Installing service $ServiceName...

$installService = "nssm install $ServiceName $ScriptToRun"
cmd /C $installService

Set-Service -Name $ServiceName -DisplayName "$ServiceTitle - $ServiceName" -Description "Runs $ServiceTitle." -StartupType Automatic
sc.exe failure $ServiceName reset= 30 actions= restart/5000

if ($Username) {
Write-Host Running service under specific credentials.
sc.exe config "$ServiceName" obj= "$Username" password= "$Password"
}

# Run service
net start $ServiceName

Write-Host Installed service $ServiceName.
}
20 changes: 20 additions & 0 deletions src/VerifyGitHubVulnerabilities/Scripts/PostDeploy.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
. .\Functions.ps1
joelverhagen marked this conversation as resolved.
Show resolved Hide resolved

$jobsToInstall = $OctopusParameters["Jobs.ServiceNames"].Split("{,}")

Write-Host Installing services...

$currentDirectory = [string](Get-Location)

$jobsToInstall.Split("{;}") | %{
$serviceName = $_
$serviceTitle = $OctopusParameters["Jobs.$serviceName.Title"]
$serviceUsername = $OctopusParameters["Jobs.$serviceName.Username"]
$servicePassword = $OctopusParameters["Jobs.$serviceName.Password"]
$scriptToRun = $OctopusParameters["Jobs.$serviceName.Script"]
$scriptToRun = "$currentDirectory\$scriptToRun"

Install-NuGetService -ServiceName $serviceName -ServiceTitle $serviceTitle -ScriptToRun $scriptToRun -Username $serviceUsername -Password $servicePassword
}

Write-Host Installed services.
11 changes: 11 additions & 0 deletions src/VerifyGitHubVulnerabilities/Scripts/PreDeploy.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
. .\Functions.ps1
joelverhagen marked this conversation as resolved.
Show resolved Hide resolved

$jobsToInstall = $OctopusParameters["Jobs.ServiceNames"].Split("{,}")

Write-Host Removing services...

$jobsToInstall.Split("{;}") | %{
Uninstall-NuGetService -ServiceName $_
}

Write-Host Removed services.
Binary file not shown.
Loading