diff --git a/java/ql/src/Security/CWE/CWE-352/JsonpInjection.ql b/java/ql/src/Security/CWE/CWE-352/JsonpInjection.ql deleted file mode 100644 index 53ee6182511..00000000000 --- a/java/ql/src/Security/CWE/CWE-352/JsonpInjection.ql +++ /dev/null @@ -1,68 +0,0 @@ -/** - * @name JSONP Injection - * @description User-controlled callback function names that are not verified are vulnerable - * to jsonp injection attacks. - * @kind path-problem - * @problem.severity error - * @precision high - * @id java/JSONP-Injection - * @tags security - * external/cwe/cwe-352 - */ - -import java -import JsonpInjectionLib -import JsonpInjectionFilterLib -import semmle.code.java.dataflow.FlowSources -import semmle.code.java.deadcode.WebEntryPoints -import DataFlow::PathGraph - - -/** If there is a method to verify `token`, `auth`, `referer`, and `origin`, it will not pass. */ -class ServletVerifAuth extends DataFlow::BarrierGuard { - ServletVerifAuth() { - exists(MethodAccess ma, Node prod, Node succ | - ma.getMethod().getName().regexpMatch("(?i).*(token|auth|referer|origin).*") and - prod instanceof RemoteFlowSource and - succ.asExpr() = ma.getAnArgument() and - ma.getMethod().getAParameter().getName().regexpMatch("(?i).*(token|auth|referer|origin).*") and - localFlowStep*(prod, succ) and - this = ma - ) - } - - override predicate checks(Expr e, boolean branch) { - exists(Node node | - node instanceof JsonpInjectionSink and - e = node.asExpr() and - branch = true - ) - } -} - -/** Taint-tracking configuration tracing flow from get method request sources to output jsonp data. */ -class JsonpInjectionConfig extends TaintTracking::Configuration { - JsonpInjectionConfig() { this = "JsonpInjectionConfig" } - - override predicate isSource(DataFlow::Node source) { source instanceof GetHttpRequestSource } - - override predicate isSink(DataFlow::Node sink) { sink instanceof JsonpInjectionSink } - - override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { - guard instanceof ServletVerifAuth - } - - override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { - exists(MethodAccess ma | - isRequestGetParamMethod(ma) and pred.asExpr() = ma.getQualifier() and succ.asExpr() = ma - ) - } -} - -from DataFlow::PathNode source, DataFlow::PathNode sink, JsonpInjectionConfig conf -where - not checks() = false and - conf.hasFlowPath(source, sink) and - exists(JsonpInjectionFlowConfig jhfc | jhfc.hasFlowTo(sink.getNode())) -select sink.getNode(), source, sink, "Jsonp Injection query might include code from $@.", - source.getNode(), "this user input" diff --git a/java/ql/src/Security/CWE/CWE-352/JsonpInjectionFilterLib.qll b/java/ql/src/Security/CWE/CWE-352/JsonpInjectionFilterLib.qll deleted file mode 100644 index b349bed2641..00000000000 --- a/java/ql/src/Security/CWE/CWE-352/JsonpInjectionFilterLib.qll +++ /dev/null @@ -1,77 +0,0 @@ -/** - * @name JSONP Injection - * @description User-controlled callback function names that are not verified are vulnerable - * to json hijacking attacks. - * @kind path-problem - */ - -import java -import DataFlow -import semmle.code.java.dataflow.FlowSources -import semmle.code.java.dataflow.TaintTracking2 -import DataFlow::PathGraph - -class FilterVerifAuth extends DataFlow::BarrierGuard { - FilterVerifAuth() { - exists(MethodAccess ma, Node prod, Node succ | - ma.getMethod().getName().regexpMatch("(?i).*(token|auth|referer|origin).*") and - prod instanceof RemoteFlowSource and - succ.asExpr() = ma.getAnArgument() and - ma.getMethod().getAParameter().getName().regexpMatch("(?i).*(token|auth|referer|origin).*") and - localFlowStep*(prod, succ) and - this = ma - ) - } - - override predicate checks(Expr e, boolean branch) { - exists(Node node | - node instanceof DoFilterMethodSink and - e = node.asExpr() and - branch = true - ) - } -} - -/** A data flow source for `Filter.doFilter` method paramters. */ -private class DoFilterMethodSource extends DataFlow::Node { - DoFilterMethodSource() { - exists(Method m | - isDoFilterMethod(m) and - m.getAParameter().getAnAccess() = this.asExpr() - ) - } -} - -/** A data flow sink for `FilterChain.doFilter` method qualifying expression. */ -private class DoFilterMethodSink extends DataFlow::Node { - DoFilterMethodSink() { - exists(MethodAccess ma, Method m | ma.getMethod() = m | - m.hasName("doFilter") and - m.getDeclaringType*().hasQualifiedName("javax.servlet", "FilterChain") and - ma.getQualifier() = this.asExpr() - ) - } -} - -/** Taint-tracking configuration tracing flow from `doFilter` method paramter source to output - * `FilterChain.doFilter` method qualifying expression. - * */ -class DoFilterMethodConfig extends TaintTracking::Configuration { - DoFilterMethodConfig() { this = "DoFilterMethodConfig" } - - override predicate isSource(DataFlow::Node source) { source instanceof DoFilterMethodSource } - - override predicate isSink(DataFlow::Node sink) { sink instanceof DoFilterMethodSink } - - override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { - guard instanceof FilterVerifAuth - } -} - -/** Implement class modeling verification for `Filter.doFilter`, return false if it fails. */ -boolean checks() { - exists(DataFlow::PathNode source, DataFlow::PathNode sink, DoFilterMethodConfig conf | - conf.hasFlowPath(source, sink) and - result = false - ) -} diff --git a/java/ql/src/Security/CWE/CWE-352/JsonpInjectionLib.qll b/java/ql/src/Security/CWE/CWE-352/JsonpInjectionLib.qll deleted file mode 100644 index 3f730425823..00000000000 --- a/java/ql/src/Security/CWE/CWE-352/JsonpInjectionLib.qll +++ /dev/null @@ -1,155 +0,0 @@ -import java -import DataFlow -import JsonStringLib -import semmle.code.java.dataflow.DataFlow -import semmle.code.java.dataflow.FlowSources -import semmle.code.java.frameworks.spring.SpringController - -/** Holds if `m` is a method of some override of `HttpServlet.doGet`. */ -private predicate isGetServletMethod(Method m) { - isServletRequestMethod(m) and m.getName() = "doGet" -} - -/** Holds if `m` is a method of some override of `HttpServlet.doGet`. */ -private predicate isGetSpringControllerMethod(Method m) { - exists(Annotation a | - a = m.getAnAnnotation() and - a.getType().hasQualifiedName("org.springframework.web.bind.annotation", "GetMapping") - ) - or - exists(Annotation a | - a = m.getAnAnnotation() and - a.getType().hasQualifiedName("org.springframework.web.bind.annotation", "RequestMapping") and - a.getValue("method").toString().regexpMatch("RequestMethod.GET|\\{...\\}") - ) -} - -/** Method parameters use the annotation `@RequestParam` or the parameter type is `ServletRequest`, `String`, `Object` */ -predicate checkSpringMethodParameterType(Method m, int i) { - m.getParameter(i).getType() instanceof ServletRequest - or - exists(Parameter p | - p = m.getParameter(i) and - p.hasAnnotation() and - p.getAnAnnotation() - .getType() - .hasQualifiedName("org.springframework.web.bind.annotation", "RequestParam") and - p.getType().getName().regexpMatch("String|Object") - ) - or - exists(Parameter p | - p = m.getParameter(i) and - not p.hasAnnotation() and - p.getType().getName().regexpMatch("String|Object") - ) -} - -/** A data flow source for get method request parameters. */ -abstract class GetHttpRequestSource extends DataFlow::Node { } - -/** A data flow source for servlet get method request parameters. */ -private class ServletGetHttpRequestSource extends GetHttpRequestSource { - ServletGetHttpRequestSource() { - exists(Method m | - isGetServletMethod(m) and - m.getParameter(0).getAnAccess() = this.asExpr() - ) - } -} - -/** A data flow source for spring controller get method request parameters. */ -private class SpringGetHttpRequestSource extends GetHttpRequestSource { - SpringGetHttpRequestSource() { - exists(SpringControllerMethod scm, int i | - isGetSpringControllerMethod(scm) and - checkSpringMethodParameterType(scm, i) and - scm.getParameter(i).getAnAccess() = this.asExpr() - ) - } -} - -/** A data flow sink for unvalidated user input that is used to jsonp. */ -abstract class JsonpInjectionSink extends DataFlow::Node { } - -/** Use ```print```, ```println```, ```write``` to output result. */ -private class WriterPrintln extends JsonpInjectionSink { - WriterPrintln() { - exists(MethodAccess ma | - ma.getMethod().getName().regexpMatch("print|println|write") and - ma.getMethod() - .getDeclaringType() - .getASourceSupertype*() - .hasQualifiedName("java.io", "PrintWriter") and - ma.getArgument(0) = this.asExpr() - ) - } -} - -/** Spring Request Method return result. */ -private class SpringReturn extends JsonpInjectionSink { - SpringReturn() { - exists(ReturnStmt rs, Method m | m = rs.getEnclosingCallable() | - isGetSpringControllerMethod(m) and - rs.getResult() = this.asExpr() - ) - } -} - -/** A concatenate expression using `(` and `)` or `);`. */ -class JsonpInjectionExpr extends AddExpr { - JsonpInjectionExpr() { - getRightOperand().toString().regexpMatch("\"\\)\"|\"\\);\"") and - getLeftOperand() - .(AddExpr) - .getLeftOperand() - .(AddExpr) - .getRightOperand() - .toString() - .regexpMatch("\"\\(\"") - } - - /** Get the jsonp function name of this expression */ - Expr getFunctionName() { - result = getLeftOperand().(AddExpr).getLeftOperand().(AddExpr).getLeftOperand() - } - - /** Get the json data of this expression */ - Expr getJsonExpr() { result = getLeftOperand().(AddExpr).getRightOperand() } -} - -/** A data flow configuration tracing flow from remote sources to jsonp function name. */ -class RemoteFlowConfig extends DataFlow2::Configuration { - RemoteFlowConfig() { this = "RemoteFlowConfig" } - - override predicate isSource(DataFlow::Node src) { src instanceof RemoteFlowSource } - - override predicate isSink(DataFlow::Node sink) { - exists(JsonpInjectionExpr jhe | jhe.getFunctionName() = sink.asExpr()) - } -} - -/** A data flow configuration tracing flow from json data to splicing jsonp data. */ -class JsonDataFlowConfig extends DataFlow2::Configuration { - JsonDataFlowConfig() { this = "JsonDataFlowConfig" } - - override predicate isSource(DataFlow::Node src) { src instanceof JsonpStringSource } - - override predicate isSink(DataFlow::Node sink) { - exists(JsonpInjectionExpr jhe | jhe.getJsonExpr() = sink.asExpr()) - } -} - -/** Taint-tracking configuration tracing flow from user-controllable function name jsonp data to output jsonp data. */ -class JsonpInjectionFlowConfig extends DataFlow::Configuration { - JsonpInjectionFlowConfig() { this = "JsonpInjectionFlowConfig" } - - override predicate isSource(DataFlow::Node src) { - exists(JsonpInjectionExpr jhe, JsonDataFlowConfig jdfc, RemoteFlowConfig rfc | - jhe = src.asExpr() and - jdfc.hasFlowTo(DataFlow::exprNode(jhe.getJsonExpr())) and - rfc.hasFlowTo(DataFlow::exprNode(jhe.getFunctionName())) - ) - } - - override predicate isSink(DataFlow::Node sink) { sink instanceof JsonpInjectionSink } -} diff --git a/java/ql/src/Security/CWE/CWE-352/JsonStringLib.qll b/java/ql/src/experimental/Security/CWE/CWE-352/JsonStringLib.qll similarity index 100% rename from java/ql/src/Security/CWE/CWE-352/JsonStringLib.qll rename to java/ql/src/experimental/Security/CWE/CWE-352/JsonStringLib.qll diff --git a/java/ql/test/experimental/query-tests/security/CWE-352/JsonpInjection.java b/java/ql/src/experimental/Security/CWE/CWE-352/JsonpController.java similarity index 72% rename from java/ql/test/experimental/query-tests/security/CWE-352/JsonpInjection.java rename to java/ql/src/experimental/Security/CWE/CWE-352/JsonpController.java index 9f079513a8b..84a172a7aeb 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-352/JsonpInjection.java +++ b/java/ql/src/experimental/Security/CWE/CWE-352/JsonpController.java @@ -3,17 +3,14 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.google.gson.Gson; import java.io.PrintWriter; import java.util.HashMap; -import java.util.Random; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; @Controller -public class JsonpInjection { +public class JsonpController { private static HashMap hashMap = new HashMap(); static { @@ -96,54 +93,13 @@ public class JsonpInjection { @GetMapping(value = "jsonp7") @ResponseBody - public String good(HttpServletRequest request) { - String resultStr = null; - String jsonpCallback = request.getParameter("jsonpCallback"); - - String val = ""; - Random random = new Random(); - for (int i = 0; i < 10; i++) { - val += String.valueOf(random.nextInt(10)); - } - // good - jsonpCallback = jsonpCallback + "_" + val; - String jsonStr = getJsonStr(hashMap); - resultStr = jsonpCallback + "(" + jsonStr + ")"; - return resultStr; - } - - @GetMapping(value = "jsonp8") - @ResponseBody public String good1(HttpServletRequest request) { String resultStr = null; - String jsonpCallback = request.getParameter("jsonpCallback"); String token = request.getParameter("token"); - // good if (verifToken(token)){ - System.out.println(token); - String jsonStr = getJsonStr(hashMap); - resultStr = jsonpCallback + "(" + jsonStr + ")"; - return resultStr; - } - - return "error"; - } - - @GetMapping(value = "jsonp9") - @ResponseBody - public String good2(HttpServletRequest request) { - String resultStr = null; - String jsonpCallback = request.getParameter("jsonpCallback"); - - String referer = request.getHeader("Referer"); - - boolean result = verifReferer(referer); - - boolean test = result; - // good - if (test){ + String jsonpCallback = request.getParameter("jsonpCallback"); String jsonStr = getJsonStr(hashMap); resultStr = jsonpCallback + "(" + jsonStr + ")"; return resultStr; diff --git a/java/ql/src/Security/CWE/CWE-352/JsonpInjection.java b/java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjection.java similarity index 100% rename from java/ql/src/Security/CWE/CWE-352/JsonpInjection.java rename to java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjection.java diff --git a/java/ql/src/Security/CWE/CWE-352/JsonpInjection.qhelp b/java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjection.qhelp similarity index 96% rename from java/ql/src/Security/CWE/CWE-352/JsonpInjection.qhelp rename to java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjection.qhelp index b063b409d3a..bb5d628ac0b 100644 --- a/java/ql/src/Security/CWE/CWE-352/JsonpInjection.qhelp +++ b/java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjection.qhelp @@ -16,7 +16,7 @@ there is a problem of sensitive information leakage.

The following example shows the case of no verification processing and verification processing for the external input function name.

- + diff --git a/java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjection.ql b/java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjection.ql new file mode 100644 index 00000000000..f3ae25daa03 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjection.ql @@ -0,0 +1,64 @@ +/** + * @name JSONP Injection + * @description User-controlled callback function names that are not verified are vulnerable + * to jsonp injection attacks. + * @kind path-problem + * @problem.severity error + * @precision high + * @id java/JSONP-Injection + * @tags security + * external/cwe/cwe-352 + */ + +import java +import JsonpInjectionLib +import semmle.code.java.dataflow.FlowSources +import semmle.code.java.deadcode.WebEntryPoints +import semmle.code.java.security.XSS +import DataFlow::PathGraph + +/** Determine whether there is a verification method for the remote streaming source data flow path method. */ +predicate existsFilterVerificationMethod() { + exists(MethodAccess ma,Node existsNode, Method m| + ma.getMethod() instanceof VerificationMethodClass and + existsNode.asExpr() = ma and + m = getAnMethod(existsNode.getEnclosingCallable()) and + isDoFilterMethod(m) + ) +} + +/** Determine whether there is a verification method for the remote streaming source data flow path method. */ +predicate existsServletVerificationMethod(Node checkNode) { + exists(MethodAccess ma,Node existsNode| + ma.getMethod() instanceof VerificationMethodClass and + existsNode.asExpr() = ma and + getAnMethod(existsNode.getEnclosingCallable()) = getAnMethod(checkNode.getEnclosingCallable()) + ) +} + +/** Taint-tracking configuration tracing flow from get method request sources to output jsonp data. */ +class RequestResponseFlowConfig extends TaintTracking::Configuration { + RequestResponseFlowConfig() { this = "RequestResponseFlowConfig" } + + override predicate isSource(DataFlow::Node source) { + source instanceof RemoteFlowSource and + getAnMethod(source.getEnclosingCallable()) instanceof RequestGetMethod + } + + override predicate isSink(DataFlow::Node sink) { sink instanceof XssSink } + + override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { + exists(MethodAccess ma | + isRequestGetParamMethod(ma) and pred.asExpr() = ma.getQualifier() and succ.asExpr() = ma + ) + } +} + +from DataFlow::PathNode source, DataFlow::PathNode sink, RequestResponseFlowConfig conf +where + not existsServletVerificationMethod(source.getNode()) and + not existsFilterVerificationMethod() and + conf.hasFlowPath(source, sink) and + exists(JsonpInjectionFlowConfig jhfc | jhfc.hasFlowTo(sink.getNode())) +select sink.getNode(), source, sink, "Jsonp Injection query might include code from $@.", + source.getNode(), "this user input" \ No newline at end of file diff --git a/java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjectionLib.qll b/java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjectionLib.qll new file mode 100644 index 00000000000..b8964524a9f --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjectionLib.qll @@ -0,0 +1,130 @@ +import java +import DataFlow +import JsonStringLib +import semmle.code.java.security.XSS +import semmle.code.java.dataflow.DataFlow +import semmle.code.java.dataflow.FlowSources +import semmle.code.java.frameworks.spring.SpringController + +/** Taint-tracking configuration tracing flow from user-controllable function name jsonp data to output jsonp data. */ +class VerificationMethodFlowConfig extends TaintTracking::Configuration { + VerificationMethodFlowConfig() { this = "VerificationMethodFlowConfig" } + + override predicate isSource(DataFlow::Node src) { src instanceof RemoteFlowSource } + + override predicate isSink(DataFlow::Node sink) { + exists(MethodAccess ma, BarrierGuard bg | + ma.getMethod().getAParameter().getName().regexpMatch("(?i).*(token|auth|referer|origin).*") and + bg = ma and + sink.asExpr() = ma.getAnArgument() + ) + } +} + +/** The parameter name of the method is `token`, `auth`, `referer`, `origin`. */ +class VerificationMethodClass extends Method { + VerificationMethodClass() { + exists(MethodAccess ma, BarrierGuard bg, VerificationMethodFlowConfig vmfc, Node node | + this = ma.getMethod() and + this.getAParameter().getName().regexpMatch("(?i).*(token|auth|referer|origin).*") and + bg = ma and + node.asExpr() = ma.getAnArgument() and + vmfc.hasFlowTo(node) + ) + } +} + +/** Get Callable by recursive method. */ +Callable getAnMethod(Callable call) { + result = call + or + result = getAnMethod(call.getAReference().getEnclosingCallable()) +} + +abstract class RequestGetMethod extends Method { } + +/** Holds if `m` is a method of some override of `HttpServlet.doGet`. */ +private class ServletGetMethod extends RequestGetMethod { + ServletGetMethod() { + exists(Method m | + m = this and + isServletRequestMethod(m) and + m.getName() = "doGet" + ) + } +} + +/** Holds if `m` is a method of some override of `HttpServlet.doGet`. */ +private class SpringControllerGetMethod extends RequestGetMethod { + SpringControllerGetMethod() { + exists(Annotation a | + a = this.getAnAnnotation() and + a.getType().hasQualifiedName("org.springframework.web.bind.annotation", "GetMapping") + ) + or + exists(Annotation a | + a = this.getAnAnnotation() and + a.getType().hasQualifiedName("org.springframework.web.bind.annotation", "RequestMapping") and + a.getValue("method").toString().regexpMatch("RequestMethod.GET|\\{...\\}") + ) + } +} + +/** A concatenate expression using `(` and `)` or `);`. */ +class JsonpInjectionExpr extends AddExpr { + JsonpInjectionExpr() { + getRightOperand().toString().regexpMatch("\"\\)\"|\"\\);\"") and + getLeftOperand() + .(AddExpr) + .getLeftOperand() + .(AddExpr) + .getRightOperand() + .toString() + .regexpMatch("\"\\(\"") + } + + /** Get the jsonp function name of this expression */ + Expr getFunctionName() { + result = getLeftOperand().(AddExpr).getLeftOperand().(AddExpr).getLeftOperand() + } + + /** Get the json data of this expression */ + Expr getJsonExpr() { result = getLeftOperand().(AddExpr).getRightOperand() } +} + +/** A data flow configuration tracing flow from remote sources to jsonp function name. */ +class RemoteFlowConfig extends DataFlow2::Configuration { + RemoteFlowConfig() { this = "RemoteFlowConfig" } + + override predicate isSource(DataFlow::Node src) { src instanceof RemoteFlowSource } + + override predicate isSink(DataFlow::Node sink) { + exists(JsonpInjectionExpr jhe | jhe.getFunctionName() = sink.asExpr()) + } +} + +/** A data flow configuration tracing flow from json data to splicing jsonp data. */ +class JsonDataFlowConfig extends DataFlow2::Configuration { + JsonDataFlowConfig() { this = "JsonDataFlowConfig" } + + override predicate isSource(DataFlow::Node src) { src instanceof JsonpStringSource } + + override predicate isSink(DataFlow::Node sink) { + exists(JsonpInjectionExpr jhe | jhe.getJsonExpr() = sink.asExpr()) + } +} + +/** Taint-tracking configuration tracing flow from user-controllable function name jsonp data to output jsonp data. */ +class JsonpInjectionFlowConfig extends TaintTracking::Configuration { + JsonpInjectionFlowConfig() { this = "JsonpInjectionFlowConfig" } + + override predicate isSource(DataFlow::Node src) { + exists(JsonpInjectionExpr jhe, JsonDataFlowConfig jdfc, RemoteFlowConfig rfc | + jhe = src.asExpr() and + jdfc.hasFlowTo(DataFlow::exprNode(jhe.getJsonExpr())) and + rfc.hasFlowTo(DataFlow::exprNode(jhe.getFunctionName())) + ) + } + + override predicate isSink(DataFlow::Node sink) { sink instanceof XssSink } +} diff --git a/java/ql/src/Security/CWE/CWE-352/JsonpInjectionServlet1.java b/java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjectionServlet1.java similarity index 100% rename from java/ql/src/Security/CWE/CWE-352/JsonpInjectionServlet1.java rename to java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjectionServlet1.java diff --git a/java/ql/src/Security/CWE/CWE-352/JsonpInjectionServlet2.java b/java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjectionServlet2.java similarity index 100% rename from java/ql/src/Security/CWE/CWE-352/JsonpInjectionServlet2.java rename to java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjectionServlet2.java diff --git a/java/ql/src/experimental/Security/CWE/CWE-352/RefererFilter.java b/java/ql/src/experimental/Security/CWE/CWE-352/RefererFilter.java new file mode 100644 index 00000000000..97444932ae1 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-352/RefererFilter.java @@ -0,0 +1,43 @@ +import java.io.IOException; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.springframework.util.StringUtils; + +public class RefererFilter implements Filter { + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + } + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { + HttpServletRequest request = (HttpServletRequest) servletRequest; + HttpServletResponse response = (HttpServletResponse) servletResponse; + String refefer = request.getHeader("Referer"); + boolean result = verifReferer(refefer); + if (result){ + filterChain.doFilter(servletRequest, servletResponse); + } + response.sendError(444, "Referer xxx."); + } + + @Override + public void destroy() { + } + + public static boolean verifReferer(String referer){ + if (StringUtils.isEmpty(referer)){ + return false; + } + if (referer.startsWith("http://www.baidu.com/")){ + return true; + } + return false; + } +} diff --git a/java/ql/src/semmle/code/java/frameworks/Servlets.qll b/java/ql/src/semmle/code/java/frameworks/Servlets.qll index b2054dc30cb..5cccf62122f 100644 --- a/java/ql/src/semmle/code/java/frameworks/Servlets.qll +++ b/java/ql/src/semmle/code/java/frameworks/Servlets.qll @@ -338,7 +338,6 @@ predicate isRequestGetParamMethod(MethodAccess ma) { ma.getMethod() instanceof HttpServletRequestGetQueryStringMethod } - /** * A class that has `javax.servlet.Filter` as an ancestor. */ @@ -346,21 +345,18 @@ class FilterClass extends Class { FilterClass() { getAnAncestor().hasQualifiedName("javax.servlet", "Filter") } } - /** * The interface `javax.servlet.FilterChain` */ -class FilterChain extends RefType { - FilterChain() { - hasQualifiedName("javax.servlet", "FilterChain") - } +class FilterChain extends Interface { + FilterChain() { hasQualifiedName("javax.servlet", "FilterChain") } } -/** Holds if `m` is a request handler method (for example `doGet` or `doPost`). */ +/** Holds if `m` is a filter handler method (for example `doFilter`). */ predicate isDoFilterMethod(Method m) { m.getDeclaringType() instanceof FilterClass and m.getNumberOfParameters() = 3 and m.getParameter(0).getType() instanceof ServletRequest and m.getParameter(1).getType() instanceof ServletResponse and m.getParameter(2).getType() instanceof FilterChain -} \ No newline at end of file +} diff --git a/java/ql/test/experimental/query-tests/security/CWE-352/JsonpController.java b/java/ql/test/experimental/query-tests/security/CWE-352/JsonpController.java new file mode 100644 index 00000000000..cf860c75640 --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/CWE-352/JsonpController.java @@ -0,0 +1,128 @@ +import com.alibaba.fastjson.JSONObject; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.Gson; +import java.io.PrintWriter; +import java.util.HashMap; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +@Controller +public class JsonpController { + private static HashMap hashMap = new HashMap(); + + static { + hashMap.put("username","admin"); + hashMap.put("password","123456"); + } + + + @GetMapping(value = "jsonp1", produces="text/javascript") + @ResponseBody + public String bad1(HttpServletRequest request) { + String resultStr = null; + String jsonpCallback = request.getParameter("jsonpCallback"); + + Gson gson = new Gson(); + String result = gson.toJson(hashMap); + resultStr = jsonpCallback + "(" + result + ")"; + return resultStr; + } + + @GetMapping(value = "jsonp2") + @ResponseBody + public String bad2(HttpServletRequest request) { + String resultStr = null; + String jsonpCallback = request.getParameter("jsonpCallback"); + + resultStr = jsonpCallback + "(" + JSONObject.toJSONString(hashMap) + ")"; + + return resultStr; + } + + @GetMapping(value = "jsonp3") + @ResponseBody + public String bad3(HttpServletRequest request) { + String resultStr = null; + String jsonpCallback = request.getParameter("jsonpCallback"); + String jsonStr = getJsonStr(hashMap); + resultStr = jsonpCallback + "(" + jsonStr + ")"; + return resultStr; + } + + @GetMapping(value = "jsonp4") + @ResponseBody + public String bad4(HttpServletRequest request) { + String resultStr = null; + String jsonpCallback = request.getParameter("jsonpCallback"); + String restr = JSONObject.toJSONString(hashMap); + resultStr = jsonpCallback + "(" + restr + ");"; + return resultStr; + } + + @GetMapping(value = "jsonp5") + @ResponseBody + public void bad5(HttpServletRequest request, + HttpServletResponse response) throws Exception { + String jsonpCallback = request.getParameter("jsonpCallback"); + PrintWriter pw = null; + Gson gson = new Gson(); + String result = gson.toJson(hashMap); + + String resultStr = null; + pw = response.getWriter(); + resultStr = jsonpCallback + "(" + result + ")"; + pw.println(resultStr); + } + + @GetMapping(value = "jsonp6") + @ResponseBody + public void bad6(HttpServletRequest request, + HttpServletResponse response) throws Exception { + String jsonpCallback = request.getParameter("jsonpCallback"); + PrintWriter pw = null; + ObjectMapper mapper = new ObjectMapper(); + String result = mapper.writeValueAsString(hashMap); + String resultStr = null; + pw = response.getWriter(); + resultStr = jsonpCallback + "(" + result + ")"; + pw.println(resultStr); + } + + @GetMapping(value = "jsonp7") + @ResponseBody + public String good1(HttpServletRequest request) { + String resultStr = null; + + String token = request.getParameter("token"); + + if (verifToken(token)){ + String jsonpCallback = request.getParameter("jsonpCallback"); + String jsonStr = getJsonStr(hashMap); + resultStr = jsonpCallback + "(" + jsonStr + ")"; + return resultStr; + } + + return "error"; + } + + public static String getJsonStr(Object result) { + return JSONObject.toJSONString(result); + } + + public static boolean verifToken(String token){ + if (token != "xxxx"){ + return false; + } + return true; + } + + public static boolean verifReferer(String referer){ + if (!referer.startsWith("http://test.com/")){ + return false; + } + return true; + } +} diff --git a/java/ql/test/experimental/query-tests/security/CWE-352/JsonpInjection.expected b/java/ql/test/experimental/query-tests/security/CWE-352/JsonpInjection.expected deleted file mode 100644 index 7e3069cf1d9..00000000000 --- a/java/ql/test/experimental/query-tests/security/CWE-352/JsonpInjection.expected +++ /dev/null @@ -1,60 +0,0 @@ -edges -| JsonpInjection.java:29:32:29:38 | request : HttpServletRequest | JsonpInjection.java:34:16:34:24 | resultStr | -| JsonpInjection.java:33:21:33:54 | ... + ... : String | JsonpInjection.java:34:16:34:24 | resultStr | -| JsonpInjection.java:41:32:41:38 | request : HttpServletRequest | JsonpInjection.java:45:16:45:24 | resultStr | -| JsonpInjection.java:43:21:43:80 | ... + ... : String | JsonpInjection.java:45:16:45:24 | resultStr | -| JsonpInjection.java:52:32:52:38 | request : HttpServletRequest | JsonpInjection.java:55:16:55:24 | resultStr | -| JsonpInjection.java:54:21:54:55 | ... + ... : String | JsonpInjection.java:55:16:55:24 | resultStr | -| JsonpInjection.java:62:32:62:38 | request : HttpServletRequest | JsonpInjection.java:65:16:65:24 | resultStr | -| JsonpInjection.java:64:21:64:54 | ... + ... : String | JsonpInjection.java:65:16:65:24 | resultStr | -| JsonpInjection.java:72:32:72:38 | request : HttpServletRequest | JsonpInjection.java:80:20:80:28 | resultStr | -| JsonpInjection.java:79:21:79:54 | ... + ... : String | JsonpInjection.java:80:20:80:28 | resultStr | -| JsonpInjection.java:87:32:87:38 | request : HttpServletRequest | JsonpInjection.java:94:20:94:28 | resultStr | -| JsonpInjection.java:93:21:93:54 | ... + ... : String | JsonpInjection.java:94:20:94:28 | resultStr | -| JsonpInjection.java:101:32:101:38 | request : HttpServletRequest | JsonpInjection.java:112:16:112:24 | resultStr | -| JsonpInjection.java:127:25:127:59 | ... + ... : String | JsonpInjection.java:128:20:128:28 | resultStr | -| JsonpInjection.java:148:25:148:59 | ... + ... : String | JsonpInjection.java:149:20:149:28 | resultStr | -nodes -| JsonpInjection.java:29:32:29:38 | request : HttpServletRequest | semmle.label | request : HttpServletRequest | -| JsonpInjection.java:33:21:33:54 | ... + ... : String | semmle.label | ... + ... : String | -| JsonpInjection.java:34:16:34:24 | resultStr | semmle.label | resultStr | -| JsonpInjection.java:34:16:34:24 | resultStr | semmle.label | resultStr | -| JsonpInjection.java:41:32:41:38 | request : HttpServletRequest | semmle.label | request : HttpServletRequest | -| JsonpInjection.java:43:21:43:80 | ... + ... : String | semmle.label | ... + ... : String | -| JsonpInjection.java:45:16:45:24 | resultStr | semmle.label | resultStr | -| JsonpInjection.java:45:16:45:24 | resultStr | semmle.label | resultStr | -| JsonpInjection.java:52:32:52:38 | request : HttpServletRequest | semmle.label | request : HttpServletRequest | -| JsonpInjection.java:54:21:54:55 | ... + ... : String | semmle.label | ... + ... : String | -| JsonpInjection.java:55:16:55:24 | resultStr | semmle.label | resultStr | -| JsonpInjection.java:55:16:55:24 | resultStr | semmle.label | resultStr | -| JsonpInjection.java:62:32:62:38 | request : HttpServletRequest | semmle.label | request : HttpServletRequest | -| JsonpInjection.java:64:21:64:54 | ... + ... : String | semmle.label | ... + ... : String | -| JsonpInjection.java:65:16:65:24 | resultStr | semmle.label | resultStr | -| JsonpInjection.java:65:16:65:24 | resultStr | semmle.label | resultStr | -| JsonpInjection.java:72:32:72:38 | request : HttpServletRequest | semmle.label | request : HttpServletRequest | -| JsonpInjection.java:79:21:79:54 | ... + ... : String | semmle.label | ... + ... : String | -| JsonpInjection.java:80:20:80:28 | resultStr | semmle.label | resultStr | -| JsonpInjection.java:80:20:80:28 | resultStr | semmle.label | resultStr | -| JsonpInjection.java:87:32:87:38 | request : HttpServletRequest | semmle.label | request : HttpServletRequest | -| JsonpInjection.java:93:21:93:54 | ... + ... : String | semmle.label | ... + ... : String | -| JsonpInjection.java:94:20:94:28 | resultStr | semmle.label | resultStr | -| JsonpInjection.java:94:20:94:28 | resultStr | semmle.label | resultStr | -| JsonpInjection.java:101:32:101:38 | request : HttpServletRequest | semmle.label | request : HttpServletRequest | -| JsonpInjection.java:112:16:112:24 | resultStr | semmle.label | resultStr | -| JsonpInjection.java:127:25:127:59 | ... + ... : String | semmle.label | ... + ... : String | -| JsonpInjection.java:128:20:128:28 | resultStr | semmle.label | resultStr | -| JsonpInjection.java:148:25:148:59 | ... + ... : String | semmle.label | ... + ... : String | -| JsonpInjection.java:149:20:149:28 | resultStr | semmle.label | resultStr | -#select -| JsonpInjection.java:34:16:34:24 | resultStr | JsonpInjection.java:29:32:29:38 | request : HttpServletRequest | JsonpInjection.java:34:16:34:24 | -resultStr | Jsonp Injection query might include code from $@. | JsonpInjection.java:29:32:29:38 | request | this user input | -| JsonpInjection.java:45:16:45:24 | resultStr | JsonpInjection.java:41:32:41:38 | request : HttpServletRequest | JsonpInjection.java:45:16:45:24 | -resultStr | Jsonp Injection query might include code from $@. | JsonpInjection.java:41:32:41:38 | request | this user input | -| JsonpInjection.java:55:16:55:24 | resultStr | JsonpInjection.java:52:32:52:38 | request : HttpServletRequest | JsonpInjection.java:55:16:55:24 | -resultStr | Jsonp Injection query might include code from $@. | JsonpInjection.java:52:32:52:38 | request | this user input | -| JsonpInjection.java:65:16:65:24 | resultStr | JsonpInjection.java:62:32:62:38 | request : HttpServletRequest | JsonpInjection.java:65:16:65:24 | -resultStr | Jsonp Injection query might include code from $@. | JsonpInjection.java:62:32:62:38 | request | this user input | -| JsonpInjection.java:80:20:80:28 | resultStr | JsonpInjection.java:72:32:72:38 | request : HttpServletRequest | JsonpInjection.java:80:20:80:28 | -resultStr | Jsonp Injection query might include code from $@. | JsonpInjection.java:72:32:72:38 | request | this user input | -| JsonpInjection.java:94:20:94:28 | resultStr | JsonpInjection.java:87:32:87:38 | request : HttpServletRequest | JsonpInjection.java:94:20:94:28 | -resultStr | Jsonp Injection query might include code from $@. | JsonpInjection.java:87:32:87:38 | request | this user input | \ No newline at end of file diff --git a/java/ql/test/experimental/query-tests/security/CWE-352/JsonpInjectionServlet1.java b/java/ql/test/experimental/query-tests/security/CWE-352/JsonpInjectionServlet1.java new file mode 100644 index 00000000000..14ef76275b1 --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/CWE-352/JsonpInjectionServlet1.java @@ -0,0 +1,64 @@ +import com.google.gson.Gson; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.HashMap; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +public class JsonpInjectionServlet1 extends HttpServlet { + + private static HashMap hashMap = new HashMap(); + + static { + hashMap.put("username","admin"); + hashMap.put("password","123456"); + } + + private static final long serialVersionUID = 1L; + + private String key = "test"; + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + doPost(req, resp); + } + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + resp.setContentType("application/json"); + String jsonpCallback = req.getParameter("jsonpCallback"); + PrintWriter pw = null; + Gson gson = new Gson(); + String jsonResult = gson.toJson(hashMap); + + String referer = req.getHeader("Referer"); + + boolean result = verifReferer(referer); + + // good + if (result){ + String resultStr = null; + pw = resp.getWriter(); + resultStr = jsonpCallback + "(" + jsonResult + ")"; + pw.println(resultStr); + pw.flush(); + } + } + + public static boolean verifReferer(String referer){ + if (!referer.startsWith("http://test.com/")){ + return false; + } + return true; + } + + @Override + public void init(ServletConfig config) throws ServletException { + this.key = config.getInitParameter("key"); + System.out.println("初始化" + this.key); + super.init(config); + } + +} diff --git a/java/ql/src/Security/CWE/CWE-352/JsonpInjectionServlet.java b/java/ql/test/experimental/query-tests/security/CWE-352/JsonpInjectionServlet2.java similarity index 75% rename from java/ql/src/Security/CWE/CWE-352/JsonpInjectionServlet.java rename to java/ql/test/experimental/query-tests/security/CWE-352/JsonpInjectionServlet2.java index 916cd9bf676..bbfbc2dc436 100644 --- a/java/ql/src/Security/CWE/CWE-352/JsonpInjectionServlet.java +++ b/java/ql/test/experimental/query-tests/security/CWE-352/JsonpInjectionServlet2.java @@ -4,12 +4,11 @@ import java.io.PrintWriter; import java.util.HashMap; import javax.servlet.ServletConfig; import javax.servlet.ServletException; -import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -public class JsonpInjectionServlet extends HttpServlet { +public class JsonpInjectionServlet2 extends HttpServlet { private static HashMap hashMap = new HashMap(); @@ -23,21 +22,12 @@ public class JsonpInjectionServlet extends HttpServlet { private String key = "test"; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - String jsonpCallback = req.getParameter("jsonpCallback"); - - PrintWriter pw = null; - Gson gson = new Gson(); - String result = gson.toJson(hashMap); - - String resultStr = null; - pw = resp.getWriter(); - resultStr = jsonpCallback + "(" + result + ")"; - pw.println(resultStr); - pw.flush(); + doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + resp.setContentType("application/json"); String jsonpCallback = req.getParameter("jsonpCallback"); PrintWriter pw = null; Gson gson = new Gson(); diff --git a/java/ql/test/experimental/query-tests/security/CWE-352/JsonpInjection_1.expected b/java/ql/test/experimental/query-tests/security/CWE-352/JsonpInjection_1.expected new file mode 100644 index 00000000000..a89d03b67a7 --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/CWE-352/JsonpInjection_1.expected @@ -0,0 +1,60 @@ +edges +| JsonpController.java:26:32:26:68 | getParameter(...) : String | JsonpController.java:31:16:31:24 | resultStr | +| JsonpController.java:30:21:30:54 | ... + ... : String | JsonpController.java:31:16:31:24 | resultStr | +| JsonpController.java:38:32:38:68 | getParameter(...) : String | JsonpController.java:42:16:42:24 | resultStr | +| JsonpController.java:40:21:40:80 | ... + ... : String | JsonpController.java:42:16:42:24 | resultStr | +| JsonpController.java:49:32:49:68 | getParameter(...) : String | JsonpController.java:52:16:52:24 | resultStr | +| JsonpController.java:51:21:51:55 | ... + ... : String | JsonpController.java:52:16:52:24 | resultStr | +| JsonpController.java:59:32:59:68 | getParameter(...) : String | JsonpController.java:62:16:62:24 | resultStr | +| JsonpController.java:61:21:61:54 | ... + ... : String | JsonpController.java:62:16:62:24 | resultStr | +| JsonpController.java:69:32:69:68 | getParameter(...) : String | JsonpController.java:77:20:77:28 | resultStr | +| JsonpController.java:76:21:76:54 | ... + ... : String | JsonpController.java:77:20:77:28 | resultStr | +| JsonpController.java:84:32:84:68 | getParameter(...) : String | JsonpController.java:91:20:91:28 | resultStr | +| JsonpController.java:90:21:90:54 | ... + ... : String | JsonpController.java:91:20:91:28 | resultStr | +| JsonpController.java:99:24:99:52 | getParameter(...) : String | JsonpController.java:101:24:101:28 | token | +| JsonpController.java:102:36:102:72 | getParameter(...) : String | JsonpController.java:105:20:105:28 | resultStr | +| JsonpController.java:104:25:104:59 | ... + ... : String | JsonpController.java:105:20:105:28 | resultStr | +nodes +| JsonpController.java:26:32:26:68 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| JsonpController.java:30:21:30:54 | ... + ... : String | semmle.label | ... + ... : String | +| JsonpController.java:31:16:31:24 | resultStr | semmle.label | resultStr | +| JsonpController.java:31:16:31:24 | resultStr | semmle.label | resultStr | +| JsonpController.java:38:32:38:68 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| JsonpController.java:40:21:40:80 | ... + ... : String | semmle.label | ... + ... : String | +| JsonpController.java:42:16:42:24 | resultStr | semmle.label | resultStr | +| JsonpController.java:42:16:42:24 | resultStr | semmle.label | resultStr | +| JsonpController.java:49:32:49:68 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| JsonpController.java:51:21:51:55 | ... + ... : String | semmle.label | ... + ... : String | +| JsonpController.java:52:16:52:24 | resultStr | semmle.label | resultStr | +| JsonpController.java:52:16:52:24 | resultStr | semmle.label | resultStr | +| JsonpController.java:59:32:59:68 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| JsonpController.java:61:21:61:54 | ... + ... : String | semmle.label | ... + ... : String | +| JsonpController.java:62:16:62:24 | resultStr | semmle.label | resultStr | +| JsonpController.java:62:16:62:24 | resultStr | semmle.label | resultStr | +| JsonpController.java:69:32:69:68 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| JsonpController.java:76:21:76:54 | ... + ... : String | semmle.label | ... + ... : String | +| JsonpController.java:77:20:77:28 | resultStr | semmle.label | resultStr | +| JsonpController.java:77:20:77:28 | resultStr | semmle.label | resultStr | +| JsonpController.java:84:32:84:68 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| JsonpController.java:90:21:90:54 | ... + ... : String | semmle.label | ... + ... : String | +| JsonpController.java:91:20:91:28 | resultStr | semmle.label | resultStr | +| JsonpController.java:91:20:91:28 | resultStr | semmle.label | resultStr | +| JsonpController.java:99:24:99:52 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| JsonpController.java:101:24:101:28 | token | semmle.label | token | +| JsonpController.java:102:36:102:72 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| JsonpController.java:104:25:104:59 | ... + ... : String | semmle.label | ... + ... : String | +| JsonpController.java:105:20:105:28 | resultStr | semmle.label | resultStr | +| JsonpController.java:105:20:105:28 | resultStr | semmle.label | resultStr | +#select +| JsonpController.java:31:16:31:24 | resultStr | JsonpController.java:26:32:26:68 | getParameter(...) : String | JsonpController.java:31:16:31:24 | + resultStr | Jsonp Injection query might include code from $@. | JsonpController.java:26:32:26:68 | getParameter(...) | this user input | +| JsonpController.java:42:16:42:24 | resultStr | JsonpController.java:38:32:38:68 | getParameter(...) : String | JsonpController.java:42:16:42:24 | + resultStr | Jsonp Injection query might include code from $@. | JsonpController.java:38:32:38:68 | getParameter(...) | this user input | +| JsonpController.java:52:16:52:24 | resultStr | JsonpController.java:49:32:49:68 | getParameter(...) : String | JsonpController.java:52:16:52:24 | + resultStr | Jsonp Injection query might include code from $@. | JsonpController.java:49:32:49:68 | getParameter(...) | this user input | +| JsonpController.java:62:16:62:24 | resultStr | JsonpController.java:59:32:59:68 | getParameter(...) : String | JsonpController.java:62:16:62:24 | + resultStr | Jsonp Injection query might include code from $@. | JsonpController.java:59:32:59:68 | getParameter(...) | this user input | +| JsonpController.java:77:20:77:28 | resultStr | JsonpController.java:69:32:69:68 | getParameter(...) : String | JsonpController.java:77:20:77:28 | + resultStr | Jsonp Injection query might include code from $@. | JsonpController.java:69:32:69:68 | getParameter(...) | this user input | +| JsonpController.java:91:20:91:28 | resultStr | JsonpController.java:84:32:84:68 | getParameter(...) : String | JsonpController.java:91:20:91:28 | + resultStr | Jsonp Injection query might include code from $@. | JsonpController.java:84:32:84:68 | getParameter(...) | this user input | \ No newline at end of file diff --git a/java/ql/test/experimental/query-tests/security/CWE-352/JsonpInjection_2.expected b/java/ql/test/experimental/query-tests/security/CWE-352/JsonpInjection_2.expected new file mode 100644 index 00000000000..4b12308a212 --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/CWE-352/JsonpInjection_2.expected @@ -0,0 +1,78 @@ +edges +| JsonpController.java:26:32:26:68 | getParameter(...) : String | JsonpController.java:31:16:31:24 | resultStr | +| JsonpController.java:30:21:30:54 | ... + ... : String | JsonpController.java:31:16:31:24 | resultStr | +| JsonpController.java:38:32:38:68 | getParameter(...) : String | JsonpController.java:42:16:42:24 | resultStr | +| JsonpController.java:40:21:40:80 | ... + ... : String | JsonpController.java:42:16:42:24 | resultStr | +| JsonpController.java:49:32:49:68 | getParameter(...) : String | JsonpController.java:52:16:52:24 | resultStr | +| JsonpController.java:51:21:51:55 | ... + ... : String | JsonpController.java:52:16:52:24 | resultStr | +| JsonpController.java:59:32:59:68 | getParameter(...) : String | JsonpController.java:62:16:62:24 | resultStr | +| JsonpController.java:61:21:61:54 | ... + ... : String | JsonpController.java:62:16:62:24 | resultStr | +| JsonpController.java:69:32:69:68 | getParameter(...) : String | JsonpController.java:77:20:77:28 | resultStr | +| JsonpController.java:76:21:76:54 | ... + ... : String | JsonpController.java:77:20:77:28 | resultStr | +| JsonpController.java:84:32:84:68 | getParameter(...) : String | JsonpController.java:91:20:91:28 | resultStr | +| JsonpController.java:90:21:90:54 | ... + ... : String | JsonpController.java:91:20:91:28 | resultStr | +| JsonpController.java:99:24:99:52 | getParameter(...) : String | JsonpController.java:101:24:101:28 | token | +| JsonpController.java:102:36:102:72 | getParameter(...) : String | JsonpController.java:105:20:105:28 | resultStr | +| JsonpController.java:104:25:104:59 | ... + ... : String | JsonpController.java:105:20:105:28 | resultStr | +| JsonpInjectionServlet1.java:31:32:31:64 | getParameter(...) : String | JsonpInjectionServlet1.java:45:24:45:32 | resultStr | +| JsonpInjectionServlet1.java:36:26:36:49 | getHeader(...) : String | JsonpInjectionServlet1.java:38:39:38:45 | referer | +| JsonpInjectionServlet1.java:44:25:44:62 | ... + ... : String | JsonpInjectionServlet1.java:45:24:45:32 | resultStr | +| JsonpInjectionServlet2.java:31:32:31:64 | getParameter(...) : String | JsonpInjectionServlet2.java:39:20:39:28 | resultStr | +| JsonpInjectionServlet2.java:38:21:38:54 | ... + ... : String | JsonpInjectionServlet2.java:39:20:39:28 | resultStr | +nodes +| JsonpController.java:26:32:26:68 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| JsonpController.java:30:21:30:54 | ... + ... : String | semmle.label | ... + ... : String | +| JsonpController.java:31:16:31:24 | resultStr | semmle.label | resultStr | +| JsonpController.java:31:16:31:24 | resultStr | semmle.label | resultStr | +| JsonpController.java:38:32:38:68 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| JsonpController.java:40:21:40:80 | ... + ... : String | semmle.label | ... + ... : String | +| JsonpController.java:42:16:42:24 | resultStr | semmle.label | resultStr | +| JsonpController.java:42:16:42:24 | resultStr | semmle.label | resultStr | +| JsonpController.java:49:32:49:68 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| JsonpController.java:51:21:51:55 | ... + ... : String | semmle.label | ... + ... : String | +| JsonpController.java:52:16:52:24 | resultStr | semmle.label | resultStr | +| JsonpController.java:52:16:52:24 | resultStr | semmle.label | resultStr | +| JsonpController.java:59:32:59:68 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| JsonpController.java:61:21:61:54 | ... + ... : String | semmle.label | ... + ... : String | +| JsonpController.java:62:16:62:24 | resultStr | semmle.label | resultStr | +| JsonpController.java:62:16:62:24 | resultStr | semmle.label | resultStr | +| JsonpController.java:69:32:69:68 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| JsonpController.java:76:21:76:54 | ... + ... : String | semmle.label | ... + ... : String | +| JsonpController.java:77:20:77:28 | resultStr | semmle.label | resultStr | +| JsonpController.java:77:20:77:28 | resultStr | semmle.label | resultStr | +| JsonpController.java:84:32:84:68 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| JsonpController.java:90:21:90:54 | ... + ... : String | semmle.label | ... + ... : String | +| JsonpController.java:91:20:91:28 | resultStr | semmle.label | resultStr | +| JsonpController.java:91:20:91:28 | resultStr | semmle.label | resultStr | +| JsonpController.java:99:24:99:52 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| JsonpController.java:101:24:101:28 | token | semmle.label | token | +| JsonpController.java:102:36:102:72 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| JsonpController.java:104:25:104:59 | ... + ... : String | semmle.label | ... + ... : String | +| JsonpController.java:105:20:105:28 | resultStr | semmle.label | resultStr | +| JsonpController.java:105:20:105:28 | resultStr | semmle.label | resultStr | +| JsonpInjectionServlet1.java:31:32:31:64 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| JsonpInjectionServlet1.java:36:26:36:49 | getHeader(...) : String | semmle.label | getHeader(...) : String | +| JsonpInjectionServlet1.java:38:39:38:45 | referer | semmle.label | referer | +| JsonpInjectionServlet1.java:44:25:44:62 | ... + ... : String | semmle.label | ... + ... : String | +| JsonpInjectionServlet1.java:45:24:45:32 | resultStr | semmle.label | resultStr | +| JsonpInjectionServlet1.java:45:24:45:32 | resultStr | semmle.label | resultStr | +| JsonpInjectionServlet2.java:31:32:31:64 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| JsonpInjectionServlet2.java:38:21:38:54 | ... + ... : String | semmle.label | ... + ... : String | +| JsonpInjectionServlet2.java:39:20:39:28 | resultStr | semmle.label | resultStr | +| JsonpInjectionServlet2.java:39:20:39:28 | resultStr | semmle.label | resultStr | +#select +| JsonpController.java:31:16:31:24 | resultStr | JsonpController.java:26:32:26:68 | getParameter(...) : String | JsonpController.java:31:16:31:24 | + resultStr | Jsonp Injection query might include code from $@. | JsonpController.java:26:32:26:68 | getParameter(...) | this user input | +| JsonpController.java:42:16:42:24 | resultStr | JsonpController.java:38:32:38:68 | getParameter(...) : String | JsonpController.java:42:16:42:24 | + resultStr | Jsonp Injection query might include code from $@. | JsonpController.java:38:32:38:68 | getParameter(...) | this user input | +| JsonpController.java:52:16:52:24 | resultStr | JsonpController.java:49:32:49:68 | getParameter(...) : String | JsonpController.java:52:16:52:24 | + resultStr | Jsonp Injection query might include code from $@. | JsonpController.java:49:32:49:68 | getParameter(...) | this user input | +| JsonpController.java:62:16:62:24 | resultStr | JsonpController.java:59:32:59:68 | getParameter(...) : String | JsonpController.java:62:16:62:24 | + resultStr | Jsonp Injection query might include code from $@. | JsonpController.java:59:32:59:68 | getParameter(...) | this user input | +| JsonpController.java:77:20:77:28 | resultStr | JsonpController.java:69:32:69:68 | getParameter(...) : String | JsonpController.java:77:20:77:28 | + resultStr | Jsonp Injection query might include code from $@. | JsonpController.java:69:32:69:68 | getParameter(...) | this user input | +| JsonpController.java:91:20:91:28 | resultStr | JsonpController.java:84:32:84:68 | getParameter(...) : String | JsonpController.java:91:20:91:28 | + resultStr | Jsonp Injection query might include code from $@. | JsonpController.java:84:32:84:68 | getParameter(...) | this user input | +| JsonpInjectionServlet2.java:39:20:39:28 | resultStr | JsonpInjectionServlet2.java:31:32:31:64 | getParameter(...) : String | JsonpInjectionServle +t2.java:39:20:39:28 | resultStr | Jsonp Injection query might include code from $@. | JsonpInjectionServlet2.java:31:32:31:64 | getParameter(...) | + this user input | \ No newline at end of file diff --git a/java/ql/test/experimental/query-tests/security/CWE-352/JsonpInjection_3.expected b/java/ql/test/experimental/query-tests/security/CWE-352/JsonpInjection_3.expected new file mode 100644 index 00000000000..8e33ca6984c --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/CWE-352/JsonpInjection_3.expected @@ -0,0 +1,66 @@ +edges +| JsonpController.java:26:32:26:68 | getParameter(...) : String | JsonpController.java:31:16:31:24 | resultStr | +| JsonpController.java:30:21:30:54 | ... + ... : String | JsonpController.java:31:16:31:24 | resultStr | +| JsonpController.java:38:32:38:68 | getParameter(...) : String | JsonpController.java:42:16:42:24 | resultStr | +| JsonpController.java:40:21:40:80 | ... + ... : String | JsonpController.java:42:16:42:24 | resultStr | +| JsonpController.java:49:32:49:68 | getParameter(...) : String | JsonpController.java:52:16:52:24 | resultStr | +| JsonpController.java:51:21:51:55 | ... + ... : String | JsonpController.java:52:16:52:24 | resultStr | +| JsonpController.java:59:32:59:68 | getParameter(...) : String | JsonpController.java:62:16:62:24 | resultStr | +| JsonpController.java:61:21:61:54 | ... + ... : String | JsonpController.java:62:16:62:24 | resultStr | +| JsonpController.java:69:32:69:68 | getParameter(...) : String | JsonpController.java:77:20:77:28 | resultStr | +| JsonpController.java:76:21:76:54 | ... + ... : String | JsonpController.java:77:20:77:28 | resultStr | +| JsonpController.java:84:32:84:68 | getParameter(...) : String | JsonpController.java:91:20:91:28 | resultStr | +| JsonpController.java:90:21:90:54 | ... + ... : String | JsonpController.java:91:20:91:28 | resultStr | +| JsonpController.java:99:24:99:52 | getParameter(...) : String | JsonpController.java:101:24:101:28 | token | +| JsonpController.java:102:36:102:72 | getParameter(...) : String | JsonpController.java:105:20:105:28 | resultStr | +| JsonpController.java:104:25:104:59 | ... + ... : String | JsonpController.java:105:20:105:28 | resultStr | +| JsonpInjectionServlet1.java:31:32:31:64 | getParameter(...) : String | JsonpInjectionServlet1.java:45:24:45:32 | resultStr | +| JsonpInjectionServlet1.java:36:26:36:49 | getHeader(...) : String | JsonpInjectionServlet1.java:38:39:38:45 | referer | +| JsonpInjectionServlet1.java:44:25:44:62 | ... + ... : String | JsonpInjectionServlet1.java:45:24:45:32 | resultStr | +| JsonpInjectionServlet2.java:31:32:31:64 | getParameter(...) : String | JsonpInjectionServlet2.java:39:20:39:28 | resultStr | +| JsonpInjectionServlet2.java:38:21:38:54 | ... + ... : String | JsonpInjectionServlet2.java:39:20:39:28 | resultStr | +| RefererFilter.java:22:26:22:53 | getHeader(...) : String | RefererFilter.java:23:39:23:45 | refefer | +nodes +| JsonpController.java:26:32:26:68 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| JsonpController.java:30:21:30:54 | ... + ... : String | semmle.label | ... + ... : String | +| JsonpController.java:31:16:31:24 | resultStr | semmle.label | resultStr | +| JsonpController.java:31:16:31:24 | resultStr | semmle.label | resultStr | +| JsonpController.java:38:32:38:68 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| JsonpController.java:40:21:40:80 | ... + ... : String | semmle.label | ... + ... : String | +| JsonpController.java:42:16:42:24 | resultStr | semmle.label | resultStr | +| JsonpController.java:42:16:42:24 | resultStr | semmle.label | resultStr | +| JsonpController.java:49:32:49:68 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| JsonpController.java:51:21:51:55 | ... + ... : String | semmle.label | ... + ... : String | +| JsonpController.java:52:16:52:24 | resultStr | semmle.label | resultStr | +| JsonpController.java:52:16:52:24 | resultStr | semmle.label | resultStr | +| JsonpController.java:59:32:59:68 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| JsonpController.java:61:21:61:54 | ... + ... : String | semmle.label | ... + ... : String | +| JsonpController.java:62:16:62:24 | resultStr | semmle.label | resultStr | +| JsonpController.java:62:16:62:24 | resultStr | semmle.label | resultStr | +| JsonpController.java:69:32:69:68 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| JsonpController.java:76:21:76:54 | ... + ... : String | semmle.label | ... + ... : String | +| JsonpController.java:77:20:77:28 | resultStr | semmle.label | resultStr | +| JsonpController.java:77:20:77:28 | resultStr | semmle.label | resultStr | +| JsonpController.java:84:32:84:68 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| JsonpController.java:90:21:90:54 | ... + ... : String | semmle.label | ... + ... : String | +| JsonpController.java:91:20:91:28 | resultStr | semmle.label | resultStr | +| JsonpController.java:91:20:91:28 | resultStr | semmle.label | resultStr | +| JsonpController.java:99:24:99:52 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| JsonpController.java:101:24:101:28 | token | semmle.label | token | +| JsonpController.java:102:36:102:72 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| JsonpController.java:104:25:104:59 | ... + ... : String | semmle.label | ... + ... : String | +| JsonpController.java:105:20:105:28 | resultStr | semmle.label | resultStr | +| JsonpController.java:105:20:105:28 | resultStr | semmle.label | resultStr | +| JsonpInjectionServlet1.java:31:32:31:64 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| JsonpInjectionServlet1.java:36:26:36:49 | getHeader(...) : String | semmle.label | getHeader(...) : String | +| JsonpInjectionServlet1.java:38:39:38:45 | referer | semmle.label | referer | +| JsonpInjectionServlet1.java:44:25:44:62 | ... + ... : String | semmle.label | ... + ... : String | +| JsonpInjectionServlet1.java:45:24:45:32 | resultStr | semmle.label | resultStr | +| JsonpInjectionServlet1.java:45:24:45:32 | resultStr | semmle.label | resultStr | +| JsonpInjectionServlet2.java:31:32:31:64 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| JsonpInjectionServlet2.java:38:21:38:54 | ... + ... : String | semmle.label | ... + ... : String | +| JsonpInjectionServlet2.java:39:20:39:28 | resultStr | semmle.label | resultStr | +| JsonpInjectionServlet2.java:39:20:39:28 | resultStr | semmle.label | resultStr | +| RefererFilter.java:22:26:22:53 | getHeader(...) : String | semmle.label | getHeader(...) : String | +| RefererFilter.java:23:39:23:45 | refefer | semmle.label | refefer | +#select \ No newline at end of file diff --git a/java/ql/test/experimental/query-tests/security/CWE-352/Readme b/java/ql/test/experimental/query-tests/security/CWE-352/Readme new file mode 100644 index 00000000000..15715d6187c --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/CWE-352/Readme @@ -0,0 +1,3 @@ +1. The JsonpInjection_1.expected result is obtained through the test of `JsonpController.java`. +2. The JsonpInjection_2.expected result is obtained through the test of `JsonpController.java`, `JsonpInjectionServlet1.java`, `JsonpInjectionServlet2.java`. +3. The JsonpInjection_3.expected result is obtained through the test of `JsonpController.java`, `JsonpInjectionServlet1.java`, `JsonpInjectionServlet2.java`, `RefererFilter.java`. \ No newline at end of file diff --git a/java/ql/test/experimental/query-tests/security/CWE-352/RefererFilter.java b/java/ql/test/experimental/query-tests/security/CWE-352/RefererFilter.java new file mode 100644 index 00000000000..97444932ae1 --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/CWE-352/RefererFilter.java @@ -0,0 +1,43 @@ +import java.io.IOException; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.springframework.util.StringUtils; + +public class RefererFilter implements Filter { + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + } + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { + HttpServletRequest request = (HttpServletRequest) servletRequest; + HttpServletResponse response = (HttpServletResponse) servletResponse; + String refefer = request.getHeader("Referer"); + boolean result = verifReferer(refefer); + if (result){ + filterChain.doFilter(servletRequest, servletResponse); + } + response.sendError(444, "Referer xxx."); + } + + @Override + public void destroy() { + } + + public static boolean verifReferer(String referer){ + if (StringUtils.isEmpty(referer)){ + return false; + } + if (referer.startsWith("http://www.baidu.com/")){ + return true; + } + return false; + } +} diff --git a/java/ql/test/stubs/gson-2.8.6/com/google/gson/Gson.java b/java/ql/test/stubs/gson-2.8.6/com/google/gson/Gson.java new file mode 100644 index 00000000000..bbe53dc2a5f --- /dev/null +++ b/java/ql/test/stubs/gson-2.8.6/com/google/gson/Gson.java @@ -0,0 +1,7 @@ +package com.google.gson; + +public final class Gson { + public String toJson(Object src) { + return null; + } +} diff --git a/java/ql/test/stubs/spring-core-5.3.2/org/springframework/util/StringUtils.java b/java/ql/test/stubs/spring-core-5.3.2/org/springframework/util/StringUtils.java new file mode 100644 index 00000000000..6ee07f84593 --- /dev/null +++ b/java/ql/test/stubs/spring-core-5.3.2/org/springframework/util/StringUtils.java @@ -0,0 +1,8 @@ +package org.springframework.util; + +public abstract class StringUtils { + + public static boolean isEmpty(Object str) { + return str == null || "".equals(str); + } +} \ No newline at end of file diff --git a/java/ql/test/stubs/tomcat-embed-core-9.0.41/javax/servlet/Filter.java b/java/ql/test/stubs/tomcat-embed-core-9.0.41/javax/servlet/Filter.java new file mode 100644 index 00000000000..5833e3c909d --- /dev/null +++ b/java/ql/test/stubs/tomcat-embed-core-9.0.41/javax/servlet/Filter.java @@ -0,0 +1,13 @@ +package javax.servlet; + +import java.io.IOException; + +public interface Filter { + default void init(FilterConfig filterConfig) throws ServletException { + } + + void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException; + + default void destroy() { + } +} diff --git a/java/ql/test/stubs/tomcat-embed-core-9.0.41/javax/servlet/FilterChain.java b/java/ql/test/stubs/tomcat-embed-core-9.0.41/javax/servlet/FilterChain.java new file mode 100644 index 00000000000..6a1dfc588b6 --- /dev/null +++ b/java/ql/test/stubs/tomcat-embed-core-9.0.41/javax/servlet/FilterChain.java @@ -0,0 +1,8 @@ +package javax.servlet; + +import java.io.IOException; + +public interface FilterChain { + void doFilter(ServletRequest var1, ServletResponse var2) throws IOException, ServletException; +} + diff --git a/java/ql/test/stubs/tomcat-embed-core-9.0.41/javax/servlet/FilterConfig.java b/java/ql/test/stubs/tomcat-embed-core-9.0.41/javax/servlet/FilterConfig.java new file mode 100644 index 00000000000..66c13eb54f0 --- /dev/null +++ b/java/ql/test/stubs/tomcat-embed-core-9.0.41/javax/servlet/FilterConfig.java @@ -0,0 +1,3 @@ +package javax.servlet; + +public interface FilterConfig {} diff --git a/java/ql/test/stubs/tomcat-embed-core-9.0.41/javax/servlet/ServletException.java b/java/ql/test/stubs/tomcat-embed-core-9.0.41/javax/servlet/ServletException.java new file mode 100644 index 00000000000..ce5f7c4465a --- /dev/null +++ b/java/ql/test/stubs/tomcat-embed-core-9.0.41/javax/servlet/ServletException.java @@ -0,0 +1,8 @@ +package javax.servlet; + +public class ServletException extends Exception { + private static final long serialVersionUID = 1L; + + public ServletException() { + } +} diff --git a/java/ql/test/stubs/tomcat-embed-core-9.0.41/javax/servlet/ServletRequest.java b/java/ql/test/stubs/tomcat-embed-core-9.0.41/javax/servlet/ServletRequest.java new file mode 100644 index 00000000000..4ee0026d066 --- /dev/null +++ b/java/ql/test/stubs/tomcat-embed-core-9.0.41/javax/servlet/ServletRequest.java @@ -0,0 +1,87 @@ +package javax.servlet; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.util.Enumeration; +import java.util.Locale; +import java.util.Map; + +public interface ServletRequest { + Object getAttribute(String var1); + + Enumeration getAttributeNames(); + + String getCharacterEncoding(); + + void setCharacterEncoding(String var1) throws UnsupportedEncodingException; + + int getContentLength(); + + long getContentLengthLong(); + + String getContentType(); + + ServletInputStream getInputStream() throws IOException; + + String getParameter(String var1); + + Enumeration getParameterNames(); + + String[] getParameterValues(String var1); + + Map getParameterMap(); + + String getProtocol(); + + String getScheme(); + + String getServerName(); + + int getServerPort(); + + BufferedReader getReader() throws IOException; + + String getRemoteAddr(); + + String getRemoteHost(); + + void setAttribute(String var1, Object var2); + + void removeAttribute(String var1); + + Locale getLocale(); + + Enumeration getLocales(); + + boolean isSecure(); + + RequestDispatcher getRequestDispatcher(String var1); + + /** @deprecated */ + @Deprecated + String getRealPath(String var1); + + int getRemotePort(); + + String getLocalName(); + + String getLocalAddr(); + + int getLocalPort(); + + ServletContext getServletContext(); + + AsyncContext startAsync() throws IllegalStateException; + + AsyncContext startAsync(ServletRequest var1, ServletResponse var2) throws IllegalStateException; + + boolean isAsyncStarted(); + + boolean isAsyncSupported(); + + AsyncContext getAsyncContext(); + + DispatcherType getDispatcherType(); +} + diff --git a/java/ql/test/stubs/tomcat-embed-core-9.0.41/javax/servlet/ServletResponse.java b/java/ql/test/stubs/tomcat-embed-core-9.0.41/javax/servlet/ServletResponse.java new file mode 100644 index 00000000000..0aa6121e686 --- /dev/null +++ b/java/ql/test/stubs/tomcat-embed-core-9.0.41/javax/servlet/ServletResponse.java @@ -0,0 +1,39 @@ +package javax.servlet; + +import java.io.IOException; +import java.io.PrintWriter; +import java.util.Locale; + +public interface ServletResponse { + String getCharacterEncoding(); + + String getContentType(); + + ServletOutputStream getOutputStream() throws IOException; + + PrintWriter getWriter() throws IOException; + + void setCharacterEncoding(String var1); + + void setContentLength(int var1); + + void setContentLengthLong(long var1); + + void setContentType(String var1); + + void setBufferSize(int var1); + + int getBufferSize(); + + void flushBuffer() throws IOException; + + void resetBuffer(); + + boolean isCommitted(); + + void reset(); + + void setLocale(Locale var1); + + Locale getLocale(); +} diff --git a/java/ql/test/stubs/tomcat-embed-core-9.0.41/javax/servlet/http/HttpServletRequest.java b/java/ql/test/stubs/tomcat-embed-core-9.0.41/javax/servlet/http/HttpServletRequest.java new file mode 100644 index 00000000000..02d53a96a33 --- /dev/null +++ b/java/ql/test/stubs/tomcat-embed-core-9.0.41/javax/servlet/http/HttpServletRequest.java @@ -0,0 +1,116 @@ +package javax.servlet.http; + +import java.io.IOException; +import java.security.Principal; +import java.util.Collection; +import java.util.Collections; +import java.util.Enumeration; +import java.util.Map; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; + +public interface HttpServletRequest extends ServletRequest { + String BASIC_AUTH = "BASIC"; + String FORM_AUTH = "FORM"; + String CLIENT_CERT_AUTH = "CLIENT_CERT"; + String DIGEST_AUTH = "DIGEST"; + + String getAuthType(); + + Cookie[] getCookies(); + + long getDateHeader(String var1); + + String getHeader(String var1); + + Enumeration getHeaders(String var1); + + Enumeration getHeaderNames(); + + int getIntHeader(String var1); + + default HttpServletMapping getHttpServletMapping() { + return new HttpServletMapping() { + public String getMatchValue() { + return ""; + } + + public String getPattern() { + return ""; + } + + public String getServletName() { + return ""; + } + + public MappingMatch getMappingMatch() { + return null; + } + }; + } + + String getMethod(); + + String getPathInfo(); + + String getPathTranslated(); + + default PushBuilder newPushBuilder() { + return null; + } + + String getContextPath(); + + String getQueryString(); + + String getRemoteUser(); + + boolean isUserInRole(String var1); + + Principal getUserPrincipal(); + + String getRequestedSessionId(); + + String getRequestURI(); + + StringBuffer getRequestURL(); + + String getServletPath(); + + HttpSession getSession(boolean var1); + + HttpSession getSession(); + + String changeSessionId(); + + boolean isRequestedSessionIdValid(); + + boolean isRequestedSessionIdFromCookie(); + + boolean isRequestedSessionIdFromURL(); + + /** @deprecated */ + @Deprecated + boolean isRequestedSessionIdFromUrl(); + + boolean authenticate(HttpServletResponse var1) throws IOException, ServletException; + + void login(String var1, String var2) throws ServletException; + + void logout() throws ServletException; + + Collection getParts() throws IOException, ServletException; + + Part getPart(String var1) throws IOException, ServletException; + + T upgrade(Class var1) throws IOException, ServletException; + + default Map getTrailerFields() { + return Collections.emptyMap(); + } + + default boolean isTrailerFieldsReady() { + return false; + } +} + diff --git a/java/ql/test/stubs/tomcat-embed-core-9.0.41/javax/servlet/http/HttpServletResponse.java b/java/ql/test/stubs/tomcat-embed-core-9.0.41/javax/servlet/http/HttpServletResponse.java new file mode 100644 index 00000000000..0a2c6af0913 --- /dev/null +++ b/java/ql/test/stubs/tomcat-embed-core-9.0.41/javax/servlet/http/HttpServletResponse.java @@ -0,0 +1,106 @@ +package javax.servlet.http; + +import java.io.IOException; +import java.util.Collection; +import java.util.Map; +import java.util.function.Supplier; +import javax.servlet.ServletResponse; + +public interface HttpServletResponse extends ServletResponse { + int SC_CONTINUE = 100; + int SC_SWITCHING_PROTOCOLS = 101; + int SC_OK = 200; + int SC_CREATED = 201; + int SC_ACCEPTED = 202; + int SC_NON_AUTHORITATIVE_INFORMATION = 203; + int SC_NO_CONTENT = 204; + int SC_RESET_CONTENT = 205; + int SC_PARTIAL_CONTENT = 206; + int SC_MULTIPLE_CHOICES = 300; + int SC_MOVED_PERMANENTLY = 301; + int SC_MOVED_TEMPORARILY = 302; + int SC_FOUND = 302; + int SC_SEE_OTHER = 303; + int SC_NOT_MODIFIED = 304; + int SC_USE_PROXY = 305; + int SC_TEMPORARY_REDIRECT = 307; + int SC_BAD_REQUEST = 400; + int SC_UNAUTHORIZED = 401; + int SC_PAYMENT_REQUIRED = 402; + int SC_FORBIDDEN = 403; + int SC_NOT_FOUND = 404; + int SC_METHOD_NOT_ALLOWED = 405; + int SC_NOT_ACCEPTABLE = 406; + int SC_PROXY_AUTHENTICATION_REQUIRED = 407; + int SC_REQUEST_TIMEOUT = 408; + int SC_CONFLICT = 409; + int SC_GONE = 410; + int SC_LENGTH_REQUIRED = 411; + int SC_PRECONDITION_FAILED = 412; + int SC_REQUEST_ENTITY_TOO_LARGE = 413; + int SC_REQUEST_URI_TOO_LONG = 414; + int SC_UNSUPPORTED_MEDIA_TYPE = 415; + int SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416; + int SC_EXPECTATION_FAILED = 417; + int SC_INTERNAL_SERVER_ERROR = 500; + int SC_NOT_IMPLEMENTED = 501; + int SC_BAD_GATEWAY = 502; + int SC_SERVICE_UNAVAILABLE = 503; + int SC_GATEWAY_TIMEOUT = 504; + int SC_HTTP_VERSION_NOT_SUPPORTED = 505; + + void addCookie(Cookie var1); + + boolean containsHeader(String var1); + + String encodeURL(String var1); + + String encodeRedirectURL(String var1); + + /** @deprecated */ + @Deprecated + String encodeUrl(String var1); + + /** @deprecated */ + @Deprecated + String encodeRedirectUrl(String var1); + + void sendError(int var1, String var2) throws IOException; + + void sendError(int var1) throws IOException; + + void sendRedirect(String var1) throws IOException; + + void setDateHeader(String var1, long var2); + + void addDateHeader(String var1, long var2); + + void setHeader(String var1, String var2); + + void addHeader(String var1, String var2); + + void setIntHeader(String var1, int var2); + + void addIntHeader(String var1, int var2); + + void setStatus(int var1); + + /** @deprecated */ + @Deprecated + void setStatus(int var1, String var2); + + int getStatus(); + + String getHeader(String var1); + + Collection getHeaders(String var1); + + Collection getHeaderNames(); + + default void setTrailerFields(Supplier> supplier) { + } + + default Supplier> getTrailerFields() { + return null; + } +}