293 lines
12 KiB
C#
293 lines
12 KiB
C#
<Query Kind="Program">
|
|
<Reference><ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll</Reference>
|
|
<NuGetReference>Amazon.Lambda.S3Events</NuGetReference>
|
|
<NuGetReference>AWSSDK.Core</NuGetReference>
|
|
<NuGetReference>AWSSDK.S3</NuGetReference>
|
|
<Namespace>Amazon</Namespace>
|
|
<Namespace>Amazon.Auth.AccessControlPolicy</Namespace>
|
|
<Namespace>Amazon.Auth.AccessControlPolicy.ActionIdentifiers</Namespace>
|
|
<Namespace>Amazon.Internal</Namespace>
|
|
<Namespace>Amazon.Lambda.S3Events</Namespace>
|
|
<Namespace>Amazon.MissingTypes</Namespace>
|
|
<Namespace>Amazon.Runtime</Namespace>
|
|
<Namespace>Amazon.Runtime.CredentialManagement</Namespace>
|
|
<Namespace>Amazon.Runtime.CredentialManagement.Internal</Namespace>
|
|
<Namespace>Amazon.Runtime.EventStreams</Namespace>
|
|
<Namespace>Amazon.Runtime.EventStreams.Internal</Namespace>
|
|
<Namespace>Amazon.Runtime.Internal</Namespace>
|
|
<Namespace>Amazon.Runtime.Internal.Auth</Namespace>
|
|
<Namespace>Amazon.Runtime.Internal.Settings</Namespace>
|
|
<Namespace>Amazon.Runtime.Internal.Transform</Namespace>
|
|
<Namespace>Amazon.Runtime.Internal.Util</Namespace>
|
|
<Namespace>Amazon.Runtime.SharedInterfaces</Namespace>
|
|
<Namespace>Amazon.Runtime.SharedInterfaces.Internal</Namespace>
|
|
<Namespace>Amazon.S3</Namespace>
|
|
<Namespace>Amazon.S3.Encryption</Namespace>
|
|
<Namespace>Amazon.S3.Encryption.Internal</Namespace>
|
|
<Namespace>Amazon.S3.Internal</Namespace>
|
|
<Namespace>Amazon.S3.IO</Namespace>
|
|
<Namespace>Amazon.S3.Model</Namespace>
|
|
<Namespace>Amazon.S3.Model.Internal.MarshallTransformations</Namespace>
|
|
<Namespace>Amazon.S3.Transfer</Namespace>
|
|
<Namespace>Amazon.S3.Util</Namespace>
|
|
<Namespace>Amazon.Util</Namespace>
|
|
<Namespace>Amazon.Util.Internal</Namespace>
|
|
<Namespace>Amazon.Util.Internal.PlatformServices</Namespace>
|
|
<Namespace>Newtonsoft.Json</Namespace>
|
|
<Namespace>Newtonsoft.Json.Converters</Namespace>
|
|
<Namespace>Newtonsoft.Json.Linq</Namespace>
|
|
<Namespace>Newtonsoft.Json.Schema</Namespace>
|
|
<Namespace>Newtonsoft.Json.Serialization</Namespace>
|
|
<Namespace>System</Namespace>
|
|
<Namespace>System.ComponentModel.Composition</Namespace>
|
|
<Namespace>System.ComponentModel.Composition.Hosting</Namespace>
|
|
<Namespace>System.ComponentModel.Composition.Primitives</Namespace>
|
|
<Namespace>System.ComponentModel.Composition.ReflectionModel</Namespace>
|
|
<Namespace>System.Diagnostics</Namespace>
|
|
<Namespace>System.Diagnostics.Tracing</Namespace>
|
|
<Namespace>System.IO.Compression</Namespace>
|
|
<Namespace>System.Net.Http</Namespace>
|
|
<Namespace>System.Net.Http.Headers</Namespace>
|
|
<Namespace>System.Numerics</Namespace>
|
|
<Namespace>ThirdParty.BouncyCastle.Asn1</Namespace>
|
|
<Namespace>ThirdParty.BouncyCastle.Asn1.Utilities</Namespace>
|
|
<Namespace>ThirdParty.BouncyCastle.Math</Namespace>
|
|
<Namespace>ThirdParty.BouncyCastle.OpenSsl</Namespace>
|
|
<Namespace>ThirdParty.BouncyCastle.Utilities.IO.Pem</Namespace>
|
|
<Namespace>ThirdParty.Ionic.Zlib</Namespace>
|
|
<Namespace>ThirdParty.Json.LitJson</Namespace>
|
|
<Namespace>ThirdParty.MD5</Namespace>
|
|
</Query>
|
|
|
|
//private string xmlAnalyticsFile = @"C:\Users\tlamb\Downloads\detailedreport_Strata_Jazz_Web_Jazz_web_201911511115217.xml";
|
|
private string xmlAnalyticsFile = @"C:\Users\tlamb\Downloads\detailedreport_Strata_Jazz_Web_Strata_Jazz_Web_201953102954843.xml";
|
|
|
|
public static class IntExtensions
|
|
{
|
|
public static string SeverityLabel(this int severity)
|
|
{
|
|
switch (severity)
|
|
{
|
|
case 5: return "Very High";
|
|
case 4: return "High";
|
|
case 3: return "Medium";
|
|
case 2: return "Low";
|
|
case 1: return "Very Low";
|
|
default: return "Informational";
|
|
}
|
|
}
|
|
}
|
|
|
|
internal class Module
|
|
{
|
|
public string name { get; set; }
|
|
public int score { get; set; }
|
|
public int totalNumberOfFlaws => flawsBySeverity.Values.Sum();
|
|
public int numberOfImportantFlaws => flawsBySeverity.Where(f => f.Key > 2).Select(f => f.Value).Sum();
|
|
private Dictionary<int, int> flawsBySeverity { get; set; }
|
|
public string flawsSummary => totalNumberOfFlaws > 0
|
|
? flawsBySeverity.Where(f => f.Value > 0).OrderByDescending(f => f.Key).Aggregate(new StringBuilder("Severity\n"), (x, y) =>
|
|
x.Append($"{y.Key.SeverityLabel()}: {y.Value}\r\n")).ToString().TrimEnd(new[] { '\r', '\n' })
|
|
: "";
|
|
public IEnumerable<ModuleFlaw> flaws { get; set; }
|
|
public string flawList => !flaws.Any()
|
|
? "" : flaws.Aggregate(new StringBuilder("path\tfile\tline\ttype\n"), (x, y) =>
|
|
x.AppendLine($"{(string.IsNullOrEmpty(y.sourcefile) ? "na" : Path.GetDirectoryName(y.sourcefile))}\t"
|
|
+ $"{(string.IsNullOrEmpty(y.sourcefile) ? "na" : Path.GetFileName(y.sourcefile))}\t{y.line}\t{y.type}")).ToString();
|
|
|
|
public Module(XElement module, IEnumerable<Cwe> cwes)
|
|
{
|
|
name = module.Attribute("name")?.Value;
|
|
score = Convert.ToInt32(module.Attribute("score")?.Value ?? "0");
|
|
flawsBySeverity = new Dictionary<int, int>();
|
|
flawsBySeverity[0] = Convert.ToInt32(module.Attribute("numflawssev0")?.Value ?? "0");
|
|
flawsBySeverity[1] = Convert.ToInt32(module.Attribute("numflawssev1")?.Value ?? "0");
|
|
flawsBySeverity[2] = Convert.ToInt32(module.Attribute("numflawssev2")?.Value ?? "0");
|
|
flawsBySeverity[3] = Convert.ToInt32(module.Attribute("numflawssev3")?.Value ?? "0");
|
|
flawsBySeverity[4] = Convert.ToInt32(module.Attribute("numflawssev4")?.Value ?? "0");
|
|
flawsBySeverity[5] = Convert.ToInt32(module.Attribute("numflawssev5")?.Value ?? "0");
|
|
var cx = cwes.Where(c => c.details.Any(d => d.module.Equals(name, StringComparison.CurrentCultureIgnoreCase)));
|
|
flaws = cx.SelectMany(c => c.details.Where(d => d.module.Equals(name, StringComparison.CurrentCultureIgnoreCase))
|
|
.Select(d => new ModuleFlaw(d)))
|
|
//.GroupBy(d => $"{d.type}{d.sourcefile}{d.line}").Select(grp => grp.First())
|
|
.OrderBy(grp => grp.sourcefile).ThenBy(grp => grp.line).ThenBy(grp => grp.type);
|
|
}
|
|
}
|
|
|
|
internal class ModuleFlaw
|
|
{
|
|
public string type { get; set; }
|
|
public string sourcefile { get; set; }
|
|
public int line { get; set; }
|
|
public bool hasMitigations { get; set; }
|
|
|
|
public ModuleFlaw(XElement element)
|
|
{
|
|
hasMitigations = element.Descendants().Any(sfd => sfd.Name.LocalName == "mitigations");
|
|
var regex = new Regex(@"\.!newinit_0_[0-9]|mscorlib_dll|system_xml_dll|system_web_dll|system_data_dll|system_directoryservices_dll|system_dll\.");
|
|
type = regex.Replace(element.Attribute("type")?.Value, "").Trim(new[] { '.' });
|
|
sourcefile = System.IO.Path.Combine((element.Attribute("sourcefilepath")?.Value ?? "").Replace("/jazz new", ""),
|
|
element.Attribute("sourcefile")?.Value ?? "");
|
|
line = Convert.ToInt32(element.Attribute("line")?.Value ?? "0");
|
|
}
|
|
|
|
public ModuleFlaw(Flaw flaw)
|
|
{
|
|
hasMitigations = flaw.hasMitigations;
|
|
type = flaw.type;
|
|
sourcefile = flaw.sourcefile;
|
|
line = flaw.line;
|
|
}
|
|
}
|
|
|
|
internal class Flaw : ModuleFlaw
|
|
{
|
|
public string module { get; set; }
|
|
public string description { get; set; }
|
|
public string grace_period_expires { get; set; }
|
|
public string remediation_status { get; set; }
|
|
public bool remediated => (remediation_status == "Fixed");
|
|
|
|
public Flaw(XElement element)
|
|
: base(element)
|
|
{
|
|
module = string.Join("\r\n", element.Attribute("module")?.Value.Split("/".ToCharArray()));
|
|
description = element.Attribute("description")?.Value;
|
|
DateTime parsedDate;
|
|
var theDate = System.Net.WebUtility.HtmlDecode(element.Attribute("grace_period_expires")?.Value).Replace(" UTC", "Z");
|
|
if (DateTime.TryParse(theDate, out parsedDate))
|
|
{
|
|
grace_period_expires = parsedDate.ToShortDateString();
|
|
}
|
|
else
|
|
{
|
|
grace_period_expires = string.Empty;
|
|
}
|
|
remediation_status = element.Attribute("remediation_status")?.Value;
|
|
}
|
|
|
|
}
|
|
|
|
internal class Cwe
|
|
{
|
|
public int id { get; set; }
|
|
public string category { get; set; }
|
|
public string name { get; set; }
|
|
public int severity { get; set; }
|
|
public int count { get; set; }
|
|
public string recommendation { get; set; }
|
|
public IEnumerable<Flaw> details { get; set; }
|
|
|
|
public Cwe(XElement module)
|
|
{
|
|
var categoryElement = module.Parent;
|
|
var severityElement = categoryElement.Parent;
|
|
severity = Convert.ToInt32(severityElement.Attribute("level")?.Value ?? "0");
|
|
|
|
category = categoryElement.Attribute("categoryname")?.Value ?? "";
|
|
var recommendations = categoryElement.Descendants().Where(d => d.Name.LocalName == "recommendations");
|
|
var content = recommendations.Descendants();
|
|
recommendation = string.Join("\r\n", content.ToList().Select(n => (n.Name.LocalName == "bulletitem" ? "- " : "") + n.Attribute("text")?.Value));
|
|
|
|
id = Convert.ToInt32(module.Attribute("cweid").Value);
|
|
name = module.Attribute("cwename").Value;
|
|
|
|
var staticFlaws = module.XPathSelectElements("./*").Where(m => m.Name.LocalName == "staticflaws");
|
|
var flaws = (staticFlaws.SelectMany(m => m.XPathSelectElements("./*").Where(sf => sf.Name.LocalName == "flaw")))?.ToList()
|
|
.Select(f => new Flaw(f));
|
|
//.GroupBy(grp => new { grp.module, grp.type, grp.description })
|
|
//.Select(x => x.First());
|
|
|
|
details = flaws
|
|
//.Where(f => !f.hasMitigations)
|
|
.OrderBy(d => d.type).ThenBy(d => d.module).ThenBy(d => d.description);
|
|
|
|
count = details.Count();
|
|
}
|
|
}
|
|
|
|
internal IEnumerable<Cwe> ParseVeracodeReport(XDocument xmlDoc)
|
|
{
|
|
return from module in xmlDoc.Descendants()
|
|
where module.Name.LocalName == "cwe"
|
|
&& module.Attributes().Any(a => a.Name == "cweid")
|
|
orderby Int32.Parse(module.Attribute("cweid").Value)
|
|
select new Cwe(module);
|
|
}
|
|
|
|
void Main()
|
|
{
|
|
XDocument xmlDoc = XDocument.Load(xmlAnalyticsFile);
|
|
//xmlDoc.DumpFormatted();
|
|
var cwes = ParseVeracodeReport(xmlDoc).Where(cwe => cwe.count > 0);
|
|
cwes
|
|
.SelectMany(c => c.details.Select(d => new
|
|
{
|
|
c.severity,
|
|
c.category,
|
|
c.id,
|
|
c.name,
|
|
d.type,
|
|
d.sourcefile,
|
|
line = d.line.ToString(),
|
|
d.hasMitigations,
|
|
d.module,
|
|
d.grace_period_expires,
|
|
d.remediation_status,
|
|
d.remediated
|
|
}))
|
|
.Where(c => !c.remediated)
|
|
.OrderByDescending(c => c.severity).ThenBy(c => c.category).ThenBy(c => c.module).ThenBy(c => c.sourcefile).ThenBy(c => c.type).ThenBy(c => c.line)
|
|
.GroupBy(c => new
|
|
{
|
|
Severity = c.severity.SeverityLabel(),
|
|
Category = c.category,
|
|
CWE_Id = c.id.ToString(),
|
|
Description = c.name
|
|
}, (key, group) => new
|
|
{
|
|
Severity = key,
|
|
Items = group.ToList().Select(g => new
|
|
{
|
|
g.type,
|
|
g.sourcefile,
|
|
g.line,
|
|
g.hasMitigations,
|
|
g.module,
|
|
g.grace_period_expires
|
|
})
|
|
})
|
|
.Dump();
|
|
// cwes.SelectMany(c => c.details.Select(d => new { c.category, c.name, d.type, d.sourcefile, line = d.line.ToString(), d.hasMitigations, d.module }))
|
|
// .Where(c => c.module.Contains(".dss."))
|
|
// .OrderBy(c => c.module).ThenBy(c => c.category).ThenBy(c => c.sourcefile).ThenBy(c => c.type).ThenBy(c => c.line)
|
|
// .Dump();
|
|
// cwes.Where(cwe => cwe.count > 1)
|
|
// .OrderByDescending(cwe => cwe.severity).ThenByDescending(cwe => cwe.count)
|
|
// .Select(cwe => new
|
|
// {
|
|
// severity = cwe.severity.SeverityLabel(),
|
|
// category_id = $"{cwe.category} ({cwe.id})",
|
|
// wo_Tests = cwe.count,
|
|
// cwe.name,
|
|
// cwe.recommendation })
|
|
// .Dump($"Summary: ({cwes.Where(cwe => cwe.count > 1).Count()})");
|
|
//
|
|
// var regex = new Regex(@"\.Test\.|\.IntegrationTests\.|\.UnitTests\.");
|
|
// var modules = from m in xmlDoc.Descendants()
|
|
// where m.Name.LocalName == "module" && m.Parent.Name.LocalName == "modules"
|
|
// select new Module(m, cwes);
|
|
// modules.Where(m => !regex.IsMatch(m.name) && m.totalNumberOfFlaws > 0)
|
|
// .Select(m => new {m.name, m.score, m.totalNumberOfFlaws, m.numberOfImportantFlaws, m.flawsSummary, m.flawList})
|
|
// .Dump($"Modules: ({modules.Count(m => !regex.IsMatch(m.name) && m.totalNumberOfFlaws > 0)})");
|
|
//
|
|
// modules.Where(m => !regex.IsMatch(m.name) && m.totalNumberOfFlaws > 0
|
|
// && new [] {"Strata.CS.Jazz.Biz.DSS.Episodes.EpisodeDefinition.dll","Strata.CS.Jazz.Biz.DSS.Episodes.dll","Strata.Administrator.Base.dll"}.Contains(m.name))
|
|
// .Select(m => new { m.name, m.flaws })
|
|
// .Dump($"Module Flaws: ({modules.Count(m => !regex.IsMatch(m.name) && m.totalNumberOfFlaws > 0)})");
|
|
//
|
|
// cwes.Where(cwe => cwe.count > 1)
|
|
// .OrderBy(cwe => cwe.id).ToList()
|
|
// .ForEach(cwe => cwe.details.Dump($"ID: {cwe.id} {cwe.name} ({cwe.count})"));
|
|
// //JsonConvert.SerializeObject(cwes, Newtonsoft.Json.Formatting.Indented).Dump("Json");
|
|
} |