From 8944bfcc1dbfbcacc814431e58325d8da1e62709 Mon Sep 17 00:00:00 2001 From: Philippe Steinbach Date: Mon, 26 Nov 2018 17:55:21 +0100 Subject: [PATCH] implemented xss mitigation assignment 1, draft validation without parser --- .../plugin/CrossSiteScriptingLesson3.java | 35 +++----- .../html/CrossSiteScriptingMitigation.html | 4 + .../resources/i18n/WebGoatLabels.properties | 4 + .../en/CrossSiteScripting_content8a.adoc | 80 +++++++------------ .../en/CrossSiteScripting_content8b.adoc | 65 +++++++++++++++ 5 files changed, 115 insertions(+), 73 deletions(-) create mode 100644 webgoat-lessons/cross-site-scripting/src/main/resources/lessonPlans/en/CrossSiteScripting_content8b.adoc diff --git a/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson3.java b/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson3.java index f5e04a96a..850fd1985 100644 --- a/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson3.java +++ b/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson3.java @@ -18,43 +18,34 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; @AssignmentPath("CrossSiteScripting/attack3") -//@AssignmentHints(value = {"SqlStringInjectionHint-mitigation-10b-1", "SqlStringInjectionHint-mitigation-10b-2", "SqlStringInjectionHint-mitigation-10b-3"}) +@AssignmentHints(value = {"mitigation-3-hint1", "mitigation-3-hint2", "mitigation-3-hint3", "mitigation-3-hint4"}) public class CrossSiteScriptingLesson3 extends AssignmentEndpoint { @RequestMapping(method = RequestMethod.POST) @ResponseBody public AttackResult completed(@RequestParam String editor) { - String regex1 = "<(\\\"[^\\\"]*\\\"|'[^']*'|[^'\\\">])*>(.*<(\\\"[^\\\"]*\\\"|'[^']*'|[^'\\\">])*>)?"; //Insert regex to verify html editor = editor.replaceAll("\\<.*?>",""); - boolean hasImportant = this.check_text(regex1, editor.replace("\n", "").replace("\r", "")); - //http://www.java67.com/2012/10/how-to-escape-html-special-characters-JSP-Java-Example.html // - // + // //or //${fn:escapeXml("param.first_name/last_name")} //check html string for regex //check for c:out && escapeXml="true" && !request.getParameter - /** - if(hasImportant && hasCompiled.size() < 1) { + System.out.println(editor); + if (editor.contains("c:out") && editor.contains("escapeXml=\"true\"") && editor.contains("value=\"${last_name}\"") && editor.contains("value=\"${first_name}\"")) { + System.out.println("true"); return trackProgress(success().build()); - } else if(hasCompiled.size() > 1) { - for(Diagnostic d : hasCompiled) { - errors += d.getMessage(null) + "\n"; - } } - **/ - return trackProgress(failed().build()); - - } - - private boolean check_text(String regex, String text) { - Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE); - Matcher m = p.matcher(text); - if(m.find()) - return true; - else return false; + else if (editor.contains("${fn:escapeXml") && editor.contains("\"param.first_name\"") && editor.contains("\"param.last_name\"")) { + System.out.println("true"); + return trackProgress(success().build()); + } + else { + System.out.println("false"); + return trackProgress(failed().build()); + } } } diff --git a/webgoat-lessons/cross-site-scripting/src/main/resources/html/CrossSiteScriptingMitigation.html b/webgoat-lessons/cross-site-scripting/src/main/resources/html/CrossSiteScriptingMitigation.html index f8729a0c8..c01ed1ece 100644 --- a/webgoat-lessons/cross-site-scripting/src/main/resources/html/CrossSiteScriptingMitigation.html +++ b/webgoat-lessons/cross-site-scripting/src/main/resources/html/CrossSiteScriptingMitigation.html @@ -12,6 +12,10 @@
+
+ +
+
diff --git a/webgoat-lessons/cross-site-scripting/src/main/resources/i18n/WebGoatLabels.properties b/webgoat-lessons/cross-site-scripting/src/main/resources/i18n/WebGoatLabels.properties index 2bca3fd31..be093abfe 100644 --- a/webgoat-lessons/cross-site-scripting/src/main/resources/i18n/WebGoatLabels.properties +++ b/webgoat-lessons/cross-site-scripting/src/main/resources/i18n/WebGoatLabels.properties @@ -30,3 +30,7 @@ xss-stored-comment-success=It appears your payload should invoke the function. T xss-stored-comment-failure=We can't see the payload in your submission, but XSS can be tricky. Look for the call back fired after the comments reload. If you see that and can put the correct value there and put it in, maybe you did succeed. xss-stored-callback-success=Yes, that is the correct value (note, it will be a different value each time the phoneHome endpoint is called). xss-stored-callback-failure=No, that is not the correct value (note, it will be a different value each time the phoneHome endpoint is called). +xss-mitigation-3-hint1=You don't store the user input in this example. Try to escape the user input right before you it into the HTML element. +xss-mitigation-3-hint2=Use JavaServer Pages Standard Tag Library (JSTL) tags or Unified Expression Language +xss-mitigation-3-hint3=You don't have to import the libs. (<%@ taglib uri = "http://java.sun.com/jsp/jstl/core" prefix = "c" %> and <%@ taglib uri = "http://java.sun.com/jsp/jstl/functions" prefix = "fn" %> already included in this example) +xss-mitigation-3-hint4=Have you ever heared of escapeXml? Ask the web. \ No newline at end of file diff --git a/webgoat-lessons/cross-site-scripting/src/main/resources/lessonPlans/en/CrossSiteScripting_content8a.adoc b/webgoat-lessons/cross-site-scripting/src/main/resources/lessonPlans/en/CrossSiteScripting_content8a.adoc index 7274f55e6..b1e5dad5d 100644 --- a/webgoat-lessons/cross-site-scripting/src/main/resources/lessonPlans/en/CrossSiteScripting_content8a.adoc +++ b/webgoat-lessons/cross-site-scripting/src/main/resources/lessonPlans/en/CrossSiteScripting_content8a.adoc @@ -1,65 +1,43 @@ -== Reflective XSS +== What is encoding -See the HTML file below which passes data to a JSP file. +Not trusting user input means validating data for type, length, format and range whenever it passes through a trust boundary, +say from a Web form to an application script, and then encoding it prior to redisplay in a dynamic page. -[source,html] -------------------------------------------------------- - - +In practice, this means that you need to review every point on your site where user-supplied data is handled and processed and +ensure that, before being passed back to the user, any values accepted from the client side are checked, filtered and encoded. - - First Name: -
- Last Name: - -
+Client-side validation cannot be relied upon, but user input can be forced down to a minimal alphanumeric set with server-side +processing before being used by a Web application in any way. - - -------------------------------------------------------- +== Escaping -Here is the JSP file: +Escaping means that you convert (or mark) key characters of the data to prevent it from being interpreted in a dangerous context. +In the case of HTML output, you need to convert the < and > characters (among others), to prevent any malicious code from rendering. +Escaping these characters involves turning them into their entity equivalents \< and \>, +which will not be interpreted as HTML tags by a browser. -[source,html] -------------------------------------------------------- - - - Using GET and POST Method to Read Form Data - +== Special characters - -
-

