Skip to content

Instantly share code, notes, and snippets.

@hoerup
Created August 12, 2024 12:06
Show Gist options
  • Save hoerup/92e2f4d1bb1e16fedf354ec981abcf35 to your computer and use it in GitHub Desktop.
Save hoerup/92e2f4d1bb1e16fedf354ec981abcf35 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text.Json;
namespace Hoerup.PackageReplacer
{
public static class DotnetHelper
{
public static PackageOverview ListPackages()
{
var processInfo = new ProcessStartInfo("dotnet", "list package --format json --include-transitive");
processInfo.UseShellExecute = false;
processInfo.RedirectStandardOutput = true;
processInfo.RedirectStandardError = true;
var process = Process.Start(processInfo);
process.WaitForExit();
var output = process.StandardOutput.ReadToEnd();
var err = process.StandardError.ReadToEnd();
if (process.ExitCode != 0)
{
Console.WriteLine(output);
Console.WriteLine(err);
throw new Exception($"'dotnet list' exited with exitcode {process.ExitCode}");
}
return JsonSerializer.Deserialize<PackageOverview>(output);
}
public static void AddPackage(string package, string version)
{
var processInfo = new ProcessStartInfo("dotnet", $"add package {package} --version {version}");
processInfo.UseShellExecute = false;
processInfo.RedirectStandardOutput = true;
processInfo.RedirectStandardError = true;
var process = Process.Start(processInfo);
process.WaitForExit();
var output = process.StandardOutput.ReadToEnd();
var err = process.StandardError.ReadToEnd();
if (process.ExitCode != 0)
{
Console.WriteLine(output);
Console.WriteLine(err);
throw new Exception($"'dotnet add' exited with exitcode {process.ExitCode}");
}
}
}
public record PackageOverview(int version, string parameters, List<PackageProject> projects);
public record PackageProject(string path, List<PackageFramework> frameworks);
public record PackageFramework(string framework, List<Package> topLevelPackages, List<Package> transitivePackages);
public record Package(string id, string resolvedVersion);
}
using System;
using System.Collections.Generic;
using System.Linq;
namespace Hoerup.PackageReplacer
{
record PackageReplacement(string package, string oldVersion, string newVersion, string reason, string severity);
class Program
{
static List<PackageReplacement> replacements = [
new PackageReplacement("System.Formats.Asn1", "6.0.0", "6.0.1", "CVE-2024-38095", "high"),
new PackageReplacement("System.Formats.Asn1", "8.0.0", "8.0.1", "CVE-2024-38095", "high"),
new PackageReplacement("System.Net.Http", "4.3.0", "4.3.4", "CVE-2018-8292", "high"),
new PackageReplacement("System.Text.RegularExpressions", "4.3.0", "4.3.1", "CVE-2019-0820", "high"),
new PackageReplacement("System.Security.Cryptography.Pkcs", "6.0.1", "6.0.3", "CVE-2023-29331", "high"),
];
static int Main(string[] args)
{
var overview = DotnetHelper.ListPackages();
if (overview.projects.Count != 1)
{
Console.WriteLine("More than 1 project was found");
return 1;
}
var proj = overview.projects[0];
Console.WriteLine($"Analyzing {proj.path}");
if (proj.frameworks.Count != 1)
{
Console.WriteLine("More than 1 framework was found");
return 1;
}
var packages = proj.frameworks[0].transitivePackages;
if (packages == null)
{
Console.WriteLine("No transitive packages was found");
return 0;
}
foreach (var package in packages)
{
var repl = replacements.Where( r => r.package == package.id && r.oldVersion == package.resolvedVersion).FirstOrDefault();
if (repl != null)
{
Console.WriteLine($"Found replacement: {repl.package} {repl.oldVersion} -> {repl.newVersion} due to {repl.reason} ({repl.severity})");
DotnetHelper.AddPackage(repl.package, repl.newVersion);
}
}
return 0;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment