Files
linqpad/Veracode/Veracode CWE Analytics.linq
T

387 lines
14 KiB
C#

<Query Kind="Program">
<Reference>&lt;ProgramFilesX64&gt;\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 XDocument xmlDoc = XDocument.Load(@"C:\Users\tlamb\Downloads\detailedreport_Strata_Jazz_Web_Jazz_web_201911511115217.xml");
void Main()
{
//xmlDoc.DumpFormatted();
var cwes = ParseVeracodeReport(xmlDoc).Where(cwe => cwe.count > 0);
var flaws = (from cwe in xmlDoc.Descendants()
where cwe.Name.LocalName == "cwe"
&& cwe.Attributes().Any(a => a.Name == "cweid")
orderby Int32.Parse(cwe.Attribute("cweid").Value)
select cwe.Descendants().Where(c => c.Name.LocalName == "flaw"));
flaws
.SelectMany(f => f.Select(x => new Flaw(x)))
.Where(x => new[] { 4, 5 }.Contains(x.severity) && !x.hasMitigations && x.remediation_status == "New")
.OrderByDescending(x => x.severity)
.ThenBy(x => x.categoryid)
.ThenBy(x => x.cweid)
.ThenBy(x => x.issueid).Dump();
//DumpTop20(cwes);
// DumpSummary(cwes);
// DumpModules(cwes);
// DumpByCweID(cwes);
}
void DumpTop20(IEnumerable<Cwe> cwes)
{
cwes.Where(cwe => cwe.count > 1 && new[] { 78, 15, 89 }.Contains(cwe.id))
.Select(cwe => new { cwe.severity, cwe.category, cwe.details })
.OrderByDescending(cwe => cwe.severity)
.Dump($"Top 20: ({cwes.Where(cwe => cwe.count > 1).Count()})");
}
void DumpSummary(IEnumerable<Cwe> cwes)
{
cwes.Where(cwe => cwe.count > 1)
.OrderByDescending(cwe => cwe.severity).ThenByDescending(cwe => cwe.count)
.Dump($"Summary: ({cwes.Where(cwe => cwe.count > 1).Count()})");
}
void DumpModules(IEnumerable<Cwe> cwes)
{
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)
.OrderBy(m => m.score).ThenByDescending(m => m.numberOfImportantFlaws)
.Dump($"Modules: ({modules.Count(m => !regex.IsMatch(m.name) && m.totalNumberOfFlaws > 0)})");
}
void DumpByCweID(IEnumerable<Cwe> cwes)
{
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");
}
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);
}
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";
}
}
public static string CategoryLabel(this int category)
{
switch (category)
{
case 18: return "OS Command Injection";
case 19: return "SQL Injections";
case 24: return "Untrusted Initialization";
case 21: return "CRLF Injection";
case 10: return "Credentials Management";
default: return $"{category}";
}
}
}
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 flawsSummaryInfo => 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 List<Severity> summary => totalNumberOfFlaws > 0
? flawsBySeverity.Where(f => f.Value > 0)
.OrderByDescending(f => f.Key)
.Select(y => new Severity
{
severity = y.Key,
Count = y.Value
}).ToList()
: new List<Severity>();
public string flawListInfo => !flaws.Any()
? "" : flaws.Aggregate(new StringBuilder("path\tfile\tline\ttype\n"), (x, y) =>
x.AppendLine($"{(string.IsNullOrEmpty(y.source.sourcefile) ? "na" : Path.GetDirectoryName(y.source.sourcefile))}\t"
+ $"{(string.IsNullOrEmpty(y.source.sourcefile) ? "na" : Path.GetFileName(y.source.sourcefile))}\t{y.source.line}\t{y.source.type}")).ToString();
public List<ModuleFlaw> flawList => !flaws.Any() ? null : flaws
.ConvertAll(y => (ModuleFlaw)y.source);
private List<ModuleSummary> flaws { get; set; }
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 => new ModuleSummary
{
key = grp.Key,
source = grp.First(),
count = grp.Count()
})
.OrderBy(grp => grp.source.sourcefile).ThenBy(grp => grp.source.line).ThenBy(grp => grp.source.type).ToList();
}
object ToDump() => new
{
Info = new
{
name,
score = score.ToString().PadLeft(3),
totalNumberOfFlaws = totalNumberOfFlaws.ToString().PadLeft(5),
numberOfImportantFlaws = numberOfImportantFlaws.ToString().PadLeft(5)
},
summary,
flaws = flawList
};
}
internal class ModuleSummary
{
public string key { get; set; }
public ModuleFlaw source { get; set; }
public int count { get; set; }
}
internal class Severity
{
public string Level => severity.SeverityLabel();
internal int severity { get; set; }
public int Count { get; set; }
object ToDump() => new
{
Level,
Count = Count.ToString().PadLeft(4)
};
}
internal class ModuleFlaw
{
public string type { get; set; }
internal string sourcefile { get; set; }
public string path => string.IsNullOrEmpty(sourcefile) ? "n/a" : System.IO.Path.GetDirectoryName(sourcefile);
public string file => string.IsNullOrEmpty(sourcefile) ? "n/a" : System.IO.Path.GetFileName(sourcefile);
public int count { get; set; }
public int line { get; set; }
public int issueid { get; set; }
public int severity { get; set; }
public int cweid { get; set; }
public string cwename { get; set; }
public string remediation_status{ get; set; }
public int categoryid { get; set; }
public bool hasMitigations { get; set; }
public ModuleFlaw(XElement element)
{
var cwe = element.Ancestors().Where(e => e.Name.LocalName == "cwe").LastOrDefault();
cwename = cwe.Attribute("cwename")?.Value ?? "";
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 ?? "");
remediation_status = element.Attribute("remediation_status")?.Value ?? "";
line = Convert.ToInt32(element.Attribute("line")?.Value ?? "0");
count = Convert.ToInt32(element.Attribute("count")?.Value ?? "0");
issueid = Convert.ToInt32(element.Attribute("issueid")?.Value ?? "0");
severity = Convert.ToInt32(element.Attribute("severity")?.Value ?? "0");
cweid = Convert.ToInt32(element.Attribute("cweid")?.Value ?? "0");
categoryid = Convert.ToInt32(element.Attribute("categoryid")?.Value ?? "0");
}
public ModuleFlaw(Flaw flaw)
{
hasMitigations = flaw.hasMitigations;
type = flaw.type;
sourcefile = flaw.sourcefile;
line = flaw.line;
}
object ToDump() => new
{
categoryid = categoryid.ToString().PadLeft(5),
cweid = cweid.ToString().PadLeft(5),
hasMitigations,
type,
path,
file,
line = line.ToString().PadLeft(5),
count = count.ToString().PadLeft(5),
issueid = issueid.ToString().PadLeft(5),
severity = severity.SeverityLabel()
};
}
internal class Flaw : ModuleFlaw
{
public string module { get; set; }
public string description { get; set; }
public Flaw(XElement element)
: base(element)
{
module = string.Join("\r\n", element.Attribute("module")?.Value.Split("/".ToCharArray()));
description = element.Attribute("description")?.Value;
}
object ToDump() => new
{
Info = new
{
categoryid = $"{categoryid.CategoryLabel()} ({categoryid})",
cweid = cweid.ToString().PadLeft(5),
cwename,
hasMitigations,
type,
path,
file,
line = line.ToString().PadLeft(5),
count = count.ToString().PadLeft(5),
issueid = issueid.ToString().PadLeft(5),
severity = severity.SeverityLabel()
},
description
};
}
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();
}
object ToDump() => new
{
Info = new
{
Name = name,
Category = $"{category} ({id})",
Severity = severity.SeverityLabel(),
wo_Tests = count
},
recommendation
};
}