public async Task Check_Sarif(string purl, string targetResult) { // for initialization FindSourceTool tool = new FindSourceTool(); RepoSearch searchTool = new RepoSearch(); var results = await searchTool.ResolvePackageLibraryAsync(new PackageURL(purl)); List <Result> sarifResults = new List <Result>(); foreach (var result in results) { var confidence = result.Value * 100.0; Result sarifResult = new Result() { Message = new Message() { Text = $"https://github.com/{result.Key.Namespace}/{result.Key.Name}" }, Kind = ResultKind.Informational, Level = FailureLevel.None, Rank = confidence, Locations = SarifOutputBuilder.BuildPurlLocation(new PackageURL(purl)) }; sarifResults.Add(sarifResult); } IOutputBuilder outputBuilder = OutputBuilderFactory.CreateOutputBuilder("sarifv2"); outputBuilder.AppendOutput(sarifResults); string sarifJSON = outputBuilder.GetOutput(); SarifLog sarif = JsonConvert.DeserializeObject <SarifLog>(sarifJSON); Assert.IsNotNull(sarif); var sarifRun = sarif.Runs.FirstOrDefault(); Assert.IsNotNull(sarifRun?.Tool.Driver.Name); // make sure atleast one of the result repos match the actual one bool found = false; if (sarifRun != null) { foreach (var result in sarifRun.Results) { if (result.Message.Text == targetResult) { found = true; } } } Assert.IsTrue(found); }
/// <summary> /// Build and return a list of Sarif Result list from the find characterstics results /// </summary> /// <param name="purl"> </param> /// <param name="results"> </param> /// <returns> </returns> private static List <SarifResult> GetSarifResults(PackageURL purl, double riskLevel) { List <SarifResult> sarifResults = new List <SarifResult>(); SarifResult sarifResult = new SarifResult() { Kind = ResultKind.Informational, Level = FailureLevel.None, Locations = SarifOutputBuilder.BuildPurlLocation(purl), Rank = riskLevel }; sarifResults.Add(sarifResult); return(sarifResults); }
public List <Result> toSarif() { BaseProjectManager?projectManager = ProjectManagerFactory.CreateProjectManager(purl, null); if (projectManager == null) { Logger.Error("Cannot determine the package type"); return(new List <Result>()); } Normalize(); List <Result> results = new List <Result>(); var properties = getHealthProperties(); foreach (var property in properties.OrderBy(s => s.Name)) { if (property.Name.EndsWith("Health")) { var textualName = Regex.Replace(property.Name, "(\\B[A-Z])", " $1"); var value = Convert.ToDouble(property.GetValue(this)); Result healthResult = new Result() { Kind = ResultKind.Review, Level = FailureLevel.None, Message = new Message() { Text = textualName }, Rank = value, Locations = SarifOutputBuilder.BuildPurlLocation(purl) }; results.Add(healthResult); } } return(results); }
/// <summary> /// Build and return a list of Sarif Result list from the find source results /// </summary> /// <param name="purl"> </param> /// <param name="results"> </param> /// <returns> </returns> private static List <Result> GetSarifResults(PackageURL purl, List <KeyValuePair <PackageURL, double> > results) { List <Result> sarifResults = new List <Result>(); foreach (var result in results) { var confidence = result.Value * 100.0; Result sarifResult = new Result() { Message = new Message() { Text = $"https://github.com/{result.Key.Namespace}/{result.Key.Name}" }, Kind = ResultKind.Informational, Level = FailureLevel.None, Rank = confidence, Locations = SarifOutputBuilder.BuildPurlLocation(purl) }; sarifResults.Add(sarifResult); } return(sarifResults); }
/// <summary> /// Build and return a list of Sarif Result list from the find characterstics results /// </summary> /// <param name="purl"> </param> /// <param name="results"> </param> /// <returns> </returns> private static List <SarifResult> GetSarifResults(PackageURL purl, Dictionary <string, AnalyzeResult?> analysisResult, Options opts) { List <SarifResult> sarifResults = new List <SarifResult>(); if (analysisResult.HasAtLeastOneNonNullValue()) { foreach (string?key in analysisResult.Keys) { MetaData?metadata = analysisResult?[key]?.Metadata; foreach (MatchRecord?result in metadata?.Matches ?? new List <MatchRecord>()) { SarifResult?individualResult = new SarifResult() { Message = new Message() { Text = result.RuleDescription, Id = result.RuleId }, Kind = ResultKind.Informational, Level = opts.SarifLevel, Locations = SarifOutputBuilder.BuildPurlLocation(purl), Rule = new ReportingDescriptorReference() { Id = result.RuleId }, }; individualResult.SetProperty("Severity", result.Severity); individualResult.SetProperty("Confidence", result.Confidence); individualResult.Locations.Add(new CodeAnalysis.Sarif.Location() { PhysicalLocation = new PhysicalLocation() { Address = new Address() { FullyQualifiedName = result.FileName }, Region = new Region() { StartLine = result.StartLocationLine, EndLine = result.EndLocationLine, StartColumn = result.StartLocationColumn, EndColumn = result.EndLocationColumn, SourceLanguage = result.Language, Snippet = new ArtifactContent() { Text = result.Excerpt, Rendered = new MultiformatMessageString(result.Excerpt, $"`{result.Excerpt}`", null) } } } }); sarifResults.Add(individualResult); } } } return(sarifResults); }
public async Task <(string output, int numSquats)> RunAsync(Options options) { IOutputBuilder outputBuilder = SelectFormat(options.Format); var foundSquats = 0; foreach (var target in options.Targets ?? Array.Empty <string>()) { var purl = new PackageURL(target); if (purl.Name is not null && purl.Type is not null) { var manager = ProjectManagerFactory.CreateProjectManager(purl, null); if (manager is not null) { var mutationsDict = gen.Mutate(purl.Name); foreach ((var candidate, var rules) in mutationsDict) { if (options.SleepDelay > 0) { Thread.Sleep(options.SleepDelay); } // Nuget will match "microsoft.cst.oat." against "Microsoft.CST.OAT" but these are the same package // For nuget in particular we filter out this case if (manager is NuGetProjectManager) { if (candidate.EndsWith('.')) { if (candidate.Equals($"{purl.Name}.", StringComparison.InvariantCultureIgnoreCase)) { continue; } } } var candidatePurl = new PackageURL(purl.Type, candidate); try { var versions = await manager.EnumerateVersions(candidatePurl); if (versions.Any()) { foundSquats++; if (!options.Quiet) { Logger.Info($"{candidate} package exists. Potential squat. {JsonConvert.SerializeObject(rules)}"); } if (outputBuilder is SarifOutputBuilder sarob) { SarifResult sarifResult = new SarifResult() { Message = new Message() { Text = $"Potential Squat candidate { candidate }.", Id = "oss-find-squats" }, Kind = ResultKind.Review, Level = FailureLevel.None, Locations = SarifOutputBuilder.BuildPurlLocation(candidatePurl), }; foreach (var tag in rules) { sarifResult.Tags.Add(tag); } sarob.AppendOutput(new SarifResult[] { sarifResult }); } else if (outputBuilder is StringOutputBuilder strob) { var rulesString = string.Join(',', rules); strob.AppendOutput(new string[] { $"Potential Squat candidate '{ candidate }' detected. Generated by { rulesString }.{Environment.NewLine}" }); } else { var rulesString = string.Join(',', rules); if (!options.Quiet) { Logger.Info($"Potential Squat candidate '{ candidate }' detected. Generated by { rulesString }."); } } } } catch (Exception e) { Logger.Trace($"Could not enumerate versions. Package {candidate} likely doesn't exist. {e.Message}:{e.StackTrace}"); } } } } } return(outputBuilder.GetOutput(), foundSquats); }
public async Task <(string output, int numSquats)> RunAsync(Options options) { IOutputBuilder?outputBuilder = SelectFormat(options.Format); int foundSquats = 0; MutateOptions? checkerOptions = new() { SleepDelay = options.SleepDelay }; foreach (string?target in options.Targets ?? Array.Empty <string>()) { PackageURL?purl = new(target); if (purl.Name is null || purl.Type is null) { Logger.Trace($"Could not generate valid PackageURL from { target }."); continue; } FindPackageSquats findPackageSquats = new FindPackageSquats(ProjectManagerFactory, purl); IDictionary <string, IList <Mutation> >?potentialSquats = findPackageSquats.GenerateSquatCandidates(options: checkerOptions); await foreach (FindPackageSquatResult? potentialSquat in findPackageSquats.FindExistingSquatsAsync(potentialSquats, checkerOptions)) { foundSquats++; if (!options.Quiet) { Logger.Info($"{potentialSquat.MutatedPackageName} package exists. Potential squat. {JsonConvert.SerializeObject(potentialSquat.Rules)}"); } if (outputBuilder is SarifOutputBuilder sarob) { SarifResult?sarifResult = new() { Message = new Message() { Text = $"Potential Squat candidate { potentialSquat.MutatedPackageName }.", Id = "oss-find-squats" }, Kind = ResultKind.Review, Level = FailureLevel.None, Locations = SarifOutputBuilder.BuildPurlLocation(potentialSquat.MutatedPackageUrl), }; foreach (string?tag in potentialSquat.Rules) { sarifResult.Tags.Add(tag); } sarob.AppendOutput(new SarifResult[] { sarifResult }); } else if (outputBuilder is StringOutputBuilder strob) { string?rulesString = string.Join(',', potentialSquat.Rules); strob.AppendOutput(new string[] { $"Potential Squat candidate '{ potentialSquat.MutatedPackageName }' detected. Generated by { rulesString }.{Environment.NewLine}" }); } else { string?rulesString = string.Join(',', potentialSquat.Rules); if (!options.Quiet) { Logger.Info($"Potential Squat candidate '{ potentialSquat.MutatedPackageName }' detected. Generated by { rulesString }."); } } } } return(outputBuilder.GetOutput(), foundSquats); } }