Skip to content

Commit 520a421

Browse files
committed
Update various classes to support crawler and other misc changes.
1 parent b3b6ecf commit 520a421

File tree

7 files changed

+411
-228
lines changed

7 files changed

+411
-228
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package org.owasp.benchmark.helpers;
2+
3+
public class TestCaseRequestFileParseException extends Exception {
4+
5+
public TestCaseRequestFileParseException(String message) {
6+
super(message);
7+
}
8+
9+
public TestCaseRequestFileParseException(String message, Exception e) {
10+
super(message, e);
11+
}
12+
13+
}

src/main/java/org/owasp/benchmark/helpers/Utils.java

+122-76
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.io.BufferedReader;
2222
import java.io.ByteArrayOutputStream;
2323
import java.io.File;
24+
import java.io.FileInputStream;
2425
import java.io.FileNotFoundException;
2526
import java.io.FileOutputStream;
2627
import java.io.FileReader;
@@ -33,6 +34,8 @@
3334
import java.net.URL;
3435
import java.nio.file.Files;
3536
import java.nio.file.Path;
37+
import static java.nio.file.StandardOpenOption.APPEND;
38+
import static java.nio.file.StandardOpenOption.CREATE;
3639
import java.nio.file.attribute.PosixFilePermission;
3740
import java.security.InvalidKeyException;
3841
import java.security.NoSuchAlgorithmException;
@@ -42,6 +45,7 @@
4245
import java.util.HashSet;
4346
import java.util.List;
4447
import java.util.Set;
48+
import java.util.Vector;
4549

4650
import javax.crypto.Cipher;
4751
import javax.crypto.NoSuchPaddingException;
@@ -51,50 +55,48 @@
5155
import javax.servlet.http.HttpServletResponse;
5256
import javax.xml.parsers.DocumentBuilder;
5357
import javax.xml.parsers.DocumentBuilderFactory;
54-
//import javax.xml.parsers.ParserConfigurationException;
55-
//import javax.xml.transform.Transformer;
56-
//import javax.xml.transform.TransformerException;
57-
//import javax.xml.transform.TransformerFactory;
58-
//import javax.xml.transform.dom.DOMSource;
59-
//import javax.xml.transform.stream.StreamResult;
58+
import javax.xml.parsers.ParserConfigurationException;
6059

6160
import org.apache.http.Header;
6261
import org.apache.http.HttpEntity;
62+
import org.apache.http.NameValuePair;
6363
import org.apache.http.ParseException;
6464
import org.apache.http.client.methods.HttpPost;
6565
import org.apache.http.client.methods.HttpRequestBase;
6666
import org.apache.http.conn.ssl.NoopHostnameVerifier;
6767
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
6868
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
69+
import org.apache.http.message.BasicNameValuePair;
6970
import org.apache.http.ssl.SSLContexts;
7071
import org.apache.http.util.EntityUtils;
7172

7273
import org.owasp.benchmark.service.pojo.StringMessage;
7374
import org.owasp.benchmark.score.BenchmarkScore;
7475
import org.owasp.benchmark.tools.AbstractTestCaseRequest;
76+
import org.owasp.benchmark.tools.AbstractTestCaseRequest.TestCaseType;
7577
import org.owasp.benchmark.tools.ServletTestCaseRequest;
7678
import org.owasp.benchmark.tools.XMLCrawler;
7779

7880
import org.owasp.esapi.ESAPI;
7981
import org.w3c.dom.Document;
80-
//import org.w3c.dom.Element;
8182
import org.w3c.dom.Node;
8283
import org.xml.sax.InputSource;
83-
//import org.xml.sax.SAXException;
84+
import org.xml.sax.SAXException;
8485