Using POST Method to Read Form Data

+You need to encode special characters like "<" and ">" before they are redisplayed if they are received from user input. +For example, encoding "<" and ">" ensures a browser will display ----- - -=== It's your turn! - -Try to prevent this kind of XSS by escaping the url parameters: diff --git a/webgoat-lessons/cross-site-scripting/src/main/resources/lessonPlans/en/CrossSiteScripting_content8b.adoc b/webgoat-lessons/cross-site-scripting/src/main/resources/lessonPlans/en/CrossSiteScripting_content8b.adoc new file mode 100644 index 000000000..b79e51743 --- /dev/null +++ b/webgoat-lessons/cross-site-scripting/src/main/resources/lessonPlans/en/CrossSiteScripting_content8b.adoc @@ -0,0 +1,65 @@ +== Reflective XSS + +See the HTML file below which passes data to a JSP file. + +[source,html] +------------------------------------------------------- + + + +
+ First Name: +
+ Last Name: + +
+ + + +------------------------------------------------------- + +Here is the JSP file: + +[source,html] +------------------------------------------------------- + + + Using GET and POST Method to Read Form Data + + + +
+

Using POST Method to Read Form Data

+ +
    +
  • First Name: + <%= request.getParameter("first_name")%> +

  • +
  • Last Name: + <%= request.getParameter("last_name")%> +

  • +
+ + + +------------------------------------------------------- + + +As you can see the JSP file prints unfiltered user input which is never a good idea. +You want people to accesses the page like this: + +---- +http://hostname.com/mywebapp/main.jsp?first_name=John&last_name=Smith +---- + +But what happens if someone uses this link: +---- +http://hostname.com/mywebapp/main.jsp?first_name= +---- + +=== It's your turn! + +Try to prevent this kind of XSS by escaping the url parameters in the JSP file: + + +