Skip to content

Commit e8f2ff6

Browse files
author
Dave Wichers
committed
More enhancements and additional rule tuning for a number of parsers.
1 parent c14b8a9 commit e8f2ff6

File tree

20 files changed

+638
-214
lines changed

20 files changed

+638
-214
lines changed

library/src/main/resources/categories.xml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
<id>deserialization</id>
6161
<name>Insecure Deserialization</name>
6262
<cwe>502</cwe>
63+
<childof>913,915</childof>
6364
<isInjection>false</isInjection>
6465
<shortname>DESER</shortname>
6566
</category>
@@ -131,12 +132,14 @@
131132
<id>redirect</id>
132133
<name>Unchecked Redirect</name>
133134
<cwe>601</cwe>
135+
<childof>610</childof>
134136
<shortname>REDIR</shortname>
135137
</category>
136138
<category>
137139
<id>reflecti</id>
138140
<name>Unsafe Reflection</name>
139141
<cwe>470</cwe>
142+
<childof>610,913</childof>
140143
<isInjection>true</isInjection>
141144
<shortname>REFLECT</shortname>
142145
</category>
@@ -160,6 +163,7 @@
160163
<id>trustbound</id>
161164
<name>Trust Boundary</name>
162165
<cwe>501</cwe>
166+
<childof>664</childof>
163167
<shortname>TRBO</shortname>
164168
</category>
165169
<category>
@@ -189,14 +193,16 @@
189193
<id>xss</id>
190194
<name>XSS (Cross-Site Scripting)</name>
191195
<cwe>79</cwe>
192-
<parentof>80,81,83,84,85,86,87</parentof>
196+
<parentof>80,81,82,83,84,85,86,87</parentof>
193197
<!-- isInjection>Don't set. Not a classic injection issue.</isInjection -->
194198
<shortname>XSS</shortname>
199+
<note>82 added manually as its the child of 83.</note>
195200
</category>
196201
<category>
197202
<id>xxe</id>
198203
<name>XML eXternal Entity Injection</name>
199204
<cwe>611</cwe>
205+
<childof>610</childof>
200206
<isInjection>true</isInjection>
201207
<shortname>XXE</shortname>
202208
</category>

plugin/src/main/java/org/owasp/benchmarkutils/helpers/Utils.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ public static void copyFilesFromDirRecursively(String source, final Path target)
239239
return;
240240
}
241241

242-
if (srcURL.getProtocol().equals("file")) {
242+
if ("file".equals(srcURL.getProtocol())) {
243243
// Copy the files from one directory to another using the normal
244244
// FileUtils.copyDirectory() method
245245

@@ -278,7 +278,7 @@ public static void copyFilesFromDirRecursively(String source, final Path target)
278278
return; // File(s) copied or it failed
279279
}
280280

281-
if (!srcURL.getProtocol().equals("jar")) {
281+
if (!"jar".equals(srcURL.getProtocol())) {
282282
System.err.printf(
283283
"ERROR: source resource not a file: or jar: resource. It is: %s%n", srcURL);
284284
return;

plugin/src/main/java/org/owasp/benchmarkutils/score/BenchmarkScore.java

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,6 @@ public class BenchmarkScore extends AbstractMojo {
8888
// scorecard dir normally created under current user directory
8989
public static final String SCORECARDDIRNAME = "scorecard";
9090

91-
// The values stored in this is pulled from the categories.xml config file
92-
// public static Categories CATEGORIES;
93-
9491
/*
9592
* The set of all the Tools. Each Tool includes the results for that tool.
9693
*/
@@ -416,7 +413,7 @@ public static void main(String[] args) {
416413

417414
// catch try for Steps 4 & 5
418415
} catch (Exception e) {
419-
System.out.println("Error during processing: " + e.getMessage());
416+
System.err.println("Error during processing: " + e.getMessage());
420417
e.printStackTrace();
421418
}
422419

@@ -526,7 +523,7 @@ public static void main(String[] args) {
526523

527524
Files.write(homeFilePath, html.getBytes());
528525
} catch (IOException e) {
529-
System.out.println("Error updating results table in: " + homeFilePath.getFileName());
526+
System.err.println("Error updating results table in: " + homeFilePath.getFileName());
530527
e.printStackTrace();
531528
}
532529

@@ -535,7 +532,7 @@ public static void main(String[] args) {
535532
try {
536533
scatter.writeChartToFile(new File(scoreCardDir, "content/testsuite_guide.png"), 800);
537534
} catch (IOException e) {
538-
System.out.println(
535+
System.err.println(
539536
"ERROR: Couldn't create content/testsuite_guide.png file for some reason.");
540537
e.printStackTrace();
541538
}
@@ -608,13 +605,13 @@ private static void process(
608605
// printExtraCWE( expectedResults, actualResults );
609606
} else {
610607
if (expectedResults == null) {
611-
System.out.println("Error!!: expected results were null.");
608+
System.err.println("Error!!: expected results were null.");
612609
} else
613-
System.out.println(
610+
System.err.println(
614611
"Error!!: actual results were null for file: " + rawToolResultsFile);
615612
}
616613
} catch (Exception e) {
617-
System.out.println("Error processing " + rawToolResultsFile + ". Continuing.");
614+
System.err.println("Error processing " + rawToolResultsFile + ". Continuing.");
618615
e.printStackTrace();
619616
}
620617
}
@@ -858,7 +855,7 @@ private static CweMatchDetails compare(
858855
// return true if there are no actual results and this was a false positive test
859856
if (actList == null || actList.isEmpty()) {
860857
return new CweMatchDetails(
861-
expectedCWE, exp.isTruePositive(), !exp.isTruePositive(), -1, "");
858+
expectedCWE, exp.isTruePositive(), !exp.isTruePositive(), -1, "", actList);
862859
}
863860

864861
// Check actual results for an exact CWE match.
@@ -872,7 +869,12 @@ private static CweMatchDetails compare(
872869
// immediately return a value if we find an exact match
873870
if (actualCWE == expectedCWE) {
874871
return new CweMatchDetails(
875-
expectedCWE, exp.isTruePositive(), exp.isTruePositive(), actualCWE, "");
872+
expectedCWE,
873+
exp.isTruePositive(),
874+
exp.isTruePositive(),
875+
actualCWE,
876+
"",
877+
actList);
876878
}
877879
}
878880

@@ -887,20 +889,22 @@ private static CweMatchDetails compare(
887889
exp.isTruePositive(),
888890
exp.isTruePositive(),
889891
actualCWE,
890-
"ChildOf");
892+
"ChildOf",
893+
actList);
891894
}
892895
if (expectedCWECategory.isParentOf(actualCWE)) {
893896
return new CweMatchDetails(
894897
expectedCWE,
895898
exp.isTruePositive(),
896899
exp.isTruePositive(),
897900
actualCWE,
898-
"ParentOf");
901+
"ParentOf",
902+
actList);
899903
}
900904
}
901905
// if we couldn't find a match, then return true if it's a False Positive test
902906
return new CweMatchDetails(
903-
expectedCWE, exp.isTruePositive(), !exp.isTruePositive(), -1, "");
907+
expectedCWE, exp.isTruePositive(), !exp.isTruePositive(), -1, "", actList);
904908
}
905909

