/// <summary> /// Main entrypoint for the download program. /// </summary> /// <param name="args"> parameters passed in from the user </param> private static async Task Main(string[] args) { ShowToolBanner(); CharacteristicTool?characteristicTool = new CharacteristicTool(); await characteristicTool.ParseOptions <Options>(args).WithParsedAsync(characteristicTool.RunAsync); }
/// <summary> /// Main entrypoint for the download program. /// </summary> /// <param name="args">parameters passed in from the user</param> static async Task Main(string[] args) { var detectBackdoorTool = new DetectBackdoorTool(); Logger.Debug($"Microsoft OSS Gadget - {TOOL_NAME} {VERSION}"); detectBackdoorTool.ParseOptions(args); if (((IList <string>)detectBackdoorTool.Options["target"]).Count > 0) { var characteristicTool = new CharacteristicTool(); characteristicTool.Options["target"] = detectBackdoorTool.Options["target"]; characteristicTool.Options["disable-default-rules"] = true; characteristicTool.Options["custom-rule-directory"] = RULE_DIRECTORY; foreach (var target in (IList <string>)detectBackdoorTool.Options["target"]) { try { var purl = new PackageURL(target); characteristicTool.AnalyzePackage(purl).Wait(); } catch (Exception ex) { Logger.Warn(ex, "Error processing {0}: {1}", target, ex.Message); } } } else { Logger.Warn("No target provided; nothing to analyze."); DetectBackdoorTool.ShowUsage(); Environment.Exit(1); } }
/// <summary> /// Main entrypoint for the download program. /// </summary> /// <param name="args">parameters passed in from the user</param> static void Main(string[] args) { var characteristicTool = new CharacteristicTool(); Logger.Debug($"Microsoft OSS Gadget - {TOOL_NAME} {VERSION}"); characteristicTool.ParseOptions(args); if (((IList <string>)characteristicTool.Options["target"]).Count > 0) { foreach (var target in (IList <string>)characteristicTool.Options["target"]) { try { var purl = new PackageURL(target); characteristicTool.AnalyzePackage(purl).Wait(); } catch (Exception ex) { Logger.Warn(ex, "Error processing {0}: {1}", target, ex.Message); } } } else { Logger.Warn("No target provided; nothing to analyze."); CharacteristicTool.ShowUsage(); Environment.Exit(1); } }
/// <summary> /// Calculates project risk based on health and characteristics. /// </summary> /// <param name="purl">Package URL to load</param> /// <param name="targetDirectory">Target directory to download content to (default: temporary location)</param> /// <param name="doCaching">Cache the project for later processing (default: false)</param> /// <returns></returns> public async Task <double> CalculateRisk(PackageURL purl, string?targetDirectory, bool doCaching = false, bool checkHealth = true) { Logger.Trace("CalculateRisk({0})", purl.ToString()); CharacteristicTool?characteristicTool = new CharacteristicTool(ProjectManagerFactory); CharacteristicTool.Options? cOptions = new CharacteristicTool.Options(); Dictionary <string, AnalyzeResult?>?characteristics = characteristicTool.AnalyzePackage(cOptions, purl, targetDirectory, doCaching).Result; double aggregateRisk = 0.0; if (checkHealth) { HealthTool? healthTool = new HealthTool(ProjectManagerFactory); HealthMetrics?healthMetrics = await healthTool.CheckHealth(purl); if (healthMetrics == null) { Logger.Warn("Unable to determine health metrics, will use a default of 0."); healthMetrics = new HealthMetrics(purl) { SecurityIssueHealth = 0, CommitHealth = 0, ContributorHealth = 0, IssueHealth = 0, ProjectSizeHealth = 0, PullRequestHealth = 0, RecentActivityHealth = 0, ReleaseHealth = 0 }; } Logger.Trace("Health Metrics:\n{}", healthMetrics); // Risk calculation algorithm: Weight each of the health scores. aggregateRisk = 1.0 - ( 5.0 * healthMetrics.SecurityIssueHealth / 100.0 + 1.0 * healthMetrics.CommitHealth / 100.0 + 3.0 * healthMetrics.IssueHealth / 100.0 + 2.0 * healthMetrics.PullRequestHealth / 100.0 + 0.25 * healthMetrics.RecentActivityHealth / 100.0 + 1.0 * healthMetrics.ContributorHealth / 100.0 ) / 12.25; Logger.Trace("Aggregate Health Risk: {}", aggregateRisk); } string[]? highRiskTags = new string[] { "Cryptography.", "Authentication.", "Authorization.", "Data.Deserialization." }; Dictionary <string, int>?highRiskTagsSeen = new Dictionary <string, int>(); foreach (AnalyzeResult?analyzeResult in characteristics.Values) { foreach (MatchRecord?match in analyzeResult?.Metadata?.Matches ?? new List <MatchRecord>()) { foreach (string?tag in match.Tags ?? Array.Empty <string>()) { foreach (string?highRiskTag in highRiskTags) { if (tag.StartsWith(highRiskTag)) { if (!highRiskTagsSeen.ContainsKey(highRiskTag)) { highRiskTagsSeen[highRiskTag] = 0; } highRiskTagsSeen[highRiskTag]++; } } } } } if (Logger.IsTraceEnabled) { Logger.Trace("Found {} high-risk tags over {} categories.", highRiskTagsSeen.Values.Sum(), highRiskTagsSeen.Keys.Count()); } double highRiskTagRisk = ( 0.4 * highRiskTagsSeen.Keys.Count() + 0.6 * Math.Min(highRiskTagsSeen.Values.Sum(), 5) ); highRiskTagRisk = highRiskTagRisk > 1.0 ? 1.0 : highRiskTagRisk; aggregateRisk = ( 0.7 * aggregateRisk + 0.7 * highRiskTagRisk ); aggregateRisk = aggregateRisk > 1.0 ? 1.0 : aggregateRisk; Logger.Trace("Final Risk: {}", aggregateRisk); return(aggregateRisk); }