From 259e7deafaad66955e434aaa3bde2a585d85023c Mon Sep 17 00:00:00 2001 From: deeplaxmi1011 Date: Wed, 12 Jul 2023 14:24:07 +0530 Subject: [PATCH] 1st --- lang/.DS_Store | Bin 0 -> 6148 bytes .../anonymous-ldap-bind.java | 20 + .../cookie-missing-httponly.java | 21 + .../cookie-missing-secure.java | 21 + .../deprecated-cipher-mode.java | 37 ++ lang/deprecated-des/deprecated-des.java | 19 + lang/deprecated-md5/deprecated-md5.java | 11 + lang/deprecated-sha-1/deprecated-sha-1.java | 11 + lang/deprecated-ssl/deprecated-ssl.java | 26 + lang/deprecated-tdes/deprecated-tdes.java | 19 + .../insecure-esapi-config.java | 25 + .../insecure-hexadecimal-conversion.java | 27 + ...ecure-implementation-hostnameverifier.java | 15 + .../insecure-implementation-trustmanager.java | 20 + ...try-poisoning-object-returning-search.java | 37 ++ lang/no-padding-rsa/no-padding-rsa.java | 19 + .../permissive-cors-policy.java | 17 + .../predictable-random-number-generator.java | 12 + .../taint-backend-cmd-exec-runtime.java | 69 +++ ...kend-code-injection-scriptengine-eval.java | 22 + ...ckend-connection-setschema-setcatalog.java | 17 + ...end-deserialization-objectinputstream.java | 107 ++++ ...ackend-el-injection-expressionfactory.java | 25 + ...end-file-disclosure-requestdispatcher.java | 23 + ...int-backend-httpservletresponse-write.java | 27 + .../taint-backend-ldap-injection-search.java | 25 + .../taint-backend-log-injection-logger.java | 51 ++ .../taint-backend-path-traversal-file.java | 60 +++ .../taint-backend-sql-injection-generic.java | 383 ++++++++++++++ ...kend-url-redirect-httpservletresponse.java | 66 +++ .../taint-backend-xxe-jaxb-unmarshaller.java | 136 +++++ .../taint-backend-xxe-xmldecoder.java | 66 +++ .../unencrypted-socket.java | 19 + .../url-rewriting-httpservletresponse.java | 63 +++ .../use-of-null-cipher.java | 18 + ...sl-certificate-validation-simpleemail.java | 54 ++ .../deprecated-defaulthttpclient.java | 15 + ...nt-backend-url-redirect-actionforward.java | 41 ++ .../variable-query-ognl.java | 87 ++++ .../taint-backend-sql-injection-jdbc.java | 475 ++++++++++++++++++ ...int-backend-url-redirect-modelandview.java | 50 ++ .../taint-backend-spel-injection.java | 75 +++ 42 files changed, 2331 insertions(+) create mode 100644 lang/.DS_Store create mode 100644 lang/anonymous-ldap-bind/anonymous-ldap-bind.java create mode 100644 lang/cookie-missing-httponly/cookie-missing-httponly.java create mode 100644 lang/cookie-missing-secure/cookie-missing-secure.java create mode 100644 lang/deprecated-cipher-mode/deprecated-cipher-mode.java create mode 100644 lang/deprecated-des/deprecated-des.java create mode 100644 lang/deprecated-md5/deprecated-md5.java create mode 100644 lang/deprecated-sha-1/deprecated-sha-1.java create mode 100644 lang/deprecated-ssl/deprecated-ssl.java create mode 100644 lang/deprecated-tdes/deprecated-tdes.java create mode 100644 lang/insecure-esapi-config/insecure-esapi-config.java create mode 100644 lang/insecure-hexadecimal-conversion/insecure-hexadecimal-conversion.java create mode 100644 lang/insecure-implementation-hostnameverifier/insecure-implementation-hostnameverifier.java create mode 100644 lang/insecure-implementation-trustmanager/insecure-implementation-trustmanager.java create mode 100644 lang/ldap-entry-poisoning-object-returning-search/ldap-entry-poisoning-object-returning-search.java create mode 100644 lang/no-padding-rsa/no-padding-rsa.java create mode 100644 lang/permissive-cors-policy/permissive-cors-policy.java create mode 100644 lang/predictable-random-number-generator/predictable-random-number-generator.java create mode 100644 lang/taint-backend-cmd-exec-runtime/taint-backend-cmd-exec-runtime.java create mode 100644 lang/taint-backend-code-injection-scriptengine-eval/taint-backend-code-injection-scriptengine-eval.java create mode 100644 lang/taint-backend-connection-setschema-setcatalog/taint-backend-connection-setschema-setcatalog.java create mode 100644 lang/taint-backend-deserialization-objectinputstream/taint-backend-deserialization-objectinputstream.java create mode 100644 lang/taint-backend-el-injection-expressionfactory/taint-backend-el-injection-expressionfactory.java create mode 100644 lang/taint-backend-file-disclosure-requestdispatcher/taint-backend-file-disclosure-requestdispatcher.java create mode 100644 lang/taint-backend-httpservletresponse-write/taint-backend-httpservletresponse-write.java create mode 100644 lang/taint-backend-ldap-injection-search/taint-backend-ldap-injection-search.java create mode 100644 lang/taint-backend-log-injection-logger/taint-backend-log-injection-logger.java create mode 100644 lang/taint-backend-path-traversal-file/taint-backend-path-traversal-file.java create mode 100644 lang/taint-backend-sql-injection-generic/taint-backend-sql-injection-generic.java create mode 100644 lang/taint-backend-url-redirect-httpservletresponse/taint-backend-url-redirect-httpservletresponse.java create mode 100644 lang/taint-backend-xxe-jaxb-unmarshaller/taint-backend-xxe-jaxb-unmarshaller.java create mode 100644 lang/taint-backend-xxe-xmldecoder/taint-backend-xxe-xmldecoder.java create mode 100644 lang/unencrypted-socket/unencrypted-socket.java create mode 100644 lang/url-rewriting-httpservletresponse/url-rewriting-httpservletresponse.java create mode 100644 lang/use-of-null-cipher/use-of-null-cipher.java create mode 100644 org.apache.commons/commons-email/missing-ssl-certificate-validation-simpleemail/missing-ssl-certificate-validation-simpleemail.java create mode 100644 org.apache.httpcomponents/deprecated-defaulthttpclient/deprecated-defaulthttpclient.java create mode 100644 org.apache.struts/taint-backend-url-redirect-actionforward/taint-backend-url-redirect-actionforward.java create mode 100644 org.apache.struts/variable-query-ognl/variable-query-ognl.java create mode 100644 org.springframework/spring-jdbc/taint-backend-sql-injection-jdbc/taint-backend-sql-injection-jdbc.java create mode 100644 org.springframework/spring-web/taint-backend-url-redirect-modelandview/taint-backend-url-redirect-modelandview.java create mode 100644 org.springframework/taint-backend-spel-injection/taint-backend-spel-injection.java diff --git a/lang/.DS_Store b/lang/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0 7000) { + return failed(this).build(); + } + if (delay < 3000) { + return failed(this).build(); + } + return success(this).build(); + } +} diff --git a/lang/taint-backend-el-injection-expressionfactory/taint-backend-el-injection-expressionfactory.java b/lang/taint-backend-el-injection-expressionfactory/taint-backend-el-injection-expressionfactory.java new file mode 100644 index 0000000..aa7c9b7 --- /dev/null +++ b/lang/taint-backend-el-injection-expressionfactory/taint-backend-el-injection-expressionfactory.java @@ -0,0 +1,25 @@ +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +// Use of variable in second parameter +public class Eval { + public static void evaluateExpressionUnsafe(HttpServletRequest request, HttpServletResponse response) { + String expression = request.getParamter("expression") + FacesContext context = FacesContext.getCurrentInstance(); + ExpressionFactory expressionFactory = context.getApplication().getExpressionFactory(); + ELContext elContext = context.getELContext(); + // ruleid: taint-backend-el-injection-expressionfactory + ValueExpression vex = expressionFactory.createValueExpression(elContext, expression, String.class); + return (String) vex.getValue(elContext); + } + + public static void evaluateExpressionSafe(HttpServletRequest request, HttpServletResponse response) { + String expression = request.getParamter("expression"); + FacesContext context = FacesContext.getCurrentInstance(); + ExpressionFactory expressionFactory = context.getApplication().getExpressionFactory(); + ELContext elContext = context.getELContext(); + // ok: taint-backend-el-injection-expressionfactory + ValueExpression vex = expressionFactory.createValueExpression(elContext, "expression", String.class); + return (String) vex.getValue(elContext); + } +} \ No newline at end of file diff --git a/lang/taint-backend-file-disclosure-requestdispatcher/taint-backend-file-disclosure-requestdispatcher.java b/lang/taint-backend-file-disclosure-requestdispatcher/taint-backend-file-disclosure-requestdispatcher.java new file mode 100644 index 0000000..1e7a5b8 --- /dev/null +++ b/lang/taint-backend-file-disclosure-requestdispatcher/taint-backend-file-disclosure-requestdispatcher.java @@ -0,0 +1,23 @@ +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +// Request parameter is first passed into another function +public class Main { + public static void main(HttpServletRequest request, HttpServletResponse response) { + String returnURL = request.getParameter("returnURL"); + String a = sanitize(returnURL); + // ok: taint-backend-file-disclosure-requestdispatcher + request.getRequestDispatcher(a).include(request, response); + // ok: taint-backend-file-disclosure-requestdispatcher + request.getRequestDispatcher("success").include(request, response); + } + + // Request parameter passed straight into function + public static void doGet(HttpServletRequest request, HttpServletResponse response) { + String jspFile = request.getParameter("jspFile"); + // ruleid: taint-backend-file-disclosure-requestdispatcher + request.getRequestDispatcher("/WEB-INF/jsps/" + jspFile + ".jsp").include(request, response); + // ok: taint-backend-file-disclosure-requestdispatcher + request.getRequestDispatcher("/pathtraver-00/BenchmarkTest00001.html"); + } +} \ No newline at end of file diff --git a/lang/taint-backend-httpservletresponse-write/taint-backend-httpservletresponse-write.java b/lang/taint-backend-httpservletresponse-write/taint-backend-httpservletresponse-write.java new file mode 100644 index 0000000..0222189 --- /dev/null +++ b/lang/taint-backend-httpservletresponse-write/taint-backend-httpservletresponse-write.java @@ -0,0 +1,27 @@ +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +// No sanitization or encoding +public class Main { + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + String input1 = req.getParameter("input1"); + // ruleid: taint-backend-httpservletresponse-write + resp.getWriter().write(input1); + PrintWriter writer = resp.getWriter(); + // ruleid: taint-backend-httpservletresponse-write + writer.write(input1); + + } +} + +public class Main { + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + String input1 = req.getParameter("input1"); + // ok: taint-backend-httpservletresponse-write + resp.getWriter().write(Encode.forHtml(input1)); + + bar = (7 * 42) - num > 200 ? "This should never happen" : input1; + // todook: taint-backend-httpservletresponse-write + resp.getWriter().write(bar.toCharArray()); + } +} \ No newline at end of file diff --git a/lang/taint-backend-ldap-injection-search/taint-backend-ldap-injection-search.java b/lang/taint-backend-ldap-injection-search/taint-backend-ldap-injection-search.java new file mode 100644 index 0000000..b82970e --- /dev/null +++ b/lang/taint-backend-ldap-injection-search/taint-backend-ldap-injection-search.java @@ -0,0 +1,25 @@ +import javax.naming.directory.InitialDirContext; +import javax.naming.ldap.InitialLdapContext; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +// Usage of string concatenation +public class Main { + public static void main (HttpServletRequest req, HttpServletResponse resp) { + InitialLdapContext context = new InitialLdapContext(); + // ruleid: taint-backend-ldap-injection-search + NamingEnumeration answers = context.search("dc=People,dc=example,dc=com", + "(uid=" + req.getParam("username") + ")", ctrls); + } + + public static void mainSecure (HttpServletRequest req, HttpServletResponse resp) { + InitialLdapContext context = new InitialLdapContext(); + String username = req.getParam("username"); + if(StringUtils.isAlphanumeric(username)) { + // todook: taint-backend-ldap-injection-search + NamingEnumeration answers = context.search("dc=People,dc=example,dc=com", + "(uid=" + username + ")", ctrls); + } + } +} \ No newline at end of file diff --git a/lang/taint-backend-log-injection-logger/taint-backend-log-injection-logger.java b/lang/taint-backend-log-injection-logger/taint-backend-log-injection-logger.java new file mode 100644 index 0000000..a96fc94 --- /dev/null +++ b/lang/taint-backend-log-injection-logger/taint-backend-log-injection-logger.java @@ -0,0 +1,51 @@ +import javax.servlet.http.HttpServletResponse; + +// No sanitization +public class Main { + Logger log = new Logger(); + public static void main(HttpServletRequest request, HttpServletResponse response) { + String val = request.getParameter("user"); + if(authenticated) { + // ruleid: taint-backend-log-injection-logger + log.info("User " + val + ") was authenticated successfully"); + } + else { + // ruleid: taint-backend-log-injection-logger + log.info("User " + val + ") was not authenticated"); + } + } +} + +// With sanitization +public class Main { + Logger log = new Logger(); + public static void main(HttpServletRequest request, HttpServletResponse response) { + String val = request.getParameter("user"); + val = sanitize(val); + if(authenticated) { + // ok: taint-backend-log-injection-logger + log.info("User " + val + ") was authenticated successfully"); + } + else { + // ok: taint-backend-log-injection-logger + log.info("User " + val + ") was not authenticated"); + } + } +} + +// With sanitization by side effect +public class Main { + Logger log = new Logger(); + public static void main(HttpServletRequest request, HttpServletResponse response) { + String val = request.getParameter("user"); + sanitize(val); + if(authenticated) { + // ok: taint-backend-log-injection-logger + log.info("User " + val + ") was authenticated successfully"); + } + else { + // ok: taint-backend-log-injection-logger + log.info("User " + val + ") was not authenticated"); + } + } +} \ No newline at end of file diff --git a/lang/taint-backend-path-traversal-file/taint-backend-path-traversal-file.java b/lang/taint-backend-path-traversal-file/taint-backend-path-traversal-file.java new file mode 100644 index 0000000..35b0969 --- /dev/null +++ b/lang/taint-backend-path-traversal-file/taint-backend-path-traversal-file.java @@ -0,0 +1,60 @@ +import java.util.Scanner; +import org.apache.commons.io.FilenameUtils; +import java.io.File; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.core.Response; + + +// Using path with input sanitization outside the function +// Currently false positive +public class Main { + + Response getImage(@javax.ws.rs.PathParam("image") String image) { + String safe = FilenameUtils.getName(image); + // ok: taint-backend-path-traversal-file + File file = new File("resources/images/", safe); + if (!file.exists()) { + return Response.status(Status.NOT_FOUND).build(); + } + return Response.ok().entity(new FileInputStream(file)).build(); + } +} + +// Using path with input sanitization inside the function +public class Main { + public static void main() { + Scanner in = new Scanner(System.in); + String image = in.nextLine(); + getImage(image); + } + Response getImage(@javax.ws.rs.PathParam("image") String image) { + String safePath = sanitize(image); + // ok: taint-backend-path-traversal-file + File file = new File("resources/images/", safePath); + if (!file.exists()) { + return Response.status(Status.NOT_FOUND).build(); + } + // ok: taint-backend-path-traversal-file + return Response.ok().entity(new FileInputStream(file)).build(); + } +} + +// Using path without input validation +public class Main { + public static void main() { + Scanner in = new Scanner(System.in); + String image = in.nextLine(); + getImage(image); + } + public Response getImage(@javax.ws.rs.PathParam("image") String image) { + // ruleid: taint-backend-path-traversal-file + File file = new File("resources/images/", image); + if (!file.exists()) { + return Response.status(Status.NOT_FOUND).build(); + } + // ruleid: taint-backend-path-traversal-file + return Response.ok().entity(new FileInputStream(file)).build(); + } +} \ No newline at end of file diff --git a/lang/taint-backend-sql-injection-generic/taint-backend-sql-injection-generic.java b/lang/taint-backend-sql-injection-generic/taint-backend-sql-injection-generic.java new file mode 100644 index 0000000..7c4eb6c --- /dev/null +++ b/lang/taint-backend-sql-injection-generic/taint-backend-sql-injection-generic.java @@ -0,0 +1,383 @@ +/** + * OWASP Benchmark v1.2 + * + *