906910
// Create a TestResults object that contains the expected results for this version

plugin/src/main/java/org/owasp/benchmarkutils/score/Configuration.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,13 @@ public class Configuration {
7777
/** Indicates whether Precision score should be included in generated tables. By default, no. */
7878
public final boolean includePrecision;
7979

80+
/**
81+
* This is a debug flag, which if set in yaml config file, causes all the CSVs for each test
82+
* case to be included in the CSV results file if no CSV matches the expected result for that
83+
* test case.
84+
*/
85+
public static boolean includeAllCWEsInCSVFile = false;
86+
8087
public final Report report;
8188

8289
private static final Yaml yaml = new Yaml();
@@ -163,6 +170,10 @@ private Configuration(Map<String, Object> yamlConfig) {
163170
includeProjectLink = (Boolean) yamlConfig.get("includeprojectlink");
164171
includePrecision = (Boolean) yamlConfig.get("includeprecision");
165172

173+
// Optional config parameter for debugging/testing only
174+
if (yamlConfig.get("includecwesincsvresults") != null)
175+
includeAllCWEsInCSVFile = (Boolean) yamlConfig.get("includecwesincsvresults");
176+
166177
report = new Report(yamlConfig);
167178
}
168179

plugin/src/main/java/org/owasp/benchmarkutils/score/CweMatchDetails.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
*/
1818
package org.owasp.benchmarkutils.score;
1919

20+
import java.util.List;
21+
2022
/**
2123
* This class contains the details of how a tool's result matches to a particular test case. With
2224
* CWE parent/child matching, we want to record exactly how a tool's finding matched. Was it an
@@ -39,18 +41,22 @@ public class CweMatchDetails {
3941
public final int actualCWEreported; // -1 if not found
4042
// Empty string if exact match or no match. ChildOF if a child CWE, ParentOf if parent CWE
4143
public final String CWErelationship;
44+
// The full set of findings for this test case
45+
public final List<TestCaseResult> actList;
4246

4347
public CweMatchDetails(
4448
int expectedCWE,
4549
boolean truePositive,
4650
boolean pass,
4751
int actualCWEreported,
48-
String CWErelationship) {
52+
String CWErelationship,
53+
List<TestCaseResult> actList) {
4954
this.expectedCWE = expectedCWE;
5055
this.truePositive = truePositive;
5156
this.pass = pass;
5257
this.actualCWEreported = actualCWEreported; // Suggest -1 if not found
5358
// Blank string if not found or exact CWE match
5459
this.CWErelationship = (CWErelationship == null ? "" : CWErelationship);
60+
this.actList = actList;
5561
}
5662
}

plugin/src/main/java/org/owasp/benchmarkutils/score/ResultFile.java

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@
1717
*/
1818
package org.owasp.benchmarkutils.score;
1919

20-
import java.io.ByteArrayInputStream;
21-
import java.io.ByteArrayOutputStream;
2220
import java.io.File;
21+
import java.io.FileInputStream;
2322
import java.io.IOException;
23+
import java.io.InputStream;
2424
import java.io.StringReader;
2525
import java.nio.charset.StandardCharsets;
2626
import java.nio.file.Files;
@@ -46,6 +46,10 @@ public class ResultFile {
4646
private final File originalFile;
4747
private JSONObject contentAsJson;
4848
private Document contentAsXml;
49+
// This is a special stream only set by test cases, because they are resource files, not actual
50+
// files on the file system. It is only used by the extract() method to pull files out of ZIP
51+
// archives in test case. The normal code pulls the data out of the result file.
52+
InputStream streamToFile = null; // If null, not used.
4953

5054
public ResultFile(File fileToParse) throws IOException {
5155
this(fileToParse, readFileContent(fileToParse));
@@ -61,8 +65,8 @@ public ResultFile(String filename, byte[] rawContent) throws IOException {
6165

6266
public ResultFile(File fileToParse, byte[] rawContent) throws IOException {
6367
this.rawContent = rawContent;
64-
originalFile = fileToParse;
65-
filename = originalFile.getName();
68+
this.originalFile = fileToParse;
69+
this.filename = originalFile.getName();
6670
parseJson();
6771
parseXml();
6872
}
@@ -191,16 +195,29 @@ public String xmlRootNodeName() {
191195
}
192196

193197
/**
194-
* Extracts a file from a packed ResultFile.
198+
* Finds the specified file in the zip file associated with this ResultFile, and returns an
199+
* InputStream to the specified file.
195200
*
196-
* @return
201+
* @return An InputStream to the specified file.
197202
*/
198-
public ResultFile extract(String zipPath) {
199-
try (ZipInputStream zipIn = new ZipInputStream(new ByteArrayInputStream(rawContent))) {
203+
public InputStream extract(String zipPath) {
204+
try {
205+
ZipInputStream zipIn;
206+
// Check to see if a stream to the file was set by a test case. If so, use that instead
207+
// of the File reference.
208+
if (this.streamToFile != null) zipIn = new ZipInputStream(this.streamToFile);
209+
else zipIn = new ZipInputStream(new FileInputStream(this.originalFile));
210+
200211
ZipEntry entry = zipIn.getNextEntry();
201212
while (entry != null) {
202213
if (entry.getName().equals(zipPath)) {
203-
return readFileFromZip(zipPath, zipIn);
214+
// NOTE: Previously this method used to call another method that extracted the
215+
// file into a new ResultFile with just the ZIP file attached to it. However,
216+
// for VERY large Fortify files, you couldn't create a byte[] big enough to hold
217+
// the entire file (as its was > 2GB), so you got an OutOfMemoryError. So now we
218+
// return a Stream instead, and that gets passed to the DOM Parser directly,
219+
// which works fine for large files.
220+
return zipIn;
204221
}
205222
zipIn.closeEntry();
206223
entry = zipIn.getNextEntry();
@@ -211,15 +228,4 @@ public ResultFile extract(String zipPath) {
211228

212229
throw new RuntimeException("ZipFile does not contain " + zipPath);
213230
}
214-
215-
private ResultFile readFileFromZip(String zipPath, ZipInputStream zipIn) throws IOException {
216-
try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
217-
final byte[] buf = new byte[1024];
218-
int length;
219-
while ((length = zipIn.read(buf, 0, buf.length)) >= 0) {
220-
bos.write(buf, 0, length);
221-
}
222-
return new ResultFile(zipPath, bos.toByteArray());
223-
}
224-
}
225231
}

plugin/src/main/java/org/owasp/benchmarkutils/score/TestSuiteResults.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ public String getMatchingTestCaseName(String testCaseFilename) {
263263
* @param filename
264264
* @return The filename without any path info (if any)
265265
*/
266-
private String getFileNameNoPath(String filename) {
266+
public static String getFileNameNoPath(String filename) {
267267
// We look for / and \ and strip off everything before and including the path separator. We
268268
// check both path chars because the results could be generated on one platform and scored
269269
// on another with different path separators.

plugin/src/main/java/org/owasp/benchmarkutils/score/WriteTime.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ private static String getLine(File file, String toFind, boolean nextLine) {
178178

179179
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
180180
String line = "";
181-
while (line.equals("")) {
181+
while ("".equals(line)) {
182182
line = br.readLine();
183183
if (line.contains(toFind)) {
184184
if (nextLine) return br.readLine();
@@ -208,7 +208,7 @@ private static void listPathFiles(String path) {
208208
}*/
209209

210210
void deletePreviousResults(String toolName, String toolVersion, String testSuiteVersion) {
211-
if (!toolName.equals("")) {
211+
if (!"".equals(toolName)) {
212212
File targetDir = new File("results/");
213213
if (targetDir.exists()) {
214214
File[] files = targetDir.listFiles();

0 commit comments

Comments
 (0)