8586
public class Utils {
8687

8788
// Properties used by the generated test suite
8889

8990
public static final String USERDIR = System.getProperty("user.dir") + File.separator;
9091

91-
// A 'test' directory that target test files are created in so test cases can use them
92+
// A 'test' directory that target test files are created in so test cases can
93+
// use them
9294
public static final String TESTFILES_DIR = USERDIR + "testfiles" + File.separator;
9395

9496
public static final String DATA_DIR = USERDIR + "data" + File.separator;
9597

96-
public static final String RESOURCES_DIR = USERDIR + "src" + File.separator + "main" + File.separator
97-
+ "resources" + File.separator;
98+
public static final String RESOURCES_DIR = USERDIR + "src" + File.separator + "main" + File.separator + "resources"
99+
+ File.separator;
98100

99101
// This constant is used by some of the generated Java test cases
100102
public static final Set<String> commonHeaders = new HashSet<>(Arrays.asList("host", "user-agent", "accept",
@@ -149,12 +151,11 @@ public class Utils {
149151
}
150152
}
151153

152-
public static String getCookie( HttpServletRequest request, String paramName ) {
154+
public static String getCookie(HttpServletRequest request, String paramName) {
153155
Cookie[] values = request.getCookies();
154156
String param = "none";
155157
if (paramName != null) {
156-
for (int i = 0; i < values.length; i++)
157-
{
158+
for (int i = 0; i < values.length; i++) {
158159
if (values[i].getName().equals(paramName)) {
159160
param = values[i].getValue();
160161
break; // break out of for loop when param found
@@ -163,8 +164,8 @@ public static String getCookie( HttpServletRequest request, String paramName ) {
163164
}
164165
return param;
165166
}
166-
167-
public static String getParam( HttpServletRequest request, String paramName ) {
167+
168+
public static String getParam(HttpServletRequest request, String paramName) {
168169
String param = request.getParameter(paramName);
169170
return param;
170171
}
@@ -289,7 +290,8 @@ public static File getFileFromClasspath(String fileName, ClassLoader classLoader
289290
System.out.println("The file '" + fileName + "' from the classpath cannot be loaded.");
290291
e.printStackTrace();
291292
}
292-
} else System.out.println("The file '" + fileName + "' from the classpath cannot be loaded.");
293+
} else
294+
System.out.println("The file '" + fileName + "' from the classpath cannot be loaded.");
293295
return null;
294296
}
295297

@@ -331,6 +333,11 @@ public static List<String> getLinesFromFile(String filename) {
331333
return getLinesFromFile(new File(filename));
332334
}
333335

336+
/**
337+
* Encodes the supplied parameter using ESAPI's encodeForHTML(). Only supports Strings and InputStreams.
338+
* @param param - The String or InputStream to encode.
339+
* @return - HTML Entity encoded version of input, or "objectTypeUnknown" if not a supported type.
340+
*/
334341
public static String encodeForHTML(Object param) {
335342

336343
String value = "objectTypeUnknown";
@@ -353,31 +360,31 @@ public static String encodeForHTML(Object param) {
353360
return ESAPI.encoder().encodeForHTML(value);
354361
}
355362

356-
public static boolean writeTimeFile(Path pathToFileDir, String completeName, List<String> outputLines,
357-
boolean append) {
358-
boolean result = true;
359-
PrintStream os = null;
360-
try {
361-
Files.createDirectories(pathToFileDir);
362-
File f = new File(completeName);
363-
if (!append) {
364-
f.delete();
365-
}
366-
FileOutputStream fos = new FileOutputStream(f, append);
367-
os = new PrintStream(fos);
363+
/**
364+
* Write a single String to the specified file.
365+
* @param file - The path to the target file.
366+
* @param content - The content to write.
367+
* @param append - True to append to an existing file. False to create or overwrite the file.
368+
* @throws IOException
369+
*/
370+
public static void writeToFile(Path file, String content, boolean append) throws IOException {
371+
PrintStream os = new PrintStream(Files.newOutputStream(file, append ? APPEND : CREATE));
372+
os.println(content);
373+
}
368374

369-
for (String ol : outputLines) {
370-
os.println(ol);
371-
}
375+
/**
376+
* Write a list of Strings to the specified file.
377+
* @param file - The path to the target file.
378+
* @param content - The list of Strings to write out.
379+
* @param append - True to append to an existing file. False to create or overwrite the file.
380+
* @throws IOException
381+
*/
382+
public static void writeToFile(Path file, List<String> contentLines, boolean append) throws IOException {
383+
PrintStream os = new PrintStream(Files.newOutputStream(file, append ? APPEND : CREATE));
372384

373-
} catch (IOException e1) {
374-
result = false;
375-
e1.printStackTrace();
376-
} finally {
377-
os.close();
385+
for (String line : contentLines) {
386+
os.println(line);
378387
}
379-
380-
return result;
381388
}
382389

383390
public static boolean writeLineToFile(Path pathToFileDir, String completeName, String line) {
@@ -387,10 +394,7 @@ public static boolean writeLineToFile(Path pathToFileDir, String completeName, S
387394
Files.createDirectories(pathToFileDir);
388395
File f = new File(completeName);
389396
if (!f.exists()) {
390-
// System.out.println("Archivo llamado: " +
391-
// f.getAbsolutePath());
392397
f.createNewFile();
393-
// System.out.println("Archivo no existia se creoooooooooo");
394398
}
395399
FileOutputStream fos = new FileOutputStream(f, true);
396400
os = new PrintStream(fos);
@@ -420,14 +424,13 @@ public static boolean deleteFile(String completeName) {
420424
}
421425

422426
/**
423-
* UNUSED METHOD!!! Why was it created?
424-
* Parses all the XML in the provided InputStream to generate a List of test case requests.
425-
* If testing that case fails, add its failure to the list of failed test cases. (Not sure about this aspect of
426-
* what it does.)
427-
* @param http
428-
* The inputstream to parse the XML test case request from (e.g., contents of benchmark-crawler(or attack)-http.xml
429-
* @param failedTestCases
430-
* A list of error messages, 1 for each test case that failed.
427+
* UNUSED METHOD!!! Why was it created? Parses all the XML in the provided InputStream to generate a
428+
* List of test case requests. If testing that case fails, add its failure to the list of failed
429+
* test cases. (Not sure about this aspect of what it does.)
430+
*
431+
* @param http The inputstream to parse the XML test case request from (e.g., contents of
432+
* benchmark-crawler(or attack)-http.xml
433+
* @param failedTestCases A list of error messages, 1 for each test case that failed.
431434
* @return A List of TestCaseRequest objects based on the file contents.
432435
* @throws Exception
433436
*/
@@ -505,7 +508,7 @@ public static boolean deleteFile(String completeName) {
505508
return requests;
506509
}
507510
*/
508-
public static String getCrawlerBenchmarkVersion(InputStream http) throws Exception {
511+
public static String getCrawlerTestSuiteVersion(InputStream http) throws Exception {
509512
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
510513
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
511514
InputSource is = new InputSource(http);
@@ -515,41 +518,83 @@ public static String getCrawlerBenchmarkVersion(InputStream http) throws Excepti
515518
return XMLCrawler.getAttributeValue("version", root);
516519
}
517520

518-
public static List<AbstractTestCaseRequest> parseHttpFile(InputStream http) throws Exception {
519-
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
520-
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
521-
InputSource is = new InputSource(http);
522-
Document doc = docBuilder.parse(is);
523-
Node root = doc.getDocumentElement();
524-
521+
public static List<AbstractTestCaseRequest> parseHttpFile(File file) throws TestCaseRequestFileParseException {
525522
List<AbstractTestCaseRequest> requests = new ArrayList<AbstractTestCaseRequest>();
526-
List<Node> tests = XMLCrawler.getNamedChildren("benchmarkTest", root);
527-
for (Node test : tests) {
528-
AbstractTestCaseRequest request = parseHttpTest(test);
529-
requests.add(request);
523+
524+
try {
525+
FileInputStream inputStream = new FileInputStream(file);
526+
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
527+
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
528+
InputSource is = new InputSource(inputStream);
529+
Document doc = docBuilder.parse(is);
530+
Node root = doc.getDocumentElement();
531+
532+
List<Node> tests = XMLCrawler.getNamedChildren("benchmarkTest", root);
533+
for (Node test : tests) {
534+
AbstractTestCaseRequest request = parseHttpTest(test);
535+
requests.add(request);
536+
}
537+
} catch (ParserConfigurationException | SAXException | IOException e) {
538+
throw new TestCaseRequestFileParseException("Error during parsing", e);
530539
}
531540
return requests;
532541
}
533542

534-
public static AbstractTestCaseRequest parseHttpTest(Node test) {
535-
String tcType = XMLCrawler.getAttributeValue("tcType", test);
536-
String fullURL = XMLCrawler.getAttributeValue("URL", test);
543+
public static AbstractTestCaseRequest parseHttpTest(Node test) throws TestCaseRequestFileParseException {
544+
AbstractTestCaseRequest request = null;
545+
546+
String url = XMLCrawler.getAttributeValue("URL", test);
547+
TestCaseType tcType = TestCaseType.valueOf(XMLCrawler.getAttributeValue("tcType", test));
548+
String category = XMLCrawler.getAttributeValue("tcCategory", test);
537549
String name = BenchmarkScore.TESTCASENAME + XMLCrawler.getAttributeValue("tname", test);
538-
String payload = "";
550+
String uiTemplateFile = XMLCrawler.getAttributeValue("tcUITemplateFile", test);
551+
String templateFile = XMLCrawler.getAttributeValue("tcTemplateFile", test);
552+
String sourceFile = XMLCrawler.getAttributeValue("tcSourceFile", test);
553+
String sourceUIType = XMLCrawler.getAttributeValue("tsSourceUIType", test);
554+
String dataflowFile = XMLCrawler.getAttributeValue("tcDataflowFile", test);
555+
String sinkFile = XMLCrawler.getAttributeValue("tcSinkFile", test);
556+
boolean isVulnerability = Boolean.valueOf(XMLCrawler.getAttributeValue("tcVulnerable", test));
557+
558+
List<Node> headerNodes = XMLCrawler.getNamedChildren("header", test);
559+
List<NameValuePair> headers = parseNameValuePairs(headerNodes);
560+
561+
List<Node> cookieNodes = XMLCrawler.getNamedChildren("cookie", test);
562+
List<NameValuePair> cookies = parseNameValuePairs(cookieNodes);
539563

540-
List<Node> headers = XMLCrawler.getNamedChildren("header", test);
541-
List<Node> cookies = XMLCrawler.getNamedChildren("cookie", test);
542-
List<Node> getParams = XMLCrawler.getNamedChildren("getparam", test);
543-
List<Node> formParams = XMLCrawler.getNamedChildren("formparam", test);
564+
List<Node> getParamNodes = XMLCrawler.getNamedChildren("getparam", test);
565+
List<NameValuePair> getParams = parseNameValuePairs(getParamNodes);
566+
567+
List<Node> formParamsNodes = XMLCrawler.getNamedChildren("formparam", test);
568+
List<NameValuePair> formParams = parseNameValuePairs(formParamsNodes);
569+
570+
List<Node> payloadNodes = XMLCrawler.getNamedChildren("payload", test);
571+
if (payloadNodes.size() > 1)
572+
throw new TestCaseRequestFileParseException("There cannot be multiple payloads for a request");
573+
String payload = XMLCrawler.getAttributeValue("value", payloadNodes.get(0));
544574

545575
switch (tcType) {
546-
case "SERVLET":
547-
ServletTestCaseRequest svlTC = new ServletTestCaseRequest(name, fullURL, tcType, headers, cookies,
548-
getParams, formParams, payload);
549-
return svlTC;
576+
case SERVLET:
577+
request = new ServletTestCaseRequest(url, tcType, category, payload, name, uiTemplateFile, templateFile,
578+
sourceFile, sourceUIType, dataflowFile, sinkFile, isVulnerability, headers, cookies, getParams,
579+
formParams);
580+
break;
581+
default:
582+
throw new TestCaseRequestFileParseException("Unrecognized tcType: " + tcType);
550583
}
551584

552-
return null;
585+
return request;
586+
}
587+
588+
private static List<NameValuePair> parseNameValuePairs(List<Node> nodes) throws TestCaseRequestFileParseException {
589+
List<NameValuePair> nameValuePairs = new Vector<NameValuePair>();
590+
591+
for (Node nameValuePairNode : nodes) {
592+
String name = XMLCrawler.getAttributeValue("name", nameValuePairNode);
593+
String value = XMLCrawler.getAttributeValue("value", nameValuePairNode);
594+
nameValuePairs.add(new BasicNameValuePair(name, value));
595+
}
596+
597+
return nameValuePairs;
553598
}
554599

555600
public static List<String> readCSVFailedTC(String csvFile) {
@@ -574,7 +619,8 @@ public static List<String> readCSVFailedTC(String csvFile) {
574619
/*
575620
* A utility method used by the generated Java Cipher test cases.
576621
*/
577-
private static javax.crypto.Cipher cipher = null;
622+
private static javax.crypto.Cipher cipher = null;
623+
578624
public static Cipher getCipher() {
579625
if (cipher == null) {
580626
try {

0 commit comments

Comments
 (0)