This file is part of the Open Web Application Security Project (OWASP) Benchmark Project. For + * details, please see https://owasp.org/www-project-benchmark/. + * + *

The OWASP Benchmark is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Foundation, version 2. + * + *

The OWASP Benchmark is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * @author Dave Wichers + * @created 2015 + */ +package org.owasp.benchmark.testcode; + +import java.io.IOException; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@WebServlet(value = "/sqli-00/BenchmarkTest00008") +public class bad1 extends HttpServlet { + + private static final long serialVersionUID = 1L; + + @Override + public void doGet(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + doPost(request, response); + } + + @Override + public void doPost(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + // some code + response.setContentType("text/html;charset=UTF-8"); + + String param = ""; + if (request.getHeader("BenchmarkTest00008") != null) { + param = request.getHeader("BenchmarkTest00008"); + } + + // URL Decode the header value since req.getHeader() doesn't. Unlike + // req.getParameter(). + param = java.net.URLDecoder.decode(param, "UTF-8"); + + String sql = "{call " + param + "}"; + + try { + java.sql.Connection connection = org.owasp.benchmark.helpers.DatabaseHelper.getSqlConnection(); + // ruleid: taint-backend-sql-injection-generic + java.sql.CallableStatement statement = connection.prepareCall(sql); + java.sql.ResultSet rs = statement.executeQuery(); + org.owasp.benchmark.helpers.DatabaseHelper.printResults(rs, sql, response); + + } catch (java.sql.SQLException e) { + if (org.owasp.benchmark.helpers.DatabaseHelper.hideSQLErrors) { + response.getWriter().println("Error processing request."); + return; + } else + throw new ServletException(e); + } + } +} + +@WebServlet(value = "/sqli-00/BenchmarkTest00018") +public class bad2 extends HttpServlet { + + private static final long serialVersionUID = 1L; + + @Override + public void doGet(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + doPost(request, response); + } + + @Override + public void doPost(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + // some code + response.setContentType("text/html;charset=UTF-8"); + + String param = ""; + java.util.Enumeration headers = request.getHeaders("BenchmarkTest00018"); + + if (headers != null && headers.hasMoreElements()) { + param = headers.nextElement(); // just grab first element + } + + // URL Decode the header value since req.getHeaders() doesn't. Unlike + // req.getParameters(). + param = java.net.URLDecoder.decode(param, "UTF-8"); + + String sql = "INSERT INTO users (username, password) VALUES ('foo','" + param + "')"; + + try { + java.sql.Statement statement = org.owasp.benchmark.helpers.DatabaseHelper.getSqlStatement(); + // ruleid: taint-backend-sql-injection-generic + int count = statement.executeUpdate(sql); + org.owasp.benchmark.helpers.DatabaseHelper.outputUpdateComplete(sql, response); + } catch (java.sql.SQLException e) { + if (org.owasp.benchmark.helpers.DatabaseHelper.hideSQLErrors) { + response.getWriter().println("Error processing request."); + return; + } else + throw new ServletException(e); + } + } +} + +@WebServlet(value = "/sqli-00/BenchmarkTest00024") +public class bad3 extends HttpServlet { + + private static final long serialVersionUID = 1L; + + @Override + public void doGet(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + doPost(request, response); + } + + @Override + public void doPost(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + // some code + response.setContentType("text/html;charset=UTF-8"); + + String param = request.getParameter("BenchmarkTest00024"); + if (param == null) + param = ""; + + String sql = "SELECT * from USERS where USERNAME=? and PASSWORD='" + param + "'"; + + try { + java.sql.Connection connection = org.owasp.benchmark.helpers.DatabaseHelper.getSqlConnection(); + // ruleid: taint-backend-sql-injection-generic + java.sql.PreparedStatement statement = connection.prepareStatement( + // ruleid: taint-backend-sql-injection-generic + sql, + java.sql.ResultSet.TYPE_FORWARD_ONLY, + java.sql.ResultSet.CONCUR_READ_ONLY, + java.sql.ResultSet.CLOSE_CURSORS_AT_COMMIT); + statement.setString(1, "foo"); + statement.execute(); + org.owasp.benchmark.helpers.DatabaseHelper.printResults(statement, sql, response); + } catch (java.sql.SQLException e) { + if (org.owasp.benchmark.helpers.DatabaseHelper.hideSQLErrors) { + response.getWriter().println("Error processing request."); + return; + } else + throw new ServletException(e); + } + } +} + +@WebServlet(value = "/sqli-00/BenchmarkTest00025") +public class bad4 extends HttpServlet { + + private static final long serialVersionUID = 1L; + + @Override + public void doGet(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + doPost(request, response); + } + + @Override + public void doPost(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + // some code + response.setContentType("text/html;charset=UTF-8"); + + String param = request.getParameter("BenchmarkTest00025"); + if (param == null) + param = ""; + + String sql = "SELECT userid from USERS where USERNAME='foo' and PASSWORD='" + param + "'"; + try { + // No longer needed - covered by JDBC specific rule + // + // Long results = + // org.owasp.benchmark.helpers.DatabaseHelper.JDBCtemplate.queryForLong(sql); + // Long results = + // org.owasp.benchmark.helpers.DatabaseHelper.JDBCtemplate.queryForObject( + // sql, Long.class); + response.getWriter().println("Your results are: " + String.valueOf(results)); + } catch (org.springframework.dao.EmptyResultDataAccessException e) { + response.getWriter() + .println( + "No results returned for query: " + + org.owasp.esapi.ESAPI.encoder().encodeForHTML(sql)); + } catch (org.springframework.dao.DataAccessException e) { + if (org.owasp.benchmark.helpers.DatabaseHelper.hideSQLErrors) { + response.getWriter().println("Error processing request."); + } else + throw new ServletException(e); + } + } +} + +@WebServlet(value = "/sqli-00/BenchmarkTest00026") +public class bad5 extends HttpServlet { + + private static final long serialVersionUID = 1L; + + @Override + public void doGet(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + doPost(request, response); + } + + @Override + public void doPost(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + // some code + response.setContentType("text/html;charset=UTF-8"); + + String param = request.getParameter("BenchmarkTest00026"); + if (param == null) + param = ""; + + String sql = "SELECT * from USERS where USERNAME='foo' and PASSWORD='" + param + "'"; + try { + // It is not necessary to cover this as it is covered by the JDBC specific rule + // + // org.springframework.jdbc.support.rowset.SqlRowSet results = + // org.owasp.benchmark.helpers.DatabaseHelper.JDBCtemplate.queryForRowSet(sql); + // response.getWriter().println("Your results are: "); + + // System.out.println("Your results are"); + while (results.next()) { + response.getWriter() + .println( + org.owasp.esapi.ESAPI + .encoder() + .encodeForHTML(results.getString("USERNAME")) + + " "); + // System.out.println(results.getString("USERNAME")); + } + } catch (org.springframework.dao.EmptyResultDataAccessException e) { + response.getWriter() + .println( + "No results returned for query: " + + org.owasp.esapi.ESAPI.encoder().encodeForHTML(sql)); + } catch (org.springframework.dao.DataAccessException e) { + if (org.owasp.benchmark.helpers.DatabaseHelper.hideSQLErrors) { + response.getWriter().println("Error processing request."); + } else + throw new ServletException(e); + } + } +} + +@WebServlet(value = "/sqli-00/BenchmarkTest00008") +public class bad1 extends HttpServlet { + + private static final long serialVersionUID = 1L; + + @Override + public void doGet(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + doPost(request, response); + } + + @Override + public void doPost(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + // some code + response.setContentType("text/html;charset=UTF-8"); + + String param = "test"; + + String sql = "{call " + param + "}"; + + try { + java.sql.Connection connection = org.owasp.benchmark.helpers.DatabaseHelper.getSqlConnection(); + // ok: taint-backend-sql-injection-generic + java.sql.CallableStatement statement = connection.prepareCall(sql); + java.sql.ResultSet rs = statement.executeQuery(); + org.owasp.benchmark.helpers.DatabaseHelper.printResults(rs, sql, response); + + } catch (java.sql.SQLException e) { + if (org.owasp.benchmark.helpers.DatabaseHelper.hideSQLErrors) { + response.getWriter().println("Error processing request."); + return; + } else + throw new ServletException(e); + } + } +} + +public class Util { + + private static final long serialVersionUID = 1L; + + public static void executeSql(String sql) { + java.sql.Connection connection = org.owasp.benchmark.helpers.DatabaseHelper.getSqlConnection(); + // ok: taint-backend-sql-injection-generic + connection.prepareCall(sql).executeQuery(); + } + +} + +public class Util { + + private static final long serialVersionUID = 1L; + + public static void executeSql(String sql) { + java.sql.Connection connection = org.owasp.benchmark.helpers.DatabaseHelper.getSqlConnection(); + // ok: taint-backend-sql-injection-generic + connection.prepareCall(sql).executeQuery(); + } + +} + +@WebServlet(value = "/sqli-03/BenchmarkTest01811") +public class BenchmarkTest01811 extends HttpServlet { + + private static final long serialVersionUID = 1L; + + @Override + public void doGet(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + doPost(request, response); + } + + @Override + public void doPost(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + response.setContentType("text/html;charset=UTF-8"); + + org.owasp.benchmark.helpers.SeparateClassRequest scr = new org.owasp.benchmark.helpers.SeparateClassRequest( + request); + String param = scr.getTheValue("BenchmarkTest01811"); + + String bar = new Test().doSomething(request, param); + + String sql = "SELECT TOP 1 userid from USERS where USERNAME='foo' and PASSWORD='" + bar + "'"; + try { + // ruleid: taint-backend-sql-injection-generic + java.util.Map results = org.owasp.benchmark.helpers.DatabaseHelper.JDBCtemplate .queryForMap(sql); + response.getWriter().println("Your results are: "); + + // System.out.println("Your results are"); + response.getWriter() + .println(org.owasp.esapi.ESAPI.encoder().encodeForHTML(results.toString())); + // System.out.println(results.toString()); + } catch (org.springframework.dao.EmptyResultDataAccessException e) { + response.getWriter() + .println( + "No results returned for query: " + + org.owasp.esapi.ESAPI.encoder().encodeForHTML(sql)); + } catch (org.springframework.dao.DataAccessException e) { + if (org.owasp.benchmark.helpers.DatabaseHelper.hideSQLErrors) { + response.getWriter().println("Error processing request."); + } else + throw new ServletException(e); + } + } // end doPost + + private class Test { + + public String doSomething(HttpServletRequest request, String param) + throws ServletException, IOException { + + String bar = "safe!"; + java.util.HashMap map31047 = new java.util.HashMap(); + map31047.put("keyA-31047", "a_Value"); // put some stuff in the collection + map31047.put("keyB-31047", param); // put it in a collection + map31047.put("keyC", "another_Value"); // put some stuff in the collection + bar = (String) map31047.get("keyB-31047"); // get it back out + bar = (String) map31047.get("keyA-31047"); // get safe value back out + + return bar; + } + } // end innerclass Test +} // end DataflowThruInnerClass diff --git a/lang/taint-backend-url-redirect-httpservletresponse/taint-backend-url-redirect-httpservletresponse.java b/lang/taint-backend-url-redirect-httpservletresponse/taint-backend-url-redirect-httpservletresponse.java new file mode 100644 index 0000000..063f30c --- /dev/null +++ b/lang/taint-backend-url-redirect-httpservletresponse/taint-backend-url-redirect-httpservletresponse.java @@ -0,0 +1,66 @@ +package testcode; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +public class UnvalidatedRedirectServlet extends HttpServlet { + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + String url = req.getParameter("urlRedirect"); + unvalidatedRedirect1(resp, url); + } + + private void unvalidatedRedirect1(HttpServletResponse resp, String url) throws IOException { + if (url != null) { + // todoruleid: taint-backend-url-redirect-httpservletresponse + resp.sendRedirect(url); + } + } + + public void unvalidatedRedirect2(HttpServletResponse resp, String url) { + if (url != null) { + // todoruleid: taint-backend-url-redirect-httpservletresponse + resp.addHeader("Location", url); + } + } + + private void unvalidatedRedirect3(HttpServletRequest req, HttpServletResponse resp) throws IOException { + // ruleid: taint-backend-url-redirect-httpservletresponse + resp.sendRedirect(req.getParameter("urlRedirect")); + } + + public void unvalidatedRedirect4(HttpServletRequest req, HttpServletResponse resp) { + String url = req.getParameter("urlRedirect"); + // ruleid: taint-backend-url-redirect-httpservletresponse + resp.addHeader("locAtion", url); + } + + public void falsePositiveRedirect1(HttpServletResponse resp) throws IOException { + String url = "/Home"; + if (url != null) { + // ok: taint-backend-url-redirect-httpservletresponse + resp.sendRedirect(url); + } + } + + public void falsePositiveRedirect2(HttpServletResponse resp) { + // ok: taint-backend-url-redirect-httpservletresponse + resp.addHeader("Location", "/login.jsp"); + } + public void falsePositiveRedirect3(HttpServletRequest request, HttpServletResponse response) { + // ok: taint-backend-url-redirect-httpservletresponse + response.sendRedirect(request.getContextPath()+"/vulnerability/SendMessage.jsp?status=* Message successfully sent *"); + } + + private void falsePositiveRedirect3(HttpServletResponse resp, String url) throws IOException { + if (url != null) { + url = "static Strings are irrelevant"; + // ok: taint-backend-url-redirect-httpservletresponse + resp.sendRedirect(url); + } + } +} diff --git a/lang/taint-backend-xxe-jaxb-unmarshaller/taint-backend-xxe-jaxb-unmarshaller.java b/lang/taint-backend-xxe-jaxb-unmarshaller/taint-backend-xxe-jaxb-unmarshaller.java new file mode 100644 index 0000000..ee249bd --- /dev/null +++ b/lang/taint-backend-xxe-jaxb-unmarshaller/taint-backend-xxe-jaxb-unmarshaller.java @@ -0,0 +1,136 @@ +package com.example.demo; + +import java.io.*; +import java.net.URL; +import java.nio.charset.StandardCharsets; + +import jakarta.servlet.ServletException; +import jakarta.servlet.http.*; +import jakarta.servlet.annotation.*; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.Unmarshaller; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +import javax.xml.stream.XMLInputFactory; + +@WebServlet(name = "helloServlet", value = "/hello-servlet") +public class HelloServlet extends HttpServlet { + @XmlRootElement(name = "book") + @XmlType(propOrder = {"name"}) + static class Book { + private String name; + + @XmlElement(name = "name") + public void setName(String name) { + this.name = name; + } + public String getName() { + return this.name; + } + } + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException { + unmarshall05(req.getParameter("content")); + } + + public Book unmarshall(HttpServletRequest req, HttpServletResponse res) { + try { + JAXBContext context = JAXBContext.newInstance(Book.class); + FileReader reader = new FileReader(req.getParameter("filename")); + // ruleid: taint-backend-xxe-jaxb-unmarshaller + Book book = (Book)context.createUnmarshaller().unmarshal(reader); + return book; + } + catch (Exception e) { return null; } + } + + public Book unmarshall01(HttpServletRequest req, HttpServletResponse res) { + try { + JAXBContext context = JAXBContext.newInstance(Book.class); + Part part = req.getPart("filecontent"); + Unmarshaller unmarshaller = context.createUnmarshaller(); + // ruleid: taint-backend-xxe-jaxb-unmarshaller + return (Book)unmarshaller.unmarshal(part.getInputStream()); + } + catch (Exception e) { return null; } + } + + public Book unmarshall02(HttpServletRequest req, HttpServletResponse res) { + try { + JAXBContext context = JAXBContext.newInstance(Book.class); + Unmarshaller unmarshaller = context.createUnmarshaller(); + // ruleid: taint-backend-xxe-jaxb-unmarshaller + return (Book)unmarshaller.unmarshal(new File(req.getParameter("filename"))); + } + catch (Exception e) { return null; } + } + + public Book unmarshall03(HttpServletRequest req, HttpServletResponse res) { + try { + JAXBContext context = JAXBContext.newInstance(Book.class); + Unmarshaller unmarshaller = context.createUnmarshaller(); + // ruleid: taint-backend-xxe-jaxb-unmarshaller + return (Book)unmarshaller.unmarshal(new URL(req.getParameter("url"))); + } + catch (Exception e) { return null; } + } + + public Book unmarshall04(HttpServletRequest req, HttpServletResponse res) { + try { + JAXBContext context = JAXBContext.newInstance(Book.class); + Unmarshaller unmarshaller = context.createUnmarshaller(); + String xml = req.getParameter("xmlcontent"); + // ruleid: taint-backend-xxe-jaxb-unmarshaller + return (Book)unmarshaller.unmarshal(new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8))); + } + catch (Exception e) { return null; } + } + + public Book unmarshall05(String xmlContent) { + try { + JAXBContext context = JAXBContext.newInstance(Book.class); + Unmarshaller unmarshaller = context.createUnmarshaller(); + // ruleid: taint-backend-xxe-jaxb-unmarshaller + return (Book)unmarshaller.unmarshal(new ByteArrayInputStream(xmlContent.getBytes(StandardCharsets.UTF_8))); + } + catch (Exception e) { return null; } + } + + public Book unmarshall05() { + try { + JAXBContext context = JAXBContext.newInstance(Book.class); + Unmarshaller unmarshaller = context.createUnmarshaller(); + // ok: taint-backend-xxe-jaxb-unmarshaller + return (Book)unmarshaller.unmarshal(new ByteArrayInputStream("safe".getBytes(StandardCharsets.UTF_8))); + } + catch (Exception e) { return null; } + } + + public class Comment { + private String user; + private String dateTime; + private String text; + } + + // This test is from + // https://github.com/guardrails-test/WebGoat-SemgrepTest/blob/main/src/main/java/org/owasp/webgoat/lessons/xxe/CommentsCache.java#L96 + protected Comment parseXml(String xml) throws JAXBException, XMLStreamException { + var jc = JAXBContext.newInstance(Comment.class); + var xif = XMLInputFactory.newInstance(); + + if (webSession.isSecurityEnabled()) { + xif.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, ""); // Compliant + xif.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); // compliant + } + + // ruleid: taint-backend-xxe-jaxb-unmarshaller + var xsr = xif.createXMLStreamReader(new StringReader(xml)); + + var unmarshaller = jc.createUnmarshaller(); + return (Comment) unmarshaller.unmarshal(xsr); + } +} \ No newline at end of file diff --git a/lang/taint-backend-xxe-xmldecoder/taint-backend-xxe-xmldecoder.java b/lang/taint-backend-xxe-xmldecoder/taint-backend-xxe-xmldecoder.java new file mode 100644 index 0000000..013cd45 --- /dev/null +++ b/lang/taint-backend-xxe-xmldecoder/taint-backend-xxe-xmldecoder.java @@ -0,0 +1,66 @@ +package testcode.xmldecoder; + +import java.beans.XMLDecoder; +import java.io.InputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +public class XmlDecodeUtil { + + public static void main(String[] args) { + InputStream in = XmlDecodeUtil.class.getResourceAsStream("/testcode/xmldecoder/obj1.xml"); + XmlDecodeUtil.handleXml0(in); + } + + public static Object handleXml(HttpServletRequest req, HttpServletResponse res) { + // ruleid: taint-backend-xxe-xmldecoder + XMLDecoder d = new XMLDecoder(req.getParam("in")); + try { + Object result = d.readObject(); //Deserialization happen here + return result; + } + finally { + d.close(); + } + } + + // Not sure about this one actually, because it is not confirmed tainted. + public static Object handleXml0(InputStream in) { + // todoruleid: taint-backend-xxe-xmldecoder + XMLDecoder d = new XMLDecoder(in); + try { + Object result = d.readObject(); //Deserialization happen here + return result; + } + finally { + d.close(); + } + } + + + // ok: taint-backend-xxe-xmldecoder + public static Object handleXml1() { + XMLDecoder d = new XMLDecoder("XML"); + try { + Object result = d.readObject(); + return result; + } + finally { + d.close(); + } + } + + // ok: taint-backend-xxe-xmldecoder + public static Object handleXml2() { + String strXml = "XML"; + XMLDecoder d = new XMLDecoder(strXml); + try { + Object result = d.readObject(); + return result; + } + finally { + d.close(); + } + } + +} diff --git a/lang/unencrypted-socket/unencrypted-socket.java b/lang/unencrypted-socket/unencrypted-socket.java new file mode 100644 index 0000000..1cda563 --- /dev/null +++ b/lang/unencrypted-socket/unencrypted-socket.java @@ -0,0 +1,19 @@ +// Use of unencrypted socket +public class Main { + private WEBPAGE = "www.google.com" + private HTTP_PORT = 80 + public static void main() { + // ruleid: unencrypted-socket + Socket soc = new Socket(WEBPAGE, HTTP_PORT); + } +} + +// Use of encrypted socket +public class Main { + private WEBPAGE = "www.google.com" + private HTTPS_PORT = 443 + public static void main() { + // ok: unencrypted-socket + Socket soc = SSLSocketFactory.getDefault().createSocket(WEBPAGE, HTTPS_PORT); + } +} \ No newline at end of file diff --git a/lang/url-rewriting-httpservletresponse/url-rewriting-httpservletresponse.java b/lang/url-rewriting-httpservletresponse/url-rewriting-httpservletresponse.java new file mode 100644 index 0000000..7b19b2f --- /dev/null +++ b/lang/url-rewriting-httpservletresponse/url-rewriting-httpservletresponse.java @@ -0,0 +1,63 @@ +package com.example.javaservletdemo; + +import jakarta.servlet.annotation.WebServlet; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +import java.io.IOException; +import java.io.PrintWriter; + +@WebServlet(name = "helloServlet", value = "/hello-servlet") +public class HelloServlet extends HttpServlet { + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { + String url = req.getParameter("urlRedirect"); + badRedirect1(resp, url); + } + + private void badRedirect1(HttpServletResponse resp, String url) throws IOException { + if (url != null) { + // ruleid: url-rewriting-httpservletresponse + resp.sendRedirect(resp.encodeRedirectURL(url)); + } + } + + public void badRedirect2(HttpServletResponse resp, String url) throws IOException { + if (url != null) { + // ruleid: url-rewriting-httpservletresponse + resp.sendRedirect(resp.encodeRedirectUrl(url)); + } + } + + private void badRedirect3(HttpServletRequest req, HttpServletResponse resp) throws IOException { + PrintWriter writer = resp.getWriter(); + // ruleid: url-rewriting-httpservletresponse + writer.print("Index"); + } + + private void badRedirect4(HttpServletRequest req, HttpServletResponse resp) throws IOException { + PrintWriter writer = resp.getWriter(); + // ruleid: url-rewriting-httpservletresponse + writer.print("Index"); + } + + public void badRedirect5(HttpServletRequest req, HttpServletResponse resp) throws IOException { + PrintWriter writer = resp.getWriter(); + // ruleid: url-rewriting-httpservletresponse + writer.print("Index"); + } + + public void badRedirect6(HttpServletRequest req, HttpServletResponse resp) throws IOException { + PrintWriter writer = resp.getWriter(); + // ruleid: url-rewriting-httpservletresponse + writer.print("Index"); + } + + private void goodRedirect7(HttpServletResponse resp, String url) throws IOException { + if (url != null) { + // ok: url-rewriting-httpservletresponse + resp.sendRedirect(url); + } + } +} \ No newline at end of file diff --git a/lang/use-of-null-cipher/use-of-null-cipher.java b/lang/use-of-null-cipher/use-of-null-cipher.java new file mode 100644 index 0000000..452c3fb --- /dev/null +++ b/lang/use-of-null-cipher/use-of-null-cipher.java @@ -0,0 +1,18 @@ +// Use of Null Cipher +public class Main { + public static void main() { + // ruleid: use-of-null-cipher + Cipher c = new NullCipher(); + byte[] cipherText = c.doFinal(plainText); + } +} + +// Use of AES +public class Main { + public static void main() { + // ok: use-of-null-cipher + Cipher c = Cipher.getInstance("AES/GCM/NoPadding"); + c.init(Cipher.ENCRYPT_MODE, k, iv); + byte[] cipherText = c.doFinal(plainText); + } +} \ No newline at end of file diff --git a/org.apache.commons/commons-email/missing-ssl-certificate-validation-simpleemail/missing-ssl-certificate-validation-simpleemail.java b/org.apache.commons/commons-email/missing-ssl-certificate-validation-simpleemail/missing-ssl-certificate-validation-simpleemail.java new file mode 100644 index 0000000..7c7248d --- /dev/null +++ b/org.apache.commons/commons-email/missing-ssl-certificate-validation-simpleemail/missing-ssl-certificate-validation-simpleemail.java @@ -0,0 +1,54 @@ +import org.apache.commons.mail.SimpleEmail; + +// Send email without verification +public class Main { + public static void main() { + Email email = new SimpleEmail(); + email.setHostName("smtp.servermail.com"); + email.setSmtpPort(465); + email.setAuthenticator(new DefaultAuthenticator(username, password)); + email.setSSLOnConnect(true); + email.setFrom("user@gmail.com"); + email.setSubject("TestMail"); + email.setMsg("This is a test mail ... :-)"); + email.addTo("foo@bar.com"); + // ruleid: missing-ssl-certificate-validation-simpleemail + email.send(); + } +} + +// Send email after verification +public class Main { + public static void main() { + Email email = new SimpleEmail(); + email.setHostName("smtp.servermail.com"); + email.setSmtpPort(465); + email.setAuthenticator(new DefaultAuthenticator(username, password)); + email.setSSLOnConnect(true); + email.setFrom("user@gmail.com"); + email.setSubject("TestMail"); + email.setMsg("This is a test mail ... :-)"); + email.addTo("foo@bar.com"); + email.setSSLCheckServerIdentity(true); + // ok: missing-ssl-certificate-validation-simpleemail + email.send(); + } +} + +// Send email before verification +public class Main { + public static void main() { + Email email = new SimpleEmail(); + email.setHostName("smtp.servermail.com"); + email.setSmtpPort(465); + email.setAuthenticator(new DefaultAuthenticator(username, password)); + email.setSSLOnConnect(true); + email.setFrom("user@gmail.com"); + email.setSubject("TestMail"); + email.setMsg("This is a test mail ... :-)"); + email.addTo("foo@bar.com"); + // ruleid: missing-ssl-certificate-validation-simpleemail + email.send(); + email.setSSLCheckServerIdentity(true); + } +} \ No newline at end of file diff --git a/org.apache.httpcomponents/deprecated-defaulthttpclient/deprecated-defaulthttpclient.java b/org.apache.httpcomponents/deprecated-defaulthttpclient/deprecated-defaulthttpclient.java new file mode 100644 index 0000000..a984cad --- /dev/null +++ b/org.apache.httpcomponents/deprecated-defaulthttpclient/deprecated-defaulthttpclient.java @@ -0,0 +1,15 @@ +// Use of DefaultHttpClient +public class Main { + public static void main() { + // ruleid: deprecated-defaulthttpclient + HttpClient client = new DefaultHttpClient(); + } +} + +// Use of SystemDefaultHttpClient +public class Main { + public static void main() { + // ok: deprecated-defaulthttpclient + HttpClient client = new SystemDefaultHttpClient(); + } +} \ No newline at end of file diff --git a/org.apache.struts/taint-backend-url-redirect-actionforward/taint-backend-url-redirect-actionforward.java b/org.apache.struts/taint-backend-url-redirect-actionforward/taint-backend-url-redirect-actionforward.java new file mode 100644 index 0000000..4196076 --- /dev/null +++ b/org.apache.struts/taint-backend-url-redirect-actionforward/taint-backend-url-redirect-actionforward.java @@ -0,0 +1,41 @@ +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.apache.struts.action.ActionForward; + + +// Request parameter is first passed into another function +public class Main { + public static void main(HttpServletRequest request, HttpServletResponse response) { + String returnURL = request.getParameter("returnURL"); + String a = sanitize(returnURL); + // ok: taint-backend-url-redirect-actionforward + return new ActionForward(a); + } +} + +// Request parameter passed straight into function +public class Main { + public static void main(HttpServletRequest request, HttpServletResponse response) { + String returnURL = request.getParameter("returnURL"); + // ruleid: taint-backend-url-redirect-actionforward + a = new ActionForward(returnURL); + + // ruleid: taint-backend-url-redirect-actionforward + b = new ActionForward(returnURL, true); + + // ruleid: taint-backend-url-redirect-actionforward + c = new ActionForward("success", returnURL, true); + + // wrong method signature + // ok: taint-backend-url-redirect-actionforward + d = new ActionForward("success", returnURL, true, false, false); + + // ok: taint-backend-url-redirect-actionforward + e = new ActionForward("/static/url"); + // todoruleid: taint-backend-url-redirect-actionforward + e.setPath(returnURL); + + // ruleid: taint-backend-url-redirect-actionforward + return new ActionForward("success", returnURL, true, false); + } +} \ No newline at end of file diff --git a/org.apache.struts/variable-query-ognl/variable-query-ognl.java b/org.apache.struts/variable-query-ognl/variable-query-ognl.java new file mode 100644 index 0000000..a1f05df --- /dev/null +++ b/org.apache.struts/variable-query-ognl/variable-query-ognl.java @@ -0,0 +1,87 @@ +package testcode.script.ognl; + +import com.opensymphony.xwork2.ognl.OgnlReflectionProvider; + +import javax.management.ReflectionException; +import java.beans.IntrospectionException; +import java.util.HashMap; +import java.util.Map; + +public class OgnlReflectionProviderSample { + + public void unsafeOgnlReflectionProvider(String input, OgnlReflectionProvider reflectionProvider, Class type) throws IntrospectionException, ReflectionException { + // ruleid: variable-query-ognl + reflectionProvider.getGetMethod(type, input); + } + + public void unsafeOgnlReflectionProvider1(String input, ReflectionProvider reflectionProvider) throws IntrospectionException, ReflectionException { + // ruleid: variable-query-ognl + reflectionProvider.getValue(input, null, null); + } + + public void unsafeOgnlReflectionProvider2(String input, OgnlUtil reflectionProvider) throws IntrospectionException, ReflectionException { + // ruleid: variable-query-ognl + reflectionProvider.setValue(input, null, null,null); + } + + public void unsafeOgnlReflectionProvider3(String input, OgnlTextParser reflectionProvider) throws IntrospectionException, ReflectionException { + // ruleid: variable-query-ognl + reflectionProvider.evaluate( input ); + } + + public void safeOgnlReflectionProvider1(OgnlReflectionProvider reflectionProvider, Class type) throws IntrospectionException, ReflectionException { + String input = "thisissafe"; + // ok: variable-query-ognl + reflectionProvider.getGetMethod(type, input); + } + + public void safeOgnlReflectionProvider2(OgnlReflectionProvider reflectionProvider, Class type) throws IntrospectionException, ReflectionException { + // ok: variable-query-ognl + reflectionProvider.getField(type, "thisissafe"); + } + +} + + +// String concatenation used +public class Main { + public void getUserProperty(String property) { + OgnlUtil ognlutil = new OgnlUtil(); + // todoruleid: variable-query-ognl + return ognlUtil.getValue("user."+property, ctx, root, String.class); + } +} + +// Standard arbitrary execution +public class Main { + public void execute(final ActionInvocation invocation) throws Exception { + if (this.namespace == null) { + this.namespace = invocation.getProxy().getNamespace(); + } + final OgnlValueStack stack = ActionContext.getContext().getValueStack(); + TextParseUtil textParse = new TextParseUtil(); + // ruleid: variable-query-ognl + final String finalNamespace = textParse.translateVariables(this.namespace, stack); + final String finalActionName = TextParseUtil.translateVariables(this.actionName, stack); + if (this.isInChainHistory(finalNamespace, finalActionName)) { + throw new XworkException("infinite recursion detected"); + } + } +} + +// Execution of fixed string +public class Main { + public void execute(final ActionInvocation invocation) throws Exception { + if (this.namespace == null) { + this.namespace = invocation.getProxy().getNamespace(); + } + final OgnlValueStack stack = ActionContext.getContext().getValueStack(); + TextParseUtil textParse = new TextParseUtil(); + // ok: variable-query-ognl + final String finalNamespace = textParse.translateVariables("this.namespace", stack); + final String finalActionName = TextParseUtil.translateVariables(this.actionName, stack); + if (this.isInChainHistory(finalNamespace, finalActionName)) { + throw new XworkException("infinite recursion detected"); + } + } +} \ No newline at end of file diff --git a/org.springframework/spring-jdbc/taint-backend-sql-injection-jdbc/taint-backend-sql-injection-jdbc.java b/org.springframework/spring-jdbc/taint-backend-sql-injection-jdbc/taint-backend-sql-injection-jdbc.java new file mode 100644 index 0000000..0046fda --- /dev/null +++ b/org.springframework/spring-jdbc/taint-backend-sql-injection-jdbc/taint-backend-sql-injection-jdbc.java @@ -0,0 +1,475 @@ +package testcode.sqli; + +import org.springframework.jdbc.core.PreparedStatementCreatorFactory; +import org.springframework.jdbc.core.SqlParameter; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.dao.DataAccessException; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.servlet.ModelAndView; +import org.springframework.jdbc.core.*; +import java.sql.*; +import javax.annotation.PostConstruct; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.ServletRequest; +import java.util.*; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; +import org.springframework.jdbc.core.simple.SimpleJdbcTemplate; +import org.springframework.jdbc.object.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import javax.sql.DataSource; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Map; + +// String concatenation +public class Main { + public static void main(@PathVariable String paramName) { + JdbcTemplate jdbc = new JdbcTemplate(); + // ruleid: taint-backend-sql-injection-jdbc + int count = jdbc.queryForObject("select count(*) from Users where name = '"+paramName+"'", Integer.class); + } +} + +// Non-final uninitialized string +public class Main { + private String sql; + + public static void main() { + JdbcOperations jdbc = new JdbcOperations(); + // todoruleid: taint-backend-sql-injection-jdbc + int count = jdbc.query(sql); + } +} + +// Prepared statement +public class Main { + public static void main() { + JdbcTemplate jdbc = new JdbcTemplate(); + // ok: taint-backend-sql-injection-jdbc + int count = jdbc.queryForObject("select count(*) from Users where name = ?", Integer.class, paramName); + } +} + +// Final string +public class Main { + private final static String sql = "select count(*) from Users"; + + public static void main() { + JdcbOperation jdbc = new JdcbOperation(); + // ok: taint-backend-sql-injection-jdbc + int count = jdbc.query(sql); + } +} + +public class T1 { + @PostMapping(path = "/abc") + public String myPath(HttpServletRequest request) throws IOException { + StringBuilder builder = new StringBuilder(); + try (BufferedReader in = request.getReader()) { + char[] buf = new char[4096]; + for (int len; (len = in.read(buf)) > 0; ) + builder.append(buf, 0, len); + } + String requestBody = builder.toString(); + // ruleid: taint-backend-sql-injection-jdbc + new PreparedStatementCreatorFactory(requestBody); + return "abc"; + } +} + +public class T2 { + @PostMapping(path = "/abc") + public String myPath(HttpServletRequest request) throws IOException { + String a = request.getHeader("Content-Type"); + String b = String.format("%s", a); + + // ruleid: taint-backend-sql-injection-jdbc + new PreparedStatementCreatorFactory(b); + + return "abc"; + } +} + +public class T3 { + + @PostMapping(path = "/abc") + public String myPath(HttpServletRequest request) throws IOException { + HttpSession sess = request.getSession(); + + // ok: taint-backend-sql-injection-jdbc + new PreparedStatementCreatorFactory(sess.getAttribute("myAttr").toString()); + + // ruleid: taint-backend-sql-injection-jdbc + new PreparedStatementCreatorFactory(request.getHeader("Content-Type")); + // ok: taint-backend-sql-injection-jdbc + new PreparedStatementCreatorFactory(request.getSession().getAttribute("myAttr2").toString()); + + return "abc"; + } +} + +public class T4 { + @PostMapping(path = "/abc") + public String myPath(HttpServletRequest request, @RequestBody String body) throws IOException { + JdbcTemplate template = new JdbcTemplate(); + + String a = request.getHeader("Content-Type"); + // ruleid: taint-backend-sql-injection-jdbc + template.batchUpdate(a, "SELECT COUNT(*) FROM USERS WHERE age=40"); + + // ruleid: taint-backend-sql-injection-jdbc + template.execute(body); + + + // fails because it can't determine the type of request.getPathInfo(). + // This should only happen with the JdbcTemplate.batchUpdate method, other methods such as execute will still trigger + // todoruleid: taint-backend-sql-injection-jdbc + template.batchUpdate(request.getPathInfo()); + + // ruleid: taint-backend-sql-injection-jdbc + template.execute(request.getPathInfo()); + + } +} + +@RequestMapping("/books") +@Controller +class BookController { + + private final JdbcTemplate jdbcTemplate; + + public BookController(JdbcTemplate jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; + } + + @RequestMapping("/") + public ModelAndView home() { + List books = loadBooks(); + + Map model = new HashMap<>(); + model.put("books", books); + + return new ModelAndView("views/sql/home", model); + } + + @RequestMapping("/detail") + public ModelAndView detail(@RequestParam(value = "id") String id) { + String sql = "SELECT * FROM books WHERE id=" + id; + final Book[] book = new Book[1]; + // ruleid: taint-backend-sql-injection-jdbc + jdbcTemplate.query(sql, (ResultSetExtractor) rs -> { + if (rs.next()) + book[0] = new Book(rs.getLong(1), rs.getString(2), rs.getString(3)); + + return null; + + }); + + Map model = new HashMap<>(); + model.put("book", book[0]); + + return new ModelAndView("views/sql/detail", model); + } + + @PostConstruct + private void bootstrap() { + initDb(); + + List books = Arrays.asList( + new Book(1L, "Moby Dick", "Herman Melville"), + new Book(2L, "Unsichtbare Spuren", "Andreas Franz"), + new Book(3L, "Das Paket", "Sebastian Fitzek") + ); + saveBooks(books); + } + + private void saveBooks(List books) { + books.forEach(book -> + jdbcTemplate.update("INSERT INTO books (id, `name`, author) values (?, ?, ?)", + book.id, book.name, book.author) + ); + } + + private List loadBooks() { + + return jdbcTemplate.query("SELECT * FROM books", rs -> { + List books = new LinkedList<>(); + + while (rs.next()) { + books.add(new Book(rs.getLong(1), rs.getString(2), rs.getString(3))); + } + + return books; + }); + + } + + private void initDb() { + jdbcTemplate.execute("CREATE TABLE books (id NUMBER, name VARCHAR(255), author VARCHAR(255))"); + } + +} + +@RestController +public class HelloController { + @Autowired + private DataSource dataSource; + private final SimpleJdbcTemplate simpleJdbcTemplate; + private final JdbcTemplate jdbcTemplate; + private final NamedParameterJdbcTemplate namedParameterJdbcTemplate; + public HelloController() { + this.simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource); + this.jdbcTemplate = new JdbcTemplate(dataSource); + this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource); + } + private class Example { + private String name; + private String content; + + public Example() {} + public String getContent() { + return this.content; + } + public void setContent(String text) { + this.content = content; + } + public String getName() { + return this.name; + } + public void setName(String name) { + this.name = name; + } + } + @GetMapping("/simpleJdbcTemplateTest") + public String simpleJdbcTemplateTest(@RequestParam(required = false, defaultValue = "911") String id, @RequestParam String name, @RequestParam(required = false) String content) { + // ruleid: taint-backend-sql-injection-jdbc + simpleJdbcTemplate.query("SELECT name, content FROM table WHERE name = '" + id + "'", + (RowMapper) (rs, rowNum) -> { + var exp = new Example(); + exp.setContent(rs.getString("content")); + exp.setName(rs.getString("name")); + return exp; + }); + // ok: taint-backend-sql-injection-jdbc + simpleJdbcTemplate.query("SELECT name, content FROM table WHERE id = 911", + (RowMapper) (rs, rowNum) -> { + var exp = new Example(); + exp.setContent(rs.getString("content")); + exp.setName(rs.getString("name")); + return exp; + }); + // ruleid: taint-backend-sql-injection-jdbc + simpleJdbcTemplate.batchUpdate("INSERT INTO table (name, content, id) VALUES (?, ? '" + id + "')", + new ArrayList<>(Collections.singleton(new Object[]{name, content}))); + // ok: taint-backend-sql-injection-jdbc + simpleJdbcTemplate.batchUpdate("INSERT INTO table (name, content) VALUES (?, ?)", + new ArrayList<>(Collections.singleton(new Object[]{name, content}))); + // ok: taint-backend-sql-injection-jdbc + simpleJdbcTemplate.queryForList("SELECT name, content FROM table WHERE id = ?", id); + // ruleid: taint-backend-sql-injection-jdbc + simpleJdbcTemplate.update("UPDATE table SET content = ? WHERE name = '" + name + "'", content); + // ok: taint-backend-sql-injection-jdbc + simpleJdbcTemplate.update("UPDATE table SET content = ? WHERE name = ?", content, name); + return "Greetings from Spring Boot! "; + } + + @GetMapping("/jdbcTemplateTest") + public String jdbcTemplateTest(@RequestParam(required = false, defaultValue = "911") String id, @RequestParam String name, @RequestParam(required = false) String content) { + // ruleid: taint-backend-sql-injection-jdbc + jdbcTemplate.query("SELECT name, content FROM table WHERE name = '" + id + "'", + (rs, rowNum) -> { + var exp = new Example(); + exp.setContent(rs.getString("content")); + exp.setName(rs.getString("name")); + return exp; + }); + // ok: taint-backend-sql-injection-jdbc + jdbcTemplate.query("SELECT name, content FROM table WHERE id = 911", + (rs, rowNum) -> { + var exp = new Example(); + exp.setContent(rs.getString("content")); + exp.setName(rs.getString("name")); + return exp; + }); + // ruleid: taint-backend-sql-injection-jdbc + jdbcTemplate.batchUpdate("INSERT INTO table (name, content, id) VALUES (?, ? '" + id + "')", + // ok: taint-backend-sql-injection-jdbc + new ArrayList<>(Collections.singleton(new Object[]{name, content}))); + // ok: taint-backend-sql-injection-jdbc + jdbcTemplate.batchUpdate("INSERT INTO table (name, content) VALUES (?, ?)", + // ok: taint-backend-sql-injection-jdbc + new ArrayList<>(Collections.singleton(new Object[]{name, content}))); + // ok: taint-backend-sql-injection-jdbc + jdbcTemplate.queryForList("SELECT name, content FROM table WHERE id = ?", id); + // ruleid: taint-backend-sql-injection-jdbc + jdbcTemplate.update("UPDATE table SET content = ? WHERE name = '" + name + "'", content); + // ok: taint-backend-sql-injection-jdbc + jdbcTemplate.update("UPDATE table SET content = ? WHERE name = ?", content, name); + return "Greetings from Spring Boot! "; + } + + @GetMapping("/sqlFunctionTest") + public String sqlFunctionTest(@RequestParam String name, @RequestParam String content) { + // ruleid: taint-backend-sql-injection-jdbc + SqlFunction sf = new SqlFunction<>(dataSource, "SELECT name, content FROM table WHERE content = '" + content + "'"); + // ruleid: taint-backend-sql-injection-jdbc + sf.setSql("SELECT name, content FROM table WHERE name = '" + name + "'"); + sf.runGeneric(); + return "Greetings from Spring Boot! "; + } + + @GetMapping("/sqlFunctionTest01") + public String sqlFunctionTest01(@RequestParam String name, @RequestParam String content) { + // ruleid: taint-backend-sql-injection-jdbc + SqlFunction<> sf = new SqlFunction(dataSource, "SELECT name, content FROM table WHERE content = '" + content + "'"); + // ruleid: taint-backend-sql-injection-jdbc + sf.setSql("SELECT name, content FROM table WHERE name = '" + name + "'"); + sf.runGeneric(); + return "Greetings from Spring Boot! "; + } + + @GetMapping("/sqlFunctionTest02") + public String sqlFunctionTest02(@RequestParam String name, @RequestParam String content) { + // ruleid: taint-backend-sql-injection-jdbc + SqlFunction sf = new SqlFunction(dataSource, "SELECT name, content FROM table WHERE content = '" + content + "'"); + // ruleid: taint-backend-sql-injection-jdbc + sf.setSql("SELECT name, content FROM table WHERE name = '" + name + "'"); + sf.runGeneric(); + return "Greetings from Spring Boot! "; + } + + @GetMapping("/sqlCallTest") + public String sqlCallTest(@RequestParam String name, @RequestParam String content) { + // todoruleid: taint-backend-sql-injection-jdbc + SqlCall sf = new SqlCall(dataSource, "SELECT name, content FROM table WHERE content = '" + content + "'") {}; + // ruleid: taint-backend-sql-injection-jdbc + sf.setSql("SELECT name, content FROM table WHERE name = '" + name + "'"); + + return "Greetings from Spring Boot! "; + } + + @GetMapping("/sqlQueryTest") + public String sqlQueryTest(@RequestParam String name, @RequestParam String content) { + // todoruleid: taint-backend-sql-injection-jdbc + SqlQuery<> sf = new SqlQuery(dataSource, "SELECT name, content FROM table WHERE content = '" + content + "'") { + @Override + protected RowMapper newRowMapper(Object[] objects, Map map) { + return null; + } + }; + // ruleid: taint-backend-sql-injection-jdbc + sf.setSql("SELECT name, content FROM table WHERE name = '" + name + "'"); + + return "Greetings from Spring Boot! "; + } + + @GetMapping("/mappingSqlQueryWithParametersTest") + public String mappingSqlQueryWithParametersTest(@RequestParam String name, @RequestParam String content) { + // todoruleid: taint-backend-sql-injection-jdbc + MappingSqlQueryWithParameters sf = new MappingSqlQueryWithParameters(dataSource, "SELECT name, content FROM table WHERE content = '" + content + "'") { + @Override + protected Object mapRow(ResultSet resultSet, int i, Object[] objects, Map map) throws SQLException { + return null; + } + }; + // ruleid: taint-backend-sql-injection-jdbc + sf.setSql("SELECT name, content FROM table WHERE name = '" + name + "'"); + return "Greetings from Spring Boot! "; + } + + @GetMapping("/mappingSqlQueryTest") + public String mappingSqlQueryTest(@RequestParam String name, @RequestParam String content) { + // todoruleid: taint-backend-sql-injection-jdbc + MappingSqlQuery sf = new MappingSqlQuery<>(dataSource, "SELECT name, content FROM table WHERE content = '" + content + "'") { + @Override + protected Example mapRow(ResultSet resultSet, int i) throws SQLException { + return null; + } + }; + // ruleid: taint-backend-sql-injection-jdbc + sf.setSql("SELECT name, content FROM table WHERE name = '" + name + "'"); + return "Greetings from Spring Boot! "; + } + + @GetMapping("/updatableSqlQueryTest") + public String updatableSqlQueryTest(@RequestParam String name, @RequestParam String content) { + // todoruleid: taint-backend-sql-injection-jdbc + UpdatableSqlQuery sf = new UpdatableSqlQuery<>(dataSource, "SELECT name, content FROM table WHERE content = '" + content + "'") { + @Override + protected Example updateRow(ResultSet resultSet, int i, Map map) { + return null; + } + }; + // ruleid: taint-backend-sql-injection-jdbc + sf.setSql("SELECT name, content FROM table WHERE name = '" + name + "'"); + + return "Greetings from Spring Boot! "; + } + + @GetMapping("/sqlUpdateTest") + public String sqlUpdateTest(@RequestParam String name, @RequestParam String content) { + // ruleid: taint-backend-sql-injection-jdbc + SqlUpdate sf = new SqlUpdate(dataSource, "SELECT name, content FROM table WHERE content = '" + content + "'"); + // ruleid: taint-backend-sql-injection-jdbc + sf.setSql("SELECT name, content FROM table WHERE name = '" + name + "'"); + return "Greetings from Spring Boot! "; + } + + @GetMapping("/batchSqlUpdateTest") + public String batchSqlUpdateTest(@RequestParam String name, @RequestParam String content) { + // ruleid: taint-backend-sql-injection-jdbc + BatchSqlUpdate sf = new BatchSqlUpdate(dataSource, "SELECT name, content FROM table WHERE content = '" + content + "'"); + // ruleid: taint-backend-sql-injection-jdbc + sf.setSql("SELECT name, content FROM table WHERE name = '" + name + "'"); + + return "Greetings from Spring Boot! "; + } + + @GetMapping("/storedProcedureTest") + public String StoredProcedureTest(@RequestParam String name, @RequestParam String content) { + // todoruleid: taint-backend-sql-injection-jdbc + StoredProcedure sf = new StoredProcedure(dataSource, "SELECT name, content FROM table WHERE content = '" + content + "'") {}; + // ruleid: taint-backend-sql-injection-jdbc + sf.setSql("SELECT name, content FROM table WHERE name = '" + name + "'"); + + return "Greetings from Spring Boot! "; + } + + @GetMapping("/genericStoredProcedureTest") + public String genericStoredProcedureTest(@RequestParam String name, @RequestParam String content) { + GenericStoredProcedure sf = new GenericStoredProcedure(); + // ruleid: taint-backend-sql-injection-jdbc + sf.setSql("SELECT name, content FROM table WHERE name = '" + name + "'"); + + return "Greetings from Spring Boot! "; + } + + @GetMapping("/sqlOperationTest") + public String sqlOperationTest(@RequestParam String name, @RequestParam String content) { + SqlOperation sf = new SqlOperation() {}; + // ruleid: taint-backend-sql-injection-jdbc + sf.setSql("SELECT name, content FROM table WHERE name = '" + name + "'"); + + return "Greetings from Spring Boot! "; + } + + @GetMapping("/genericSqlQueryTest") + public String genericSqlQueryTest(@RequestParam String name, @RequestParam String content) { + GenericSqlQuery sf = new GenericSqlQuery<>(); + // ruleid: taint-backend-sql-injection-jdbc + sf.setSql("SELECT name, content FROM table WHERE name = '" + name + "'"); + + return "Greetings from Spring Boot! "; + } +} \ No newline at end of file diff --git a/org.springframework/spring-web/taint-backend-url-redirect-modelandview/taint-backend-url-redirect-modelandview.java b/org.springframework/spring-web/taint-backend-url-redirect-modelandview/taint-backend-url-redirect-modelandview.java new file mode 100644 index 0000000..2850845 --- /dev/null +++ b/org.springframework/spring-web/taint-backend-url-redirect-modelandview/taint-backend-url-redirect-modelandview.java @@ -0,0 +1,50 @@ +package testcode.spring; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.servlet.ModelAndView; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@Controller +public class SpringUnvalidatedRedirectController { + + @RequestMapping("/redirect4") + public ModelAndView redirect4(@RequestParam("url") String url) { + // ruleid: taint-backend-url-redirect-modelandview + return new ModelAndView("redirect:" + url); + } + + @RequestMapping("/redirect5") + public ModelAndView redirect5(@RequestParam("url") String url) { + String view = "redirect:" + url; + // ruleid: taint-backend-url-redirect-modelandview + return new ModelAndView(view); + } + + public ModelAndView normalStuff(HttpServletRequest request, HttpServletResponse response) { + String returnURL = request.getParameter("returnURL"); + String view = "redirect:" + returnURL; + // ruleid: taint-backend-url-redirect-modelandview + return new ModelAndView(view); + } + + @GetMapping("/WebWolf/landing/password-reset") + public ModelAndView openPasswordReset(HttpServletRequest request) throws URISyntaxException { + URI uri = new URI(request.getRequestURL().toString()); + // ruleid: taint-backend-url-redirect-modelandview + ModelAndView modelAndView = new ModelAndView(uri); + modelAndView.addObject("webwolfUrl", landingPageUrl); + modelAndView.addObject("uniqueCode", StringUtils.reverse(getWebSession().getUserName())); + + modelAndView.setViewName("lessons/webwolfintroduction/templates/webwolfPasswordReset.html"); + return modelAndView; + } + + @RequestMapping("/redirectfp") + public String redirectfp() { + // ok: taint-backend-url-redirect-modelandview + return "redirect:/"; + } +} diff --git a/org.springframework/taint-backend-spel-injection/taint-backend-spel-injection.java b/org.springframework/taint-backend-spel-injection/taint-backend-spel-injection.java new file mode 100644 index 0000000..2abab5a --- /dev/null +++ b/org.springframework/taint-backend-spel-injection/taint-backend-spel-injection.java @@ -0,0 +1,75 @@ +package com.example.demo; + +import org.springframework.expression.Expression; +import org.springframework.expression.ExpressionParser; +import org.springframework.expression.common.TemplateAwareExpressionParser; +import org.springframework.expression.common.TemplateParserContext; +import org.springframework.expression.spel.standard.SpelExpressionParser; +import org.springframework.expression.spel.support.StandardEvaluationContext; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class HelloController { + private static final ExpressionParser EXPRESSION_PARSER = new SpelExpressionParser(); + private static final SpelExpressionParser SPEL_EXPRESSION_PARSER = new SpelExpressionParser(); + private static final TemplateAwareExpressionParser TEMPLATE_AWARE_EXPRESSION_PARSER = new SpelExpressionParser(); + @GetMapping("/test01") + public void test01(@RequestParam String pr1) { + ExpressionParser expressionParser = new SpelExpressionParser(); + // ruleid: taint-backend-spel-injection + Expression ex1 = expressionParser.parseExpression(pr1, new TemplateParserContext()); + ex1.getValue(); + + SpelExpressionParser spelExpressionParser = new SpelExpressionParser(); + // ruleid: taint-backend-spel-injection + spelExpressionParser.parseExpression(pr1, new TemplateParserContext()).getValue(new StandardEvaluationContext()); + + TemplateAwareExpressionParser templateAwareExpressionParser = new SpelExpressionParser(); + // ruleid: taint-backend-spel-injection + Expression ex2 = templateAwareExpressionParser.parseExpression(pr1, new TemplateParserContext()); + ex2.getValue(new Object()); + + // ruleid: taint-backend-spel-injection + Expression ex3 = EXPRESSION_PARSER.parseExpression(pr1); + ex3.getValue(new StandardEvaluationContext()); + // ruleid: taint-backend-spel-injection + SpelExpression spelEx = SPEL_EXPRESSION_PARSER.parseExpression(pr1); + spelEx.getValue(new StandardEvaluationContext(), new Ojbect()); + // ok: taint-backend-spel-injection + TEMPLATE_AWARE_EXPRESSION_PARSER.parseExpression(pr1).getValue(new SimpleEvaluationContext()); + // ruleid: taint-backend-spel-injection + SpelExpression spelEx = spelExpressionParser.parseRaw(pr1); + spelEx.getValue(new Object()); + + } + + @GetMapping("/test02") + public void test02(@RequestParam String pr1) { + // ok: taint-backend-spel-injection + Expression ex1 = EXPRESSION_PARSER.parseExpression("'Any String'.length()"); + ex1.getValue(); + // ok: taint-backend-spel-injection + SPEL_EXPRESSION_PARSER.parseRaw("'Any String'.length()").getValue(new StandardEvaluationContext()); + // ok: taint-backend-spel-injection + Expression ex2 = SPEL_EXPRESSION_PARSER.parseExpression("'" + pr1 + "'.length()"); + ex2.getValue(new SimpleEvaluationContext()); + // ruleid: taint-backend-spel-injection + Expression ex3 = SPEL_EXPRESSION_PARSER.parseExpression("'" + pr1 + "'.length()"); + ex3.getValue(new Object()); + // ruleid: taint-backend-spel-injection + SPEL_EXPRESSION_PARSER.parseRaw("'" + pr1 + "'.length()").getValue(); + pr1 = "'Any String'.length()"; + // ok: taint-backend-spel-injection + TEMPLATE_AWARE_EXPRESSION_PARSER.parseExpression(pr1).getValue(new Object()); + // ok: taint-backend-spel-injection + Expression ex4 = SPEL_EXPRESSION_PARSER.parseExpression(pr1); + ex4.getValue(); + // ok: taint-backend-spel-injection + SPEL_EXPRESSION_PARSER.parseRaw(pr1).getValue(); + // ok: taint-backend-spel-injection + SpelExpression ex5 = SPEL_EXPRESSION_PARSER.parseRaw(pr1); + ex5.getValue(new Object()); + } +}