2121import java .io .BufferedReader ;
2222import java .io .ByteArrayOutputStream ;
2323import java .io .File ;
24+ import java .io .FileInputStream ;
2425import java .io .FileNotFoundException ;
2526import java .io .FileOutputStream ;
2627import java .io .FileReader ;
3334import java .net .URL ;
3435import java .nio .file .Files ;
3536import java .nio .file .Path ;
37+ import static java .nio .file .StandardOpenOption .APPEND ;
38+ import static java .nio .file .StandardOpenOption .CREATE ;
3639import java .nio .file .attribute .PosixFilePermission ;
3740import java .security .InvalidKeyException ;
3841import java .security .NoSuchAlgorithmException ;
4245import java .util .HashSet ;
4346import java .util .List ;
4447import java .util .Set ;
48+ import java .util .Vector ;
4549
4650import javax .crypto .Cipher ;
4751import javax .crypto .NoSuchPaddingException ;
5155import javax .servlet .http .HttpServletResponse ;
5256import javax .xml .parsers .DocumentBuilder ;
5357import 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
6160import org .apache .http .Header ;
6261import org .apache .http .HttpEntity ;
62+ import org .apache .http .NameValuePair ;
6363import org .apache .http .ParseException ;
6464import org .apache .http .client .methods .HttpPost ;
6565import org .apache .http .client .methods .HttpRequestBase ;
6666import org .apache .http .conn .ssl .NoopHostnameVerifier ;
6767import org .apache .http .conn .ssl .SSLConnectionSocketFactory ;
6868import org .apache .http .conn .ssl .TrustSelfSignedStrategy ;
69+ import org .apache .http .message .BasicNameValuePair ;
6970import org .apache .http .ssl .SSLContexts ;
7071import org .apache .http .util .EntityUtils ;
7172
7273import org .owasp .benchmark .service .pojo .StringMessage ;
7374import org .owasp .benchmark .score .BenchmarkScore ;
7475import org .owasp .benchmark .tools .AbstractTestCaseRequest ;
76+ import org .owasp .benchmark .tools .AbstractTestCaseRequest .TestCaseType ;
7577import org .owasp .benchmark .tools .ServletTestCaseRequest ;
7678import org .owasp .benchmark .tools .XMLCrawler ;
7779
7880import org .owasp .esapi .ESAPI ;
7981import org .w3c .dom .Document ;
80- //import org.w3c.dom.Element;
8182import org .w3c .dom .Node ;
8283import org .xml .sax .InputSource ;
83- // import org.xml.sax.SAXException;
84+ import org .xml .sax .SAXException ;
8485
8586public 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