21
21
import java .io .BufferedReader ;
22
22
import java .io .ByteArrayOutputStream ;
23
23
import java .io .File ;
24
+ import java .io .FileInputStream ;
24
25
import java .io .FileNotFoundException ;
25
26
import java .io .FileOutputStream ;
26
27
import java .io .FileReader ;
33
34
import java .net .URL ;
34
35
import java .nio .file .Files ;
35
36
import java .nio .file .Path ;
37
+ import static java .nio .file .StandardOpenOption .APPEND ;
38
+ import static java .nio .file .StandardOpenOption .CREATE ;
36
39
import java .nio .file .attribute .PosixFilePermission ;
37
40
import java .security .InvalidKeyException ;
38
41
import java .security .NoSuchAlgorithmException ;
42
45
import java .util .HashSet ;
43
46
import java .util .List ;
44
47
import java .util .Set ;
48
+ import java .util .Vector ;
45
49
46
50
import javax .crypto .Cipher ;
47
51
import javax .crypto .NoSuchPaddingException ;
51
55
import javax .servlet .http .HttpServletResponse ;
52
56
import javax .xml .parsers .DocumentBuilder ;
53
57
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 ;
60
59
61
60
import org .apache .http .Header ;
62
61
import org .apache .http .HttpEntity ;
62
+ import org .apache .http .NameValuePair ;
63
63
import org .apache .http .ParseException ;
64
64
import org .apache .http .client .methods .HttpPost ;
65
65
import org .apache .http .client .methods .HttpRequestBase ;
66
66
import org .apache .http .conn .ssl .NoopHostnameVerifier ;
67
67
import org .apache .http .conn .ssl .SSLConnectionSocketFactory ;
68
68
import org .apache .http .conn .ssl .TrustSelfSignedStrategy ;
69
+ import org .apache .http .message .BasicNameValuePair ;
69
70
import org .apache .http .ssl .SSLContexts ;
70
71
import org .apache .http .util .EntityUtils ;
71
72
72
73
import org .owasp .benchmark .service .pojo .StringMessage ;
73
74
import org .owasp .benchmark .score .BenchmarkScore ;
74
75
import org .owasp .benchmark .tools .AbstractTestCaseRequest ;
76
+ import org .owasp .benchmark .tools .AbstractTestCaseRequest .TestCaseType ;
75
77
import org .owasp .benchmark .tools .ServletTestCaseRequest ;
76
78
import org .owasp .benchmark .tools .XMLCrawler ;
77
79
78
80
import org .owasp .esapi .ESAPI ;
79
81
import org .w3c .dom .Document ;
80
- //import org.w3c.dom.Element;
81
82
import org .w3c .dom .Node ;
82
83
import org .xml .sax .InputSource ;
83
- // import org.xml.sax.SAXException;
84
+ import org .xml .sax .SAXException ;
84
85
85
86
public class Utils {
86
87
87
88
// Properties used by the generated test suite
88
89
89
90
public static final String USERDIR = System .getProperty ("user.dir" ) + File .separator ;
90
91
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
92
94
public static final String TESTFILES_DIR = USERDIR + "testfiles" + File .separator ;
93
95
94
96
public static final String DATA_DIR = USERDIR + "data" + File .separator ;
95
97
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 ;
98
100
99
101
// This constant is used by some of the generated Java test cases
100
102
public static final Set <String > commonHeaders = new HashSet <>(Arrays .asList ("host" , "user-agent" , "accept" ,
@@ -149,12 +151,11 @@ public class Utils {
149
151
}
150
152
}
151
153
152
- public static String getCookie ( HttpServletRequest request , String paramName ) {
154
+ public static String getCookie (HttpServletRequest request , String paramName ) {
153
155
Cookie [] values = request .getCookies ();
154
156
String param = "none" ;
155
157
if (paramName != null ) {
156
- for (int i = 0 ; i < values .length ; i ++)
157
- {
158
+ for (int i = 0 ; i < values .length ; i ++) {
158
159
if (values [i ].getName ().equals (paramName )) {
159
160
param = values [i ].getValue ();
160
161
break ; // break out of for loop when param found
@@ -163,8 +164,8 @@ public static String getCookie( HttpServletRequest request, String paramName ) {
163
164
}
164
165
return param ;
165
166
}
166
-
167
- public static String getParam ( HttpServletRequest request , String paramName ) {
167
+
168
+ public static String getParam (HttpServletRequest request , String paramName ) {
168
169
String param = request .getParameter (paramName );
169
170
return param ;
170
171
}
@@ -289,7 +290,8 @@ public static File getFileFromClasspath(String fileName, ClassLoader classLoader
289
290
System .out .println ("The file '" + fileName + "' from the classpath cannot be loaded." );
290
291
e .printStackTrace ();
291
292
}
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." );
293
295
return null ;
294
296
}
295
297
@@ -331,6 +333,11 @@ public static List<String> getLinesFromFile(String filename) {
331
333
return getLinesFromFile (new File (filename ));
332
334
}
333
335
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
+ */
334
341
public static String encodeForHTML (Object param ) {
335
342
336
343
String value = "objectTypeUnknown" ;
@@ -353,31 +360,31 @@ public static String encodeForHTML(Object param) {
353
360
return ESAPI .encoder ().encodeForHTML (value );
354
361
}
355
362
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
+ }
368
374
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 ));
372
384
373
- } catch (IOException e1 ) {
374
- result = false ;
375
- e1 .printStackTrace ();
376
- } finally {
377
- os .close ();
385
+ for (String line : contentLines ) {
386
+ os .println (line );
378
387
}
379
-
380
- return result ;
381
388
}
382
389
383
390
public static boolean writeLineToFile (Path pathToFileDir , String completeName , String line ) {
@@ -387,10 +394,7 @@ public static boolean writeLineToFile(Path pathToFileDir, String completeName, S
387
394
Files .createDirectories (pathToFileDir );
388
395
File f = new File (completeName );
389
396
if (!f .exists ()) {
390
- // System.out.println("Archivo llamado: " +
391
- // f.getAbsolutePath());
392
397
f .createNewFile ();
393
- // System.out.println("Archivo no existia se creoooooooooo");
394
398
}
395
399
FileOutputStream fos = new FileOutputStream (f , true );
396
400
os = new PrintStream (fos );
@@ -420,14 +424,13 @@ public static boolean deleteFile(String completeName) {
420
424
}
421
425
422
426
/**
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.
431
434
* @return A List of TestCaseRequest objects based on the file contents.
432
435
* @throws Exception
433
436
*/
@@ -505,7 +508,7 @@ public static boolean deleteFile(String completeName) {
505
508
return requests;
506
509
}
507
510
*/
508
- public static String getCrawlerBenchmarkVersion (InputStream http ) throws Exception {
511
+ public static String getCrawlerTestSuiteVersion (InputStream http ) throws Exception {
509
512
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory .newInstance ();
510
513
DocumentBuilder docBuilder = docBuilderFactory .newDocumentBuilder ();
511
514
InputSource is = new InputSource (http );
@@ -515,41 +518,83 @@ public static String getCrawlerBenchmarkVersion(InputStream http) throws Excepti
515
518
return XMLCrawler .getAttributeValue ("version" , root );
516
519
}
517
520
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 {
525
522
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 );
530
539
}
531
540
return requests ;
532
541
}
533
542
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 );
537
549
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 );
539
563
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 ));
544
574
545
575
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 );
550
583
}
551
584
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 ;
553
598
}
554
599
555
600
public static List <String > readCSVFailedTC (String csvFile ) {
@@ -574,7 +619,8 @@ public static List<String> readCSVFailedTC(String csvFile) {
574
619
/*
575
620
* A utility method used by the generated Java Cipher test cases.
576
621
*/
577
- private static javax .crypto .Cipher cipher = null ;
622
+ private static javax .crypto .Cipher cipher = null ;
623
+
578
624
public static Cipher getCipher () {
579
625
if (cipher == null ) {
580
626
try {
0 commit comments