-
-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
843fdf7
commit b14a0a8
Showing
15 changed files
with
377 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
*/bin/* | ||
*/obj/* | ||
*.dll | ||
|
||
*.pdb | ||
|
||
*.cache | ||
|
||
Src/.idea/.idea.NuGetDefense/.idea/ | ||
|
||
*.blob | ||
|
||
Src/.idea/.idea.NuGetDefense/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<TargetFramework>netcoreapp3.1</TargetFramework> | ||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild> | ||
<PackageVersion>0.0.1</PackageVersion> | ||
<Title>NuGetDefense</Title> | ||
<Authors>Curtis Carter</Authors> | ||
<Description>NuGetDefense ~ Check for Known Vulnerabilities at Build</Description> | ||
<PackageDescription>NuGetDefense was inspired by [OWASP SafeNuGet](https://nuget.org/packages/SafeNuGet/) but aims to check with multiple sources for known vulnerabilities.</PackageDescription> | ||
<Copyright>Curtis Carter 2020</Copyright> | ||
<PackageProjectUrl>https://github.com/DigitalCoyote/NuGetDefense</PackageProjectUrl> | ||
<PackageLicenseExpression>MIT</PackageLicenseExpression> | ||
<PackageReleaseNotes>Initial Release: Support for checking for OSS Vulnerabilities listed on OSS Index</PackageReleaseNotes> | ||
<PackageTags>Security</PackageTags> | ||
<PackageId>NuGetDefense</PackageId> | ||
<NuspecFile>NuGetDefense.nuspec</NuspecFile> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="System.Text.Json" Version="4.7.0" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<Compile Remove="Tests\**" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<EmbeddedResource Remove="Tests\**" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<None Remove="Tests\**" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<None Remove="NuGetDefense.nuspec" /> | ||
<Content Include="NuGetDefense.nuspec" /> | ||
</ItemGroup> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
<?xml version="1.0"?> | ||
<package> | ||
<metadata> | ||
<id>NuGetDefense</id> | ||
<Title>NuGetDefense</Title> | ||
<version>0.0.1</version> | ||
<authors>Curtis Carter</authors> | ||
<owners>Curtis Carter</owners> | ||
<projectUrl>https://github.com/DigitalCoyote/NuGetDefense</projectUrl> | ||
<requireLicenseAcceptance>false</requireLicenseAcceptance> | ||
<summary>NuGetDefense ~ Check for Known Vulnerabilities at Build</summary> | ||
<description>NuGetDefense was inspired by [OWASP SafeNuGet](https://nuget.org/packages/SafeNuGet/) but aims to check with multiple sources for known vulnerabilities.</description> | ||
<releaseNotes>First version: OSS Index used as initial source for vulnerabilities</releaseNotes> | ||
<repository type="git" url="https://github.com/digitalcoyote/NuGetDefense.git"/> | ||
<license type="expression">MIT</license> | ||
<tags>Security</tags> | ||
<dependencies> | ||
<dependency id="System.Text.Json" version="4.7.0" exclude="Build,Analyzers" /> | ||
</dependencies> | ||
</metadata> | ||
|
||
<files> | ||
<!-- <file src="Src/bin/Release/net461/NuGetDefense.exe" target="tools/net461/NuGetDefense.exe" /> --> | ||
<file src="build/" target="build" /> | ||
<file src="bin/Release/" target="tools" /> | ||
<file src="lib/" target="lib" /> | ||
</files> | ||
</package> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
|
||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NuGetDefense", "NuGetDefense.csproj", "{B5542178-4516-45C6-B77D-9AF9C1DCC8EA}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Release|Any CPU = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{B5542178-4516-45C6-B77D-9AF9C1DCC8EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{B5542178-4516-45C6-B77D-9AF9C1DCC8EA}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{B5542178-4516-45C6-B77D-9AF9C1DCC8EA}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{B5542178-4516-45C6-B77D-9AF9C1DCC8EA}.Release|Any CPU.Build.0 = Release|Any CPU | ||
EndGlobalSection | ||
EndGlobal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
using System.Collections.Generic; | ||
using System.Text.Json.Serialization; | ||
using System.Xml.Serialization; | ||
|
||
namespace NuGetDefense | ||
{ | ||
public class NuGetPackage | ||
{ | ||
public string Id { get; set; } | ||
|
||
public string Version { get; set; } | ||
|
||
public string PackageUrl => $@"pkg:nuget/{Id}@{Version}"; | ||
public int LinePosition { get; set; } | ||
public int LineNumber { get; set; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
using System.Text.Json.Serialization; | ||
|
||
namespace NuGetDefense.OSSIndex | ||
{ | ||
public class ComponentReport | ||
{ | ||
/// <summary> | ||
/// Description of the package | ||
/// </summary> | ||
[JsonPropertyName("description")] | ||
public string Description { get; set; } | ||
|
||
/// <summary> | ||
/// packageUrl for this package | ||
/// </summary> | ||
[JsonPropertyName("coordinates")] | ||
public string Coordinates { get; set; } | ||
|
||
/// <summary> | ||
/// Component Details Reference | ||
/// </summary> | ||
[JsonPropertyName("reference")] | ||
public string Reference { get; set; } | ||
|
||
[JsonPropertyName("vulnerabilities")] | ||
public ComponentReportVulnerability[] Vulnerabilities { get; set; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
namespace NuGetDefense.OSSIndex | ||
{ | ||
public class ComponentReportRequest | ||
{ | ||
public string[] coordinates { get; set; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
using System.Text.Json.Serialization; | ||
|
||
namespace NuGetDefense.OSSIndex | ||
{ | ||
/// <summary> | ||
/// Vulnerability report for a specific package | ||
/// </summary> | ||
public class ComponentReportVulnerability | ||
{ | ||
/// <summary> | ||
/// public identifier | ||
/// </summary> | ||
[JsonPropertyName("id")] | ||
public string Id { get; set; } | ||
|
||
/// <summary> | ||
/// Vulnerability Title | ||
/// </summary> | ||
[JsonPropertyName("title")] | ||
public string Title { get; set; } | ||
|
||
/// <summary> | ||
/// Vulnerability Description | ||
/// </summary> | ||
[JsonPropertyName("description")] | ||
public string Description { get; set; } | ||
|
||
/// <summary> | ||
/// CVSS score (https://en.wikipedia.org/wiki/Common_Vulnerability_Scoring_System) | ||
/// </summary> | ||
[JsonPropertyName("cvssScore")] | ||
public float CvssScore { get; set; } | ||
|
||
/// <summary> | ||
/// CVSS vector | ||
/// </summary> | ||
[JsonPropertyName("cvssVector")] | ||
public string CvssVector { get; set; } | ||
|
||
/// <summary> | ||
/// Common Weakness Enumeration | ||
/// </summary> | ||
/// <returns></returns> | ||
[JsonPropertyName("cwe")] | ||
public string Cwe { get; set; } | ||
|
||
/// <summary> | ||
/// Common Vulnerability Enumeration | ||
/// </summary> | ||
[JsonPropertyName("cve")] | ||
public string Cve { get; set; } | ||
|
||
/// <summary> | ||
/// Vulnerability details reference | ||
/// </summary> | ||
[JsonPropertyName("reference")] | ||
public string Reference { get; set; } | ||
|
||
/// <summary> | ||
/// Affected version ranges | ||
/// </summary> | ||
/// <returns></returns> | ||
[JsonPropertyName("versionRanges")] | ||
public string[] VersionRanges { get; set; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Net.Http; | ||
using System.Net.Http.Headers; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
using System.Text.Json; | ||
|
||
namespace NuGetDefense.OSSIndex | ||
{ | ||
|
||
/// <summary> | ||
/// Handles interaction with the OSS Index Rest API (https://ossindex.sonatype.org/doc/rest) | ||
/// </summary> | ||
public static class RestApi | ||
{ | ||
private const string ResponseContentType = "application/vnd.ossindex.component-report.v1+json"; | ||
private const string RequestContentType = "application/vnd.ossindex.component-report-request.v1+json"; | ||
|
||
|
||
/// <summary> | ||
/// Gets vulnerabilities for a single NuGet Package. | ||
/// </summary> | ||
/// <param name="pkg">NuGetPackage to check</param> | ||
/// <returns></returns> | ||
private static async Task<ComponentReport> GetReportForPackageAsync(NuGetPackage pkg) | ||
{ | ||
using (var client = new HttpClient()) | ||
{ | ||
client.DefaultRequestHeaders.Accept.Clear(); | ||
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(ResponseContentType)); | ||
var response = await client.GetStringAsync($"https://ossindex.sonatype.org/api/v3/component-report/{pkg.PackageUrl}"); | ||
return JsonSerializer.Deserialize<ComponentReport>(response, new JsonSerializerOptions()); | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Gets Vulnerabilities for a set of NuGet Packages | ||
/// </summary> | ||
/// <param name="pkgs"> Packages to Check</param> | ||
/// <returns></returns> | ||
private static async Task<ComponentReport[]> GetReportsForPackagesAsync(NuGetPackage[] pkgs) | ||
{ | ||
using var client = new HttpClient(); | ||
var content = JsonSerializer.Serialize(new ComponentReportRequest(){ coordinates = pkgs.Select(p => p.PackageUrl).ToArray()}); | ||
client.DefaultRequestHeaders.Accept.Clear(); | ||
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(ResponseContentType)); | ||
var response = await client | ||
.PostAsync("https://ossindex.sonatype.org/api/v3/component-report", | ||
new StringContent(content, Encoding.UTF8, RequestContentType)); | ||
return await JsonSerializer.DeserializeAsync<ComponentReport[]>(response.Content.ReadAsStreamAsync().Result, new JsonSerializerOptions()); | ||
} | ||
|
||
/// <summary> | ||
/// Gets vulnerabilities for a single NuGet Package | ||
/// </summary> | ||
/// <param name="pkg">NuGetPAckage to check</param> | ||
/// <returns></returns> | ||
public static ComponentReportVulnerability[] GetVulnerabilitiesForPackage(NuGetPackage pkg) | ||
{ | ||
return GetReportForPackageAsync(pkg).Result.Vulnerabilities; | ||
} | ||
|
||
/// <summary> | ||
/// Gets Vulnerabilities for a set of NuGet Packages | ||
/// </summary> | ||
/// <param name="pkgs"> Packages to Check</param> | ||
/// <returns></returns> | ||
public static IEnumerable<ComponentReport> GetVulnerabilitiesForPackages(NuGetPackage[] pkgs) | ||
{ | ||
return GetReportsForPackagesAsync(pkgs).Result.Where(report => report.Vulnerabilities.Length > 0); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Globalization; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Text.Json; | ||
using System.Xml; | ||
using System.Xml.Linq; | ||
using NuGetDefense.OSSIndex; | ||
|
||
namespace NuGetDefense | ||
{ | ||
class Program | ||
{ | ||
/// <summary> | ||
/// args[0] is expected to be the path to the project file. | ||
/// </summary> | ||
/// <param name="args"></param> | ||
static void Main(string[] args) | ||
{ | ||
var exitCode = 0; | ||
var pkgConfig = Path.Combine(Path.GetDirectoryName(args[0]), "packages.config"); | ||
var pkgs = LoadPackages(File.Exists(pkgConfig) ? pkgConfig : args[0]); | ||
|
||
var reports = OSSIndex.RestApi.GetVulnerabilitiesForPackages(pkgs).ToArray(); | ||
foreach (var report in reports) | ||
{ | ||
var StdErrWriter = Console.Error; | ||
var pkg = pkgs.First(p => p.PackageUrl == report.Coordinates); | ||
Console.WriteLine("*************************************"); | ||
//Plan to use Warning: for warnings later | ||
//Plan to combine messages into a single Console.Write. | ||
StdErrWriter.WriteLine($"{args[0]}({pkg.LineNumber},{pkg.LinePosition}) : Error : Vulnerabilities found for {pkg.Id} @ {pkg.Version}"); | ||
Console.WriteLine($"Description: {report.Description}"); | ||
Console.WriteLine($"Reference: {report.Reference}"); | ||
foreach (var vulnerability in report.Vulnerabilities) | ||
{ | ||
exitCode++; | ||
Console.WriteLine($"Title: {vulnerability.Title}"); | ||
Console.WriteLine($"Description: {vulnerability.Description}"); | ||
Console.WriteLine($"Id: {vulnerability.Id}"); | ||
Console.WriteLine($"CVE: {vulnerability.Cve}"); | ||
Console.WriteLine($"CWE: {vulnerability.Cwe}"); | ||
Console.WriteLine($"CVSS Score: {vulnerability.CvssScore.ToString(CultureInfo.InvariantCulture)}"); | ||
Console.WriteLine($"CVSS Vector: {vulnerability.CvssVector}"); | ||
if(vulnerability.VersionRanges?.Length > 0)Console.Error.WriteLine($"Affected Versions: {vulnerability.VersionRanges}"); | ||
Console.WriteLine("---------------------------"); | ||
} | ||
} | ||
} | ||
|
||
|
||
/// <summary> | ||
/// Loads NuGet packages in use form packages.config or PackageReferences in the project file | ||
/// </summary> | ||
/// <returns></returns> | ||
public static NuGetPackage[] LoadPackages(string packageSource) | ||
{ | ||
if(Path.GetFileName(packageSource) == "packages.config") | ||
{ | ||
return XElement.Load(packageSource, LoadOptions.SetLineInfo).DescendantsAndSelf("package").Select(x => new NuGetPackage() | ||
{Id = x.Attribute("id").Value, Version = x.Attribute("version").Value, LineNumber = ((IXmlLineInfo)x).LineNumber, LinePosition = ((IXmlLineInfo)x).LinePosition}).ToArray(); | ||
} | ||
|
||
return XElement.Load(packageSource, LoadOptions.SetLineInfo).DescendantsAndSelf("PackageReference").Select(x => new NuGetPackage() | ||
{Id = x.Attribute("Include").Value, Version = x.Attribute("Version").Value, LineNumber = ((IXmlLineInfo)x).LineNumber, LinePosition = ((IXmlLineInfo)x).LinePosition}).ToArray(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<packages> | ||
<package id="jQuery" version="1.5.1" /> | ||
<package id="EntityFramework.SqlServerCompact" version="4.1.8482.2" /> | ||
<package id="AntiXss" version="4.0.1" /> | ||
<package id="Microsoft.Data.OData" version="5.7.2" /> | ||
</packages> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<Project> | ||
<PropertyGroup> | ||
<!-- <NuGetDefenseExe Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework'">"$(MSBuildThisFileDirectory)/net46/NuGetDefense.exe"</TsGenFileExe> --> | ||
<!-- <NuGetDefenseExe Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp' OR '$(TargetFrameworkIdentifier)' == '.NETStandard'">dotnet "$(MSBuildThisFileDirectory)/netcoreapp3.1/NuGetDefense.dll"</TsGenFileExe> --> | ||
<NuGetDefenseExe>$(MSBuildThisFileDirectory)../tools/netcoreapp3.1/NuGetDefense</NuGetDefenseExe> | ||
</PropertyGroup> | ||
|
||
<Target Name="CheckForVulnerableNuGetPkgs" AfterTargets="Build"> | ||
<Exec Command="$(NuGetDefenseExe) $(MSBuildProjectFullPath)" IgnoreExitCode="true" /> | ||
</Target> | ||
</Project> |
Empty file.
Empty file.
Empty file.