Skip to content

Commit fa9df02

Browse files
committed
add Arachni scorecard generator. Fix some unintended DOM XSS vulns.
1 parent 25a20f2 commit fa9df02

File tree

265 files changed

+881
-562
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

265 files changed

+881
-562
lines changed

src/main/java/org/owasp/benchmark/score/BenchmarkScore.java

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242

4343
import org.apache.commons.io.FileUtils;
4444
import org.owasp.benchmark.score.parsers.AppscanReader;
45+
import org.owasp.benchmark.score.parsers.ArachniReader;
4546
import org.owasp.benchmark.score.parsers.CheckmarxReader;
4647
import org.owasp.benchmark.score.parsers.Counter;
4748
import org.owasp.benchmark.score.parsers.CoverityReader;
@@ -160,16 +161,13 @@ public static void main(String[] args) {
160161
process( f, expectedResults, toolResults );
161162
}
162163

163-
System.out.println( "Benchmark scorecards computed." );
164+
System.out.println( "Tool scorecards computed." );
164165
} catch( Exception e ) {
165166
System.out.println( "Error during processing: " + e.getMessage() );
166167
e.printStackTrace();
167168
}
168169

169-
// Generate the overall comparison chart for all the tools in this test
170-
ScatterScores.generateComparisonChart(toolResults);
171-
172-
// Generate vulnerability category list
170+
// Generate vulnerability category list
173171
// A set is used here to eliminate duplicate categories across all the results
174172
Set<String> catSet = new HashSet<String>();
175173
for ( int i= 0; i < toolResults.size(); i++ ) {
@@ -180,11 +178,18 @@ public static void main(String[] args) {
180178
List<String> catList = new ArrayList<String>();
181179
catList.addAll(catSet);
182180

183-
// Generate vulnerability pages
181+
182+
// Generate vulnerability pages
183+
// System.out.println("generating vulns");
184184
BenchmarkScore.generateVulnerabilityScorecards(toolResults, catList);
185+
System.out.println( "Vulnerability scorecards computed." );
185186

186187
updateMenus(toolResults, catList);
187188

189+
// Generate the overall comparison chart for all the tools in this test
190+
ScatterScores.generateComparisonChart(toolResults);
191+
System.out.println( "Benchmark scorecards complete." );
192+
188193
System.exit(0);
189194
}
190195

@@ -400,6 +405,10 @@ else if ( line1.contains( "<OWASPZAPReport") || line2.contains( "<OWASPZAPReport
400405
else if ( line2.startsWith( "<CxXMLResults")) {
401406
tr = new CheckmarxReader().parse( actual );
402407
}
408+
409+
else if ( line2.startsWith( "<report")) {
410+
tr = new ArachniReader().parse( actual );
411+
}
403412
}
404413

405414
else if ( filename.endsWith( ".fpr" ) ) {
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
/**
2+
* OWASP Benchmark Project
3+
*
4+
* This file is part of the Open Web Application Security Project (OWASP)
5+
* Benchmark Project For details, please see
6+
* <a href="https://www.owasp.org/index.php/Benchmark">https://www.owasp.org/index.php/Benchmark</a>.
7+
*
8+
* The OWASP Benchmark is free software: you can redistribute it and/or modify it under the terms
9+
* of the GNU General Public License as published by the Free Software Foundation, version 2.
10+
*
11+
* The OWASP Benchmark is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
12+
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details
14+
*
15+
* @author Dave Wichers <a href="https://www.aspectsecurity.com">Aspect Security</a>
16+
* @created 2015
17+
*/
18+
19+
package org.owasp.benchmark.score.parsers;
20+
21+
import java.io.File;
22+
import java.io.FileInputStream;
23+
import java.net.URI;
24+
import java.net.URISyntaxException;
25+
import java.text.SimpleDateFormat;
26+
import java.util.List;
27+
28+
import javax.xml.parsers.DocumentBuilder;
29+
import javax.xml.parsers.DocumentBuilderFactory;
30+
31+
import org.w3c.dom.Document;
32+
import org.w3c.dom.Node;
33+
import org.xml.sax.InputSource;
34+
35+
public class ArachniReader extends Reader {
36+
37+
// <report xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/Arachni/arachni/v2.0dev/components/reporters/xml/schema.xsd">
38+
// <version>2.0dev</version>
39+
// <start_datetime>2015-08-17T14:21:14+03:00</start_datetime>
40+
// <finish_datetime>2015-08-17T14:44:14+03:00</finish_datetime>
41+
// <sitemap>
42+
43+
44+
public TestResults parse(File f) throws Exception {
45+
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
46+
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
47+
InputSource is = new InputSource( new FileInputStream(f) );
48+
Document doc = docBuilder.parse(is);
49+
50+
TestResults tr = new TestResults( "Arachni", false, TestResults.ToolType.DAST);
51+
52+
Node arachni = doc.getDocumentElement();
53+
String version = getNamedChild( "version", arachni ).getTextContent();
54+
tr.setToolVersion( version );
55+
56+
String start = getNamedChild( "start_datetime", arachni ).getTextContent();
57+
String stop = getNamedChild( "finish_datetime", arachni ).getTextContent();
58+
tr.setTime( calculateTime( start, stop ));
59+
60+
Node issues = getNamedChild( "issues", arachni );
61+
List<Node> issueList = getNamedChildren( "issue", issues );
62+
63+
for ( Node issue : issueList ) {
64+
try {
65+
TestCaseResult tcr = parseArachniIssue(issue);
66+
if (tcr != null ) {
67+
// System.out.println( tcr.getNumber() + " " + tcr.getName() + " -> " + tcr.getCWE() + "\t" + tcr.getEvidence() );
68+
tr.put(tcr);
69+
}
70+
} catch( Exception e ) {
71+
// print and continue
72+
e.printStackTrace();
73+
}
74+
}
75+
return tr;
76+
}
77+
78+
// <issue>
79+
// <name>Cross-Site Scripting (XSS)</name>
80+
// <description>
81+
//Client-side scripts are used extensively by modern web applications.
82+
//</description>
83+
// <remedy_guidance>
84+
//</remedy_guidance>
85+
// <remedy_code/>
86+
// <severity>high</severity>
87+
// <check>
88+
// <name>XSS</name>
89+
// <description>
90+
//Injects an HTML element into page inputs and then parses the HTML markup of
91+
//</description>
92+
// <author>Tasos "Zapotek" Laskos &lt;[email protected]&gt; </author>
93+
// <version>0.4.4</version>
94+
// <shortname>xss</shortname>
95+
// </check>
96+
// <cwe>79</cwe>
97+
// <digest>3396861445</digest>
98+
// <references>
99+
// </references>
100+
// <vector>
101+
// <class>Arachni::Element::Form</class>
102+
// <type>form</type>
103+
// <url>https://127.0.0.2:8443/benchmark/BenchmarkTest00397.html</url>
104+
// <action>https://127.0.0.2:8443/benchmark/BenchmarkTest00397</action>
105+
// <source>/form&gt;</source>
106+
// <method>post</method>
107+
// <affected_input_name>vector</affected_input_name>
108+
// <inputs>
109+
// <input name="vector" value="Singing"/>
110+
// <input name="foo" value="bar"/>
111+
// </inputs>
112+
// </vector>
113+
// </issue>
114+
115+
// 2015-08-17T14:21:14+03:00
116+
private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
117+
private String calculateTime(String submitted, String published) {
118+
try {
119+
long start = sdf.parse( submitted ).getTime();
120+
long finish = sdf.parse( published ).getTime();
121+
return TestResults.formatTime( finish - start );
122+
} catch( Exception e ) {
123+
e.printStackTrace();
124+
return "Unknown";
125+
}
126+
}
127+
128+
129+
130+
private TestCaseResult parseArachniIssue(Node flaw) throws URISyntaxException {
131+
TestCaseResult tcr = new TestCaseResult();
132+
Node rule = getNamedChild("cwe", flaw);
133+
if ( rule != null ) {
134+
tcr.setCWE( cweLookup( rule.getTextContent() ) );
135+
}
136+
137+
String cat = getNamedChild("name", flaw).getTextContent();
138+
tcr.setCategory( cat );
139+
140+
// not used
141+
String conf = getNamedChild( "severity", flaw ).getTextContent();
142+
143+
// confidence not available
144+
// tcr.setConfidence( Integer.parseInt( conf ) );
145+
146+
tcr.setEvidence( cat );
147+
148+
Node vector = getNamedChild( "vector", flaw );
149+
String uri = getNamedChild( "url", vector ).getTextContent();
150+
URI url = new URI( uri );
151+
String testfile = url.getPath();
152+
testfile = testfile.substring( testfile.lastIndexOf('/') +1 );
153+
154+
if ( testfile.startsWith( "BenchmarkTest" ) ) {
155+
String testno = testfile.substring("BenchmarkTest".length());
156+
if ( testno.endsWith( ".html" ) ) {
157+
testno = testno.substring(0, testno.length() -5 );
158+
}
159+
try {
160+
tcr.setNumber( Integer.parseInt( testno ) );
161+
return tcr;
162+
} catch( NumberFormatException e ) {
163+
System.out.println( "> Parse error " + testfile + ":: " + testno );
164+
}
165+
}
166+
return null;
167+
}
168+
169+
170+
private int cweLookup(String orig) {
171+
172+
switch( orig ) {
173+
}
174+
175+
return Integer.parseInt( orig );
176+
}
177+
178+
}
179+
180+

src/main/java/org/owasp/benchmark/score/parsers/ZapReader.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,15 @@ public TestResults parse(File f) throws Exception {
5353
List<Node> issueList = getNamedChildren( "alertitem", alertsList );
5454

5555
for ( Node flaw : issueList ) {
56-
TestCaseResult tcr = parseZapIssue(flaw);
57-
if (tcr != null ) {
58-
// System.out.println( tcr.getNumber() + " " + tcr.getName() + " -> " + tcr.getCWE() + "\t" + tcr.getEvidence() );
59-
tr.put(tcr);
56+
try {
57+
TestCaseResult tcr = parseZapIssue(flaw);
58+
if (tcr != null ) {
59+
// System.out.println( tcr.getNumber() + " " + tcr.getName() + " -> " + tcr.getCWE() + "\t" + tcr.getEvidence() );
60+
tr.put(tcr);
61+
}
62+
} catch( Exception e ) {
63+
// print and continue
64+
e.printStackTrace();
6065
}
6166
}
6267
return tr;

src/main/java/org/owasp/benchmark/score/report/Report.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,16 @@ public class Report implements Comparable<Report> {
4242

4343
// The name of the file that contains this scorecard report
4444
private String filename = null;
45-
45+
public Report( OverallResults or,boolean isCommercial,String toolName){
46+
this.toolName = toolName;
47+
this.overallResults = or;
48+
this.isCommercial = isCommercial;
49+
}
4650
public Report(TestResults actualResults, Map<String, Counter> scores, OverallResults or, int totalResults,
47-
String actualResultsFileName, boolean isCommertial, boolean isStatic)
51+
String actualResultsFileName, boolean isCommercial, boolean isStatic)
4852
throws IOException, URISyntaxException {
4953
this.isStatic = isStatic;
50-
this.isCommercial = isCommertial;
54+
this.isCommercial = isCommercial;
5155
toolName = actualResults.getTool();
5256
String version = actualResults.getToolVersion();
5357
if (version != null)
@@ -152,9 +156,11 @@ private String generateTable(TestResults actualResults, Map<String, Counter> sco
152156
double totalScore = 0;
153157

154158
for (String category : scores.keySet()) {
159+
155160
Counter c = scores.get(category);
156161
OverallResult r = or.getResults(category);
157162
String style = "";
163+
158164
if (Math.abs(r.tpr - r.fpr) < .1)
159165
style = "class=\"danger\"";
160166
else if (r.tpr > .7 && r.fpr < .3)

0 commit comments

Comments
 (0)