mirror of
https://github.com/github/codeql.git
synced 2026-04-29 02:35:15 +02:00
Merge branch 'main' into atorralba/promote-jndi-injection
This commit is contained in:
@@ -1,10 +1,14 @@
|
||||
edges
|
||||
| Test.java:6:35:6:44 | arg : String | Test.java:7:44:7:69 | ... + ... |
|
||||
| Test.java:6:35:6:44 | arg : String | Test.java:10:29:10:74 | new String[] |
|
||||
| Test.java:6:35:6:44 | arg : String | Test.java:10:61:10:73 | ... + ... : String |
|
||||
| Test.java:6:35:6:44 | arg : String | Test.java:16:13:16:25 | ... + ... : String |
|
||||
| Test.java:6:35:6:44 | arg : String | Test.java:24:29:24:32 | cmd1 |
|
||||
| Test.java:16:5:16:7 | cmd [post update] : List | Test.java:18:29:18:31 | cmd |
|
||||
| Test.java:16:13:16:25 | ... + ... : String | Test.java:16:5:16:7 | cmd [post update] : List |
|
||||
| Test.java:6:35:6:44 | arg : String | Test.java:22:15:22:27 | ... + ... : String |
|
||||
| Test.java:10:29:10:74 | {...} [[]] : String | Test.java:10:29:10:74 | new String[] |
|
||||
| Test.java:10:61:10:73 | ... + ... : String | Test.java:10:29:10:74 | {...} [[]] : String |
|
||||
| Test.java:16:5:16:7 | cmd [post update] [<element>] : String | Test.java:18:29:18:31 | cmd |
|
||||
| Test.java:16:13:16:25 | ... + ... : String | Test.java:16:5:16:7 | cmd [post update] [<element>] : String |
|
||||
| Test.java:22:5:22:8 | cmd1 [post update] [[]] : String | Test.java:24:29:24:32 | cmd1 |
|
||||
| Test.java:22:15:22:27 | ... + ... : String | Test.java:22:5:22:8 | cmd1 [post update] [[]] : String |
|
||||
| Test.java:28:38:28:47 | arg : String | Test.java:29:44:29:64 | ... + ... |
|
||||
| Test.java:57:27:57:39 | args : String[] | Test.java:60:20:60:22 | arg : String |
|
||||
| Test.java:57:27:57:39 | args : String[] | Test.java:61:23:61:25 | arg : String |
|
||||
@@ -14,9 +18,13 @@ nodes
|
||||
| Test.java:6:35:6:44 | arg : String | semmle.label | arg : String |
|
||||
| Test.java:7:44:7:69 | ... + ... | semmle.label | ... + ... |
|
||||
| Test.java:10:29:10:74 | new String[] | semmle.label | new String[] |
|
||||
| Test.java:16:5:16:7 | cmd [post update] : List | semmle.label | cmd [post update] : List |
|
||||
| Test.java:10:29:10:74 | {...} [[]] : String | semmle.label | {...} [[]] : String |
|
||||
| Test.java:10:61:10:73 | ... + ... : String | semmle.label | ... + ... : String |
|
||||
| Test.java:16:5:16:7 | cmd [post update] [<element>] : String | semmle.label | cmd [post update] [<element>] : String |
|
||||
| Test.java:16:13:16:25 | ... + ... : String | semmle.label | ... + ... : String |
|
||||
| Test.java:18:29:18:31 | cmd | semmle.label | cmd |
|
||||
| Test.java:22:5:22:8 | cmd1 [post update] [[]] : String | semmle.label | cmd1 [post update] [[]] : String |
|
||||
| Test.java:22:15:22:27 | ... + ... : String | semmle.label | ... + ... : String |
|
||||
| Test.java:24:29:24:32 | cmd1 | semmle.label | cmd1 |
|
||||
| Test.java:28:38:28:47 | arg : String | semmle.label | arg : String |
|
||||
| Test.java:29:44:29:64 | ... + ... | semmle.label | ... + ... |
|
||||
|
||||
@@ -0,0 +1,247 @@
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.Variant;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
@Path("")
|
||||
public class JaxXSS {
|
||||
|
||||
@GET
|
||||
public static Response specificContentType(boolean safeContentType, boolean chainDirectly, boolean contentTypeFirst, String userControlled) {
|
||||
|
||||
Response.ResponseBuilder builder = Response.ok();
|
||||
|
||||
if(!safeContentType) {
|
||||
if(chainDirectly) {
|
||||
if(contentTypeFirst)
|
||||
return builder.type(MediaType.TEXT_HTML).entity(userControlled).build(); // $xss
|
||||
else
|
||||
return builder.entity(userControlled).type(MediaType.TEXT_HTML).build(); // $xss
|
||||
}
|
||||
else {
|
||||
if(contentTypeFirst) {
|
||||
Response.ResponseBuilder builder2 = builder.type(MediaType.TEXT_HTML);
|
||||
return builder2.entity(userControlled).build(); // $xss
|
||||
}
|
||||
else {
|
||||
Response.ResponseBuilder builder2 = builder.entity(userControlled);
|
||||
return builder2.type(MediaType.TEXT_HTML).build(); // $xss
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(chainDirectly) {
|
||||
if(contentTypeFirst)
|
||||
return builder.type(MediaType.APPLICATION_JSON).entity(userControlled).build(); // $SPURIOUS: xss
|
||||
else
|
||||
return builder.entity(userControlled).type(MediaType.APPLICATION_JSON).build(); // $SPURIOUS: xss
|
||||
}
|
||||
else {
|
||||
if(contentTypeFirst) {
|
||||
Response.ResponseBuilder builder2 = builder.type(MediaType.APPLICATION_JSON);
|
||||
return builder2.entity(userControlled).build(); // $SPURIOUS: xss
|
||||
}
|
||||
else {
|
||||
Response.ResponseBuilder builder2 = builder.entity(userControlled);
|
||||
return builder2.type(MediaType.APPLICATION_JSON).build(); // $SPURIOUS: xss
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@GET
|
||||
public static Response specificContentTypeSetterMethods(int route, boolean safeContentType, String userControlled) {
|
||||
|
||||
// Test the remarkably many routes to setting a content-type in Jax-RS, besides the ResponseBuilder.entity method used above:
|
||||
|
||||
if(safeContentType) {
|
||||
if(route == 0) {
|
||||
// via ok, as a string literal:
|
||||
return Response.ok(userControlled, "application/json").build(); // $SPURIOUS: xss
|
||||
}
|
||||
else if(route == 1) {
|
||||
// via ok, as a string constant:
|
||||
return Response.ok(userControlled, MediaType.APPLICATION_JSON).build(); // $SPURIOUS: xss
|
||||
}
|
||||
else if(route == 2) {
|
||||
// via ok, as a MediaType constant:
|
||||
return Response.ok(userControlled, MediaType.APPLICATION_JSON_TYPE).build(); // $SPURIOUS: xss
|
||||
}
|
||||
else if(route == 3) {
|
||||
// via ok, as a Variant, via constructor:
|
||||
return Response.ok(userControlled, new Variant(MediaType.APPLICATION_JSON_TYPE, "language", "encoding")).build(); // $SPURIOUS: xss
|
||||
}
|
||||
else if(route == 4) {
|
||||
// via ok, as a Variant, via static method:
|
||||
return Response.ok(userControlled, Variant.mediaTypes(MediaType.APPLICATION_JSON_TYPE).build().get(0)).build(); // $SPURIOUS: xss
|
||||
}
|
||||
else if(route == 5) {
|
||||
// via ok, as a Variant, via instance method:
|
||||
return Response.ok(userControlled, Variant.languages(Locale.UK).mediaTypes(MediaType.APPLICATION_JSON_TYPE).build().get(0)).build(); // $SPURIOUS: xss
|
||||
}
|
||||
else if(route == 6) {
|
||||
// via builder variant, before entity:
|
||||
return Response.ok().variant(new Variant(MediaType.APPLICATION_JSON_TYPE, "language", "encoding")).entity(userControlled).build(); // $SPURIOUS: xss
|
||||
}
|
||||
else if(route == 7) {
|
||||
// via builder variant, after entity:
|
||||
return Response.ok().entity(userControlled).variant(new Variant(MediaType.APPLICATION_JSON_TYPE, "language", "encoding")).build(); // $SPURIOUS: xss
|
||||
}
|
||||
else if(route == 8) {
|
||||
// provide entity via ok, then content-type via builder:
|
||||
return Response.ok(userControlled).type(MediaType.APPLICATION_JSON_TYPE).build(); // $SPURIOUS: xss
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(route == 0) {
|
||||
// via ok, as a string literal:
|
||||
return Response.ok("text/html").entity(userControlled).build(); // $xss
|
||||
}
|
||||
else if(route == 1) {
|
||||
// via ok, as a string constant:
|
||||
return Response.ok(MediaType.TEXT_HTML).entity(userControlled).build(); // $xss
|
||||
}
|
||||
else if(route == 2) {
|
||||
// via ok, as a MediaType constant:
|
||||
return Response.ok(MediaType.TEXT_HTML_TYPE).entity(userControlled).build(); // $xss
|
||||
}
|
||||
else if(route == 3) {
|
||||
// via ok, as a Variant, via constructor:
|
||||
return Response.ok(new Variant(MediaType.TEXT_HTML_TYPE, "language", "encoding")).entity(userControlled).build(); // $xss
|
||||
}
|
||||
else if(route == 4) {
|
||||
// via ok, as a Variant, via static method:
|
||||
return Response.ok(Variant.mediaTypes(MediaType.TEXT_HTML_TYPE).build()).entity(userControlled).build(); // $xss
|
||||
}
|
||||
else if(route == 5) {
|
||||
// via ok, as a Variant, via instance method:
|
||||
return Response.ok(Variant.languages(Locale.UK).mediaTypes(MediaType.TEXT_HTML_TYPE).build()).entity(userControlled).build(); // $xss
|
||||
}
|
||||
else if(route == 6) {
|
||||
// via builder variant, before entity:
|
||||
return Response.ok().variant(new Variant(MediaType.TEXT_HTML_TYPE, "language", "encoding")).entity(userControlled).build(); // $xss
|
||||
}
|
||||
else if(route == 7) {
|
||||
// via builder variant, after entity:
|
||||
return Response.ok().entity(userControlled).variant(new Variant(MediaType.TEXT_HTML_TYPE, "language", "encoding")).build(); // $xss
|
||||
}
|
||||
else if(route == 8) {
|
||||
// provide entity via ok, then content-type via builder:
|
||||
return Response.ok(userControlled).type(MediaType.TEXT_HTML_TYPE).build(); // $xss
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
@GET @Produces(MediaType.APPLICATION_JSON)
|
||||
public static Response methodContentTypeSafe(String userControlled) {
|
||||
return Response.ok(userControlled).build();
|
||||
}
|
||||
|
||||
@POST @Produces(MediaType.APPLICATION_JSON)
|
||||
public static Response methodContentTypeSafePost(String userControlled) {
|
||||
return Response.ok(userControlled).build();
|
||||
}
|
||||
|
||||
@GET @Produces("application/json")
|
||||
public static Response methodContentTypeSafeStringLiteral(String userControlled) {
|
||||
return Response.ok(userControlled).build();
|
||||
}
|
||||
|
||||
@GET @Produces(MediaType.TEXT_HTML)
|
||||
public static Response methodContentTypeUnsafe(String userControlled) {
|
||||
return Response.ok(userControlled).build(); // $MISSING: xss
|
||||
}
|
||||
|
||||
@POST @Produces(MediaType.TEXT_HTML)
|
||||
public static Response methodContentTypeUnsafePost(String userControlled) {
|
||||
return Response.ok(userControlled).build(); // $MISSING: xss
|
||||
}
|
||||
|
||||
@GET @Produces("text/html")
|
||||
public static Response methodContentTypeUnsafeStringLiteral(String userControlled) {
|
||||
return Response.ok(userControlled).build(); // $MISSING: xss
|
||||
}
|
||||
|
||||
@GET @Produces({MediaType.TEXT_HTML, MediaType.APPLICATION_JSON})
|
||||
public static Response methodContentTypeMaybeSafe(String userControlled) {
|
||||
return Response.ok(userControlled).build(); // $MISSING: xss
|
||||
}
|
||||
|
||||
@GET @Produces(MediaType.APPLICATION_JSON)
|
||||
public static Response methodContentTypeSafeOverriddenWithUnsafe(String userControlled) {
|
||||
return Response.ok().type(MediaType.TEXT_HTML).entity(userControlled).build(); // $MISSING: xss
|
||||
}
|
||||
|
||||
@GET @Produces(MediaType.TEXT_HTML)
|
||||
public static Response methodContentTypeUnsafeOverriddenWithSafe(String userControlled) {
|
||||
return Response.ok().type(MediaType.APPLICATION_JSON).entity(userControlled).build();
|
||||
}
|
||||
|
||||
@Path("/abc")
|
||||
@Produces({"application/json"})
|
||||
public static class ClassContentTypeSafe {
|
||||
@GET
|
||||
public Response test(String userControlled) {
|
||||
return Response.ok(userControlled).build();
|
||||
}
|
||||
|
||||
@GET
|
||||
public String testDirectReturn(String userControlled) {
|
||||
return userControlled;
|
||||
}
|
||||
|
||||
@GET @Produces({"text/html"})
|
||||
public Response overridesWithUnsafe(String userControlled) {
|
||||
return Response.ok(userControlled).build(); // $MISSING: xss
|
||||
}
|
||||
|
||||
@GET
|
||||
public Response overridesWithUnsafe2(String userControlled) {
|
||||
return Response.ok().type(MediaType.TEXT_HTML).entity(userControlled).build(); // $MISSING: xss
|
||||
}
|
||||
}
|
||||
|
||||
@Path("/abc")
|
||||
@Produces({"text/html"})
|
||||
public static class ClassContentTypeUnsafe {
|
||||
@GET
|
||||
public Response test(String userControlled) {
|
||||
return Response.ok(userControlled).build(); // $MISSING: xss
|
||||
}
|
||||
|
||||
@GET
|
||||
public String testDirectReturn(String userControlled) {
|
||||
return userControlled; // $MISSING: xss
|
||||
}
|
||||
|
||||
@GET @Produces({"application/json"})
|
||||
public Response overridesWithSafe(String userControlled) {
|
||||
return Response.ok(userControlled).build();
|
||||
}
|
||||
|
||||
@GET
|
||||
public Response overridesWithSafe2(String userControlled) {
|
||||
return Response.ok().type(MediaType.APPLICATION_JSON).entity(userControlled).build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
public static Response entityWithNoMediaType(String userControlled) {
|
||||
return Response.ok(userControlled).build(); // $xss
|
||||
}
|
||||
|
||||
@GET
|
||||
public static String stringWithNoMediaType(String userControlled) {
|
||||
return userControlled; // $xss
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
edges
|
||||
| XSS.java:23:21:23:48 | getParameter(...) : String | XSS.java:23:5:23:70 | ... + ... |
|
||||
| XSS.java:38:67:38:87 | getPathInfo(...) : String | XSS.java:38:30:38:87 | ... + ... |
|
||||
| XSS.java:41:36:41:56 | getPathInfo(...) : String | XSS.java:41:36:41:67 | getBytes(...) |
|
||||
nodes
|
||||
| XSS.java:23:5:23:70 | ... + ... | semmle.label | ... + ... |
|
||||
| XSS.java:23:21:23:48 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| XSS.java:38:30:38:87 | ... + ... | semmle.label | ... + ... |
|
||||
| XSS.java:38:67:38:87 | getPathInfo(...) : String | semmle.label | getPathInfo(...) : String |
|
||||
| XSS.java:41:36:41:56 | getPathInfo(...) : String | semmle.label | getPathInfo(...) : String |
|
||||
| XSS.java:41:36:41:67 | getBytes(...) | semmle.label | getBytes(...) |
|
||||
#select
|
||||
| XSS.java:23:5:23:70 | ... + ... | XSS.java:23:21:23:48 | getParameter(...) : String | XSS.java:23:5:23:70 | ... + ... | Cross-site scripting vulnerability due to $@. | XSS.java:23:21:23:48 | getParameter(...) | user-provided value |
|
||||
| XSS.java:38:30:38:87 | ... + ... | XSS.java:38:67:38:87 | getPathInfo(...) : String | XSS.java:38:30:38:87 | ... + ... | Cross-site scripting vulnerability due to $@. | XSS.java:38:67:38:87 | getPathInfo(...) | user-provided value |
|
||||
| XSS.java:41:36:41:67 | getBytes(...) | XSS.java:41:36:41:56 | getPathInfo(...) : String | XSS.java:41:36:41:67 | getBytes(...) | Cross-site scripting vulnerability due to $@. | XSS.java:41:36:41:56 | getPathInfo(...) | user-provided value |
|
||||
|
||||
@@ -20,7 +20,7 @@ public class XSS extends HttpServlet {
|
||||
throws ServletException, IOException {
|
||||
// BAD: a request parameter is written directly to the Servlet response stream
|
||||
response.getWriter().print(
|
||||
"The page \"" + request.getParameter("page") + "\" was not found.");
|
||||
"The page \"" + request.getParameter("page") + "\" was not found."); // $xss
|
||||
|
||||
// GOOD: servlet API encodes the error message HTML for the HTML context
|
||||
response.sendError(HttpServletResponse.SC_NOT_FOUND,
|
||||
@@ -35,10 +35,10 @@ public class XSS extends HttpServlet {
|
||||
"The page \"" + capitalizeName(request.getParameter("page")) + "\" was not found.");
|
||||
|
||||
// BAD: outputting the path of the resource
|
||||
response.getWriter().print("The path section of the URL was " + request.getPathInfo());
|
||||
response.getWriter().print("The path section of the URL was " + request.getPathInfo()); // $xss
|
||||
|
||||
// BAD: typical XSS, this time written to an OutputStream instead of a Writer
|
||||
response.getOutputStream().write(request.getPathInfo().getBytes());
|
||||
response.getOutputStream().write(request.getPathInfo().getBytes()); // $xss
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import semmle.code.java.security.XSS
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
|
||||
class XSSConfig extends TaintTracking::Configuration {
|
||||
XSSConfig() { this = "XSSConfig" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof XssSink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) { node instanceof XssSanitizer }
|
||||
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
any(XssAdditionalTaintStep s).step(node1, node2)
|
||||
}
|
||||
}
|
||||
|
||||
class XssTest extends InlineExpectationsTest {
|
||||
XssTest() { this = "XssTest" }
|
||||
|
||||
override string getARelevantTag() { result = ["xss"] }
|
||||
|
||||
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "xss" and
|
||||
exists(DataFlow::Node src, DataFlow::Node sink, XSSConfig conf | conf.hasFlow(src, sink) |
|
||||
sink.getLocation() = location and
|
||||
element = sink.toString() and
|
||||
value = ""
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
Security/CWE/CWE-079/XSS.ql
|
||||
@@ -1 +1 @@
|
||||
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/servlet-api-2.4
|
||||
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/servlet-api-2.4:${testdir}/../../../../../stubs/javax-ws-rs-api-2.1.1/
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
import java.sql.ResultSet;
|
||||
import java.util.Map;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.jdbc.object.BatchSqlUpdate;
|
||||
import org.springframework.jdbc.object.MappingSqlQueryWithParameters;
|
||||
import org.springframework.jdbc.object.SqlFunction;
|
||||
import org.springframework.jdbc.object.SqlUpdate;
|
||||
import org.springframework.jdbc.object.UpdatableSqlQuery;
|
||||
|
||||
public class SpringJdbc {
|
||||
|
||||
public static String source() { return null; }
|
||||
|
||||
private static class MyUpdatableSqlQuery extends UpdatableSqlQuery<String> {
|
||||
public MyUpdatableSqlQuery() {
|
||||
super(null, source()); // $ sqlInjection
|
||||
}
|
||||
|
||||
protected String updateRow(ResultSet rs, int rowNum, Map<?,?> context) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void test(JdbcTemplate template) {
|
||||
new BatchSqlUpdate(null, source()); // $ sqlInjection
|
||||
new SqlFunction(null, source()); // $ sqlInjection
|
||||
new SqlUpdate(null, source()); // $ sqlInjection
|
||||
|
||||
(new BatchSqlUpdate()).setSql(source()); // $ sqlInjection
|
||||
|
||||
template.batchUpdate(source()); // $ sqlInjection
|
||||
template.batchUpdate(source(), null, 0, null); // $ sqlInjection
|
||||
template.execute(source()); // $ sqlInjection
|
||||
template.update(source()); // $ sqlInjection
|
||||
template.query(source(), (RowMapper)null); // $ sqlInjection
|
||||
template.queryForList(source()); // $ sqlInjection
|
||||
template.queryForMap(source()); // $ sqlInjection
|
||||
template.queryForObject(source(), (Class)null); // $ sqlInjection
|
||||
template.queryForRowSet(source()); // $ sqlInjection
|
||||
template.queryForStream(source(), (RowMapper)null); // $ sqlInjection
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/mongodbClient
|
||||
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/mongodbClient:${testdir}/../../../../../stubs/springframework-5.3.8
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.TaintTracking
|
||||
import semmle.code.java.security.QueryInjection
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
|
||||
private class QueryInjectionFlowConfig extends TaintTracking::Configuration {
|
||||
QueryInjectionFlowConfig() { this = "SqlInjectionLib::QueryInjectionFlowConfig" }
|
||||
|
||||
override predicate isSource(DataFlow::Node src) {
|
||||
src.asExpr() = any(MethodAccess ma | ma.getMethod().hasName("source"))
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof QueryInjectionSink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
node.getType() instanceof PrimitiveType or
|
||||
node.getType() instanceof BoxedType or
|
||||
node.getType() instanceof NumberType
|
||||
}
|
||||
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
any(AdditionalQueryInjectionTaintStep s).step(node1, node2)
|
||||
}
|
||||
}
|
||||
|
||||
class HasFlowTest extends InlineExpectationsTest {
|
||||
HasFlowTest() { this = "HasFlowTest" }
|
||||
|
||||
override string getARelevantTag() { result = "sqlInjection" }
|
||||
|
||||
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "sqlInjection" and
|
||||
exists(DataFlow::Node src, DataFlow::Node sink, QueryInjectionFlowConfig conf |
|
||||
conf.hasFlow(src, sink)
|
||||
|
|
||||
sink.getLocation() = location and
|
||||
element = sink.toString() and
|
||||
value = ""
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/springframework-5.2.3:${testdir}/../../../stubs/spring-ldap-2.3.2:${testdir}/../../../stubs/unboundid-ldap-4.0.14:${testdir}/../../../stubs/esapi-2.0.1:${testdir}/../../../stubs/apache-ldap-1.0.2
|
||||
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/springframework-5.3.8:${testdir}/../../../stubs/spring-ldap-2.3.2:${testdir}/../../../stubs/unboundid-ldap-4.0.14:${testdir}/../../../stubs/esapi-2.0.1:${testdir}/../../../stubs/apache-ldap-1.0.2
|
||||
|
||||
@@ -1,22 +1,7 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.DataFlow
|
||||
import semmle.code.java.dataflow.FlowSteps
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import semmle.code.java.security.JexlInjection
|
||||
import semmle.code.java.security.JexlInjectionQuery
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
|
||||
class Conf extends TaintTracking::Configuration {
|
||||
Conf() { this = "qltest:cwe:jexl-injection" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof JexlEvaluationSink }
|
||||
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
any(JexlInjectionAdditionalTaintStep c).step(node1, node2)
|
||||
}
|
||||
}
|
||||
|
||||
class JexlInjectionTest extends InlineExpectationsTest {
|
||||
JexlInjectionTest() { this = "HasJexlInjectionTest" }
|
||||
|
||||
@@ -24,7 +9,9 @@ class JexlInjectionTest extends InlineExpectationsTest {
|
||||
|
||||
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "hasJexlInjection" and
|
||||
exists(DataFlow::Node src, DataFlow::Node sink, Conf conf | conf.hasFlow(src, sink) |
|
||||
exists(DataFlow::Node src, DataFlow::Node sink, JexlInjectionConfig conf |
|
||||
conf.hasFlow(src, sink)
|
||||
|
|
||||
sink.getLocation() = location and
|
||||
element = sink.toString() and
|
||||
value = ""
|
||||
|
||||
@@ -1 +1 @@
|
||||
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/validation-api-2.0.1.Final:${testdir}/../../../stubs/springframework-5.2.3:${testdir}/../../../stubs/apache-commons-jexl-2.1.1:${testdir}/../../../stubs/apache-commons-jexl-3.1:${testdir}/../../../stubs/apache-commons-logging-1.2
|
||||
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/validation-api-2.0.1.Final:${testdir}/../../../stubs/springframework-5.3.8:${testdir}/../../../stubs/apache-commons-jexl-2.1.1:${testdir}/../../../stubs/apache-commons-jexl-3.1:${testdir}/../../../stubs/apache-commons-logging-1.2
|
||||
|
||||
114
java/ql/test/query-tests/security/CWE-502/C.java
Normal file
114
java/ql/test/query-tests/security/CWE-502/C.java
Normal file
@@ -0,0 +1,114 @@
|
||||
import java.util.HashMap;
|
||||
import java.io.StringReader;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import com.cedarsoftware.util.io.JsonReader;
|
||||
import com.esotericsoftware.yamlbeans.YamlReader;
|
||||
import org.ho.yaml.Yaml;
|
||||
import org.ho.yaml.YamlConfig;
|
||||
import org.exolab.castor.xml.Unmarshaller;
|
||||
import com.caucho.hessian.io.Hessian2Input;
|
||||
import com.caucho.hessian.io.HessianInput;
|
||||
import com.caucho.burlap.io.BurlapInput;
|
||||
import com.caucho.hessian.io.Hessian2Input;
|
||||
import com.caucho.hessian.io.HessianInput;
|
||||
import java.io.ByteArrayInputStream;
|
||||
|
||||
@Controller
|
||||
public class C {
|
||||
|
||||
@GetMapping(value = "jyaml")
|
||||
public void bad1(HttpServletRequest request) throws Exception {
|
||||
String data = request.getParameter("data");
|
||||
Yaml.load(data); //bad
|
||||
Yaml.loadStream(data); //bad
|
||||
Yaml.loadStreamOfType(data, Object.class); //bad
|
||||
Yaml.loadType(data, Object.class); //bad
|
||||
|
||||
org.ho.yaml.YamlConfig yamlConfig = new YamlConfig();
|
||||
yamlConfig.load(data); //bad
|
||||
yamlConfig.loadStream(data); //bad
|
||||
yamlConfig.loadStreamOfType(data, Object.class); //bad
|
||||
yamlConfig.loadType(data, Object.class); //bad
|
||||
}
|
||||
|
||||
@GetMapping(value = "jsonio")
|
||||
public void bad2(HttpServletRequest request) {
|
||||
String data = request.getParameter("data");
|
||||
|
||||
HashMap hashMap = new HashMap();
|
||||
hashMap.put("USE_MAPS", true);
|
||||
|
||||
JsonReader.jsonToJava(data); //bad
|
||||
|
||||
JsonReader jr = new JsonReader(data, null); //bad
|
||||
jr.readObject();
|
||||
}
|
||||
|
||||
@GetMapping(value = "yamlbeans")
|
||||
public void bad3(HttpServletRequest request) throws Exception {
|
||||
String data = request.getParameter("data");
|
||||
YamlReader r = new YamlReader(data);
|
||||
r.read(); //bad
|
||||
r.read(Object.class); //bad
|
||||
r.read(Object.class, Object.class); //bad
|
||||
}
|
||||
|
||||
@GetMapping(value = "hessian")
|
||||
public void bad4(HttpServletRequest request) throws Exception {
|
||||
byte[] bytes = request.getParameter("data").getBytes();
|
||||
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
|
||||
HessianInput hessianInput = new HessianInput(bis);
|
||||
hessianInput.readObject(); //bad
|
||||
hessianInput.readObject(Object.class); //bad
|
||||
}
|
||||
|
||||
@GetMapping(value = "hessian2")
|
||||
public void bad5(HttpServletRequest request) throws Exception {
|
||||
byte[] bytes = request.getParameter("data").getBytes();
|
||||
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
|
||||
Hessian2Input hessianInput = new Hessian2Input(bis);
|
||||
hessianInput.readObject(); //bad
|
||||
hessianInput.readObject(Object.class); //bad
|
||||
}
|
||||
|
||||
@GetMapping(value = "castor")
|
||||
public void bad6(HttpServletRequest request) throws Exception {
|
||||
Unmarshaller unmarshaller = new Unmarshaller();
|
||||
unmarshaller.unmarshal(new StringReader(request.getParameter("data"))); //bad
|
||||
}
|
||||
|
||||
@GetMapping(value = "burlap")
|
||||
public void bad7(HttpServletRequest request) throws Exception {
|
||||
byte[] serializedData = request.getParameter("data").getBytes();
|
||||
ByteArrayInputStream is = new ByteArrayInputStream(serializedData);
|
||||
BurlapInput burlapInput = new BurlapInput(is);
|
||||
burlapInput.readObject(); //bad
|
||||
|
||||
BurlapInput burlapInput1 = new BurlapInput();
|
||||
burlapInput1.init(is);
|
||||
burlapInput1.readObject(); //bad
|
||||
}
|
||||
|
||||
@GetMapping(value = "jsonio1")
|
||||
public void good1(HttpServletRequest request) {
|
||||
String data = request.getParameter("data");
|
||||
|
||||
HashMap hashMap = new HashMap();
|
||||
hashMap.put("USE_MAPS", true);
|
||||
|
||||
JsonReader.jsonToJava(data, hashMap); //good
|
||||
}
|
||||
|
||||
@GetMapping(value = "jsonio2")
|
||||
public void good2(HttpServletRequest request) {
|
||||
String data = request.getParameter("data");
|
||||
|
||||
HashMap hashMap = new HashMap();
|
||||
hashMap.put("USE_MAPS", true);
|
||||
|
||||
JsonReader jr1 = new JsonReader(data, hashMap); //good
|
||||
jr1.readObject();
|
||||
}
|
||||
}
|
||||
@@ -48,6 +48,38 @@ edges
|
||||
| B.java:27:31:27:51 | getInputStream(...) : InputStream | B.java:29:5:29:15 | inputStream : InputStream |
|
||||
| B.java:29:5:29:15 | inputStream : InputStream | B.java:29:22:29:26 | bytes [post update] : byte[] |
|
||||
| B.java:29:22:29:26 | bytes [post update] : byte[] | B.java:31:23:31:23 | s |
|
||||
| C.java:23:17:23:44 | getParameter(...) : String | C.java:24:13:24:16 | data |
|
||||
| C.java:23:17:23:44 | getParameter(...) : String | C.java:25:19:25:22 | data |
|
||||
| C.java:23:17:23:44 | getParameter(...) : String | C.java:26:25:26:28 | data |
|
||||
| C.java:23:17:23:44 | getParameter(...) : String | C.java:27:17:27:20 | data |
|
||||
| C.java:23:17:23:44 | getParameter(...) : String | C.java:30:19:30:22 | data |
|
||||
| C.java:23:17:23:44 | getParameter(...) : String | C.java:31:25:31:28 | data |
|
||||
| C.java:23:17:23:44 | getParameter(...) : String | C.java:32:31:32:34 | data |
|
||||
| C.java:23:17:23:44 | getParameter(...) : String | C.java:33:23:33:26 | data |
|
||||
| C.java:38:17:38:44 | getParameter(...) : String | C.java:43:25:43:28 | data |
|
||||
| C.java:38:17:38:44 | getParameter(...) : String | C.java:46:3:46:4 | jr |
|
||||
| C.java:51:17:51:44 | getParameter(...) : String | C.java:53:3:53:3 | r |
|
||||
| C.java:51:17:51:44 | getParameter(...) : String | C.java:54:3:54:3 | r |
|
||||
| C.java:51:17:51:44 | getParameter(...) : String | C.java:55:3:55:3 | r |
|
||||
| C.java:60:18:60:45 | getParameter(...) : String | C.java:61:55:61:59 | bytes : byte[] |
|
||||
| C.java:60:18:60:45 | getParameter(...) : String | C.java:63:3:63:14 | hessianInput |
|
||||
| C.java:60:18:60:45 | getParameter(...) : String | C.java:64:3:64:14 | hessianInput |
|
||||
| C.java:61:30:61:60 | new ByteArrayInputStream(...) : ByteArrayInputStream | C.java:63:3:63:14 | hessianInput |
|
||||
| C.java:61:30:61:60 | new ByteArrayInputStream(...) : ByteArrayInputStream | C.java:64:3:64:14 | hessianInput |
|
||||
| C.java:61:55:61:59 | bytes : byte[] | C.java:61:30:61:60 | new ByteArrayInputStream(...) : ByteArrayInputStream |
|
||||
| C.java:69:18:69:45 | getParameter(...) : String | C.java:70:55:70:59 | bytes : byte[] |
|
||||
| C.java:69:18:69:45 | getParameter(...) : String | C.java:72:3:72:14 | hessianInput |
|
||||
| C.java:69:18:69:45 | getParameter(...) : String | C.java:73:3:73:14 | hessianInput |
|
||||
| C.java:70:30:70:60 | new ByteArrayInputStream(...) : ByteArrayInputStream | C.java:72:3:72:14 | hessianInput |
|
||||
| C.java:70:30:70:60 | new ByteArrayInputStream(...) : ByteArrayInputStream | C.java:73:3:73:14 | hessianInput |
|
||||
| C.java:70:55:70:59 | bytes : byte[] | C.java:70:30:70:60 | new ByteArrayInputStream(...) : ByteArrayInputStream |
|
||||
| C.java:79:43:79:70 | getParameter(...) : String | C.java:79:26:79:71 | new StringReader(...) |
|
||||
| C.java:84:27:84:54 | getParameter(...) : String | C.java:85:54:85:67 | serializedData : byte[] |
|
||||
| C.java:84:27:84:54 | getParameter(...) : String | C.java:87:3:87:13 | burlapInput |
|
||||
| C.java:84:27:84:54 | getParameter(...) : String | C.java:91:3:91:14 | burlapInput1 |
|
||||
| C.java:85:29:85:68 | new ByteArrayInputStream(...) : ByteArrayInputStream | C.java:87:3:87:13 | burlapInput |
|
||||
| C.java:85:29:85:68 | new ByteArrayInputStream(...) : ByteArrayInputStream | C.java:91:3:91:14 | burlapInput1 |
|
||||
| C.java:85:54:85:67 | serializedData : byte[] | C.java:85:29:85:68 | new ByteArrayInputStream(...) : ByteArrayInputStream |
|
||||
| TestMessageBodyReader.java:20:55:20:78 | entityStream : InputStream | TestMessageBodyReader.java:22:18:22:52 | new ObjectInputStream(...) |
|
||||
| TestMessageBodyReader.java:20:55:20:78 | entityStream : InputStream | TestMessageBodyReader.java:22:40:22:51 | entityStream : InputStream |
|
||||
| TestMessageBodyReader.java:22:40:22:51 | entityStream : InputStream | TestMessageBodyReader.java:22:18:22:52 | new ObjectInputStream(...) |
|
||||
@@ -111,6 +143,39 @@ nodes
|
||||
| B.java:29:5:29:15 | inputStream : InputStream | semmle.label | inputStream : InputStream |
|
||||
| B.java:29:22:29:26 | bytes [post update] : byte[] | semmle.label | bytes [post update] : byte[] |
|
||||
| B.java:31:23:31:23 | s | semmle.label | s |
|
||||
| C.java:23:17:23:44 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| C.java:24:13:24:16 | data | semmle.label | data |
|
||||
| C.java:25:19:25:22 | data | semmle.label | data |
|
||||
| C.java:26:25:26:28 | data | semmle.label | data |
|
||||
| C.java:27:17:27:20 | data | semmle.label | data |
|
||||
| C.java:30:19:30:22 | data | semmle.label | data |
|
||||
| C.java:31:25:31:28 | data | semmle.label | data |
|
||||
| C.java:32:31:32:34 | data | semmle.label | data |
|
||||
| C.java:33:23:33:26 | data | semmle.label | data |
|
||||
| C.java:38:17:38:44 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| C.java:43:25:43:28 | data | semmle.label | data |
|
||||
| C.java:46:3:46:4 | jr | semmle.label | jr |
|
||||
| C.java:51:17:51:44 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| C.java:53:3:53:3 | r | semmle.label | r |
|
||||
| C.java:54:3:54:3 | r | semmle.label | r |
|
||||
| C.java:55:3:55:3 | r | semmle.label | r |
|
||||
| C.java:60:18:60:45 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| C.java:61:30:61:60 | new ByteArrayInputStream(...) : ByteArrayInputStream | semmle.label | new ByteArrayInputStream(...) : ByteArrayInputStream |
|
||||
| C.java:61:55:61:59 | bytes : byte[] | semmle.label | bytes : byte[] |
|
||||
| C.java:63:3:63:14 | hessianInput | semmle.label | hessianInput |
|
||||
| C.java:64:3:64:14 | hessianInput | semmle.label | hessianInput |
|
||||
| C.java:69:18:69:45 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| C.java:70:30:70:60 | new ByteArrayInputStream(...) : ByteArrayInputStream | semmle.label | new ByteArrayInputStream(...) : ByteArrayInputStream |
|
||||
| C.java:70:55:70:59 | bytes : byte[] | semmle.label | bytes : byte[] |
|
||||
| C.java:72:3:72:14 | hessianInput | semmle.label | hessianInput |
|
||||
| C.java:73:3:73:14 | hessianInput | semmle.label | hessianInput |
|
||||
| C.java:79:26:79:71 | new StringReader(...) | semmle.label | new StringReader(...) |
|
||||
| C.java:79:43:79:70 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| C.java:84:27:84:54 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| C.java:85:29:85:68 | new ByteArrayInputStream(...) : ByteArrayInputStream | semmle.label | new ByteArrayInputStream(...) : ByteArrayInputStream |
|
||||
| C.java:85:54:85:67 | serializedData : byte[] | semmle.label | serializedData : byte[] |
|
||||
| C.java:87:3:87:13 | burlapInput | semmle.label | burlapInput |
|
||||
| C.java:91:3:91:14 | burlapInput1 | semmle.label | burlapInput1 |
|
||||
| TestMessageBodyReader.java:20:55:20:78 | entityStream : InputStream | semmle.label | entityStream : InputStream |
|
||||
| TestMessageBodyReader.java:22:18:22:52 | new ObjectInputStream(...) | semmle.label | new ObjectInputStream(...) |
|
||||
| TestMessageBodyReader.java:22:40:22:51 | entityStream : InputStream | semmle.label | entityStream : InputStream |
|
||||
@@ -141,4 +206,24 @@ nodes
|
||||
| B.java:15:12:15:28 | parse(...) | B.java:12:31:12:51 | getInputStream(...) : InputStream | B.java:15:23:15:27 | bytes | Unsafe deserialization of $@. | B.java:12:31:12:51 | getInputStream(...) | user input |
|
||||
| B.java:23:12:23:30 | parseObject(...) | B.java:19:31:19:51 | getInputStream(...) : InputStream | B.java:23:29:23:29 | s | Unsafe deserialization of $@. | B.java:19:31:19:51 | getInputStream(...) | user input |
|
||||
| B.java:31:12:31:24 | parse(...) | B.java:27:31:27:51 | getInputStream(...) : InputStream | B.java:31:23:31:23 | s | Unsafe deserialization of $@. | B.java:27:31:27:51 | getInputStream(...) | user input |
|
||||
| C.java:24:3:24:17 | load(...) | C.java:23:17:23:44 | getParameter(...) : String | C.java:24:13:24:16 | data | Unsafe deserialization of $@. | C.java:23:17:23:44 | getParameter(...) | user input |
|
||||
| C.java:25:3:25:23 | loadStream(...) | C.java:23:17:23:44 | getParameter(...) : String | C.java:25:19:25:22 | data | Unsafe deserialization of $@. | C.java:23:17:23:44 | getParameter(...) | user input |
|
||||
| C.java:26:3:26:43 | loadStreamOfType(...) | C.java:23:17:23:44 | getParameter(...) : String | C.java:26:25:26:28 | data | Unsafe deserialization of $@. | C.java:23:17:23:44 | getParameter(...) | user input |
|
||||
| C.java:27:3:27:35 | loadType(...) | C.java:23:17:23:44 | getParameter(...) : String | C.java:27:17:27:20 | data | Unsafe deserialization of $@. | C.java:23:17:23:44 | getParameter(...) | user input |
|
||||
| C.java:30:3:30:23 | load(...) | C.java:23:17:23:44 | getParameter(...) : String | C.java:30:19:30:22 | data | Unsafe deserialization of $@. | C.java:23:17:23:44 | getParameter(...) | user input |
|
||||
| C.java:31:3:31:29 | loadStream(...) | C.java:23:17:23:44 | getParameter(...) : String | C.java:31:25:31:28 | data | Unsafe deserialization of $@. | C.java:23:17:23:44 | getParameter(...) | user input |
|
||||
| C.java:32:3:32:49 | loadStreamOfType(...) | C.java:23:17:23:44 | getParameter(...) : String | C.java:32:31:32:34 | data | Unsafe deserialization of $@. | C.java:23:17:23:44 | getParameter(...) | user input |
|
||||
| C.java:33:3:33:41 | loadType(...) | C.java:23:17:23:44 | getParameter(...) : String | C.java:33:23:33:26 | data | Unsafe deserialization of $@. | C.java:23:17:23:44 | getParameter(...) | user input |
|
||||
| C.java:43:3:43:29 | jsonToJava(...) | C.java:38:17:38:44 | getParameter(...) : String | C.java:43:25:43:28 | data | Unsafe deserialization of $@. | C.java:38:17:38:44 | getParameter(...) | user input |
|
||||
| C.java:46:3:46:17 | readObject(...) | C.java:38:17:38:44 | getParameter(...) : String | C.java:46:3:46:4 | jr | Unsafe deserialization of $@. | C.java:38:17:38:44 | getParameter(...) | user input |
|
||||
| C.java:53:3:53:10 | read(...) | C.java:51:17:51:44 | getParameter(...) : String | C.java:53:3:53:3 | r | Unsafe deserialization of $@. | C.java:51:17:51:44 | getParameter(...) | user input |
|
||||
| C.java:54:3:54:22 | read(...) | C.java:51:17:51:44 | getParameter(...) : String | C.java:54:3:54:3 | r | Unsafe deserialization of $@. | C.java:51:17:51:44 | getParameter(...) | user input |
|
||||
| C.java:55:3:55:36 | read(...) | C.java:51:17:51:44 | getParameter(...) : String | C.java:55:3:55:3 | r | Unsafe deserialization of $@. | C.java:51:17:51:44 | getParameter(...) | user input |
|
||||
| C.java:63:3:63:27 | readObject(...) | C.java:60:18:60:45 | getParameter(...) : String | C.java:63:3:63:14 | hessianInput | Unsafe deserialization of $@. | C.java:60:18:60:45 | getParameter(...) | user input |
|
||||
| C.java:64:3:64:39 | readObject(...) | C.java:60:18:60:45 | getParameter(...) : String | C.java:64:3:64:14 | hessianInput | Unsafe deserialization of $@. | C.java:60:18:60:45 | getParameter(...) | user input |
|
||||
| C.java:72:3:72:27 | readObject(...) | C.java:69:18:69:45 | getParameter(...) : String | C.java:72:3:72:14 | hessianInput | Unsafe deserialization of $@. | C.java:69:18:69:45 | getParameter(...) | user input |
|
||||
| C.java:73:3:73:39 | readObject(...) | C.java:69:18:69:45 | getParameter(...) : String | C.java:73:3:73:14 | hessianInput | Unsafe deserialization of $@. | C.java:69:18:69:45 | getParameter(...) | user input |
|
||||
| C.java:79:3:79:72 | unmarshal(...) | C.java:79:43:79:70 | getParameter(...) : String | C.java:79:26:79:71 | new StringReader(...) | Unsafe deserialization of $@. | C.java:79:43:79:70 | getParameter(...) | user input |
|
||||
| C.java:87:3:87:26 | readObject(...) | C.java:84:27:84:54 | getParameter(...) : String | C.java:87:3:87:13 | burlapInput | Unsafe deserialization of $@. | C.java:84:27:84:54 | getParameter(...) | user input |
|
||||
| C.java:91:3:91:27 | readObject(...) | C.java:84:27:84:54 | getParameter(...) : String | C.java:91:3:91:14 | burlapInput1 | Unsafe deserialization of $@. | C.java:84:27:84:54 | getParameter(...) | user input |
|
||||
| TestMessageBodyReader.java:22:18:22:65 | readObject(...) | TestMessageBodyReader.java:20:55:20:78 | entityStream : InputStream | TestMessageBodyReader.java:22:18:22:52 | new ObjectInputStream(...) | Unsafe deserialization of $@. | TestMessageBodyReader.java:20:55:20:78 | entityStream | user input |
|
||||
|
||||
@@ -1 +1 @@
|
||||
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/snakeyaml-1.21:${testdir}/../../../stubs/xstream-1.4.10:${testdir}/../../../stubs/kryo-4.0.2:${testdir}/../../../stubs/jsr311-api-1.1.1:${testdir}/../../../stubs/fastjson-1.2.74
|
||||
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/snakeyaml-1.21:${testdir}/../../../stubs/xstream-1.4.10:${testdir}/../../../stubs/kryo-4.0.2:${testdir}/../../../stubs/jsr311-api-1.1.1:${testdir}/../../../stubs/fastjson-1.2.74:${testdir}/../../../stubs/springframework-5.3.8:${testdir}/../../../stubs/servlet-api-2.4:${testdir}/../../../stubs/jyaml-1.3:${testdir}/../../../stubs/json-io-4.10.0:${testdir}/../../../stubs/yamlbeans-1.09:${testdir}/../../../stubs/hessian-4.0.38:${testdir}/../../../stubs/castor-1.4.1
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.client.methods.HttpPut;
|
||||
import org.apache.http.client.methods.HttpDelete;
|
||||
import org.apache.http.client.methods.HttpHead;
|
||||
import org.apache.http.client.methods.HttpOptions;
|
||||
import org.apache.http.client.methods.HttpTrace;
|
||||
import org.apache.http.client.methods.HttpPatch;
|
||||
import org.apache.http.client.methods.RequestBuilder;
|
||||
import org.apache.http.message.BasicHttpRequest;
|
||||
import org.apache.http.message.BasicHttpEntityEnclosingRequest;
|
||||
import org.apache.http.message.BasicRequestLine;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
public class ApacheHttpSSRF extends HttpServlet {
|
||||
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
try {
|
||||
|
||||
String sink = request.getParameter("uri");
|
||||
URI uri = new URI(sink);
|
||||
|
||||
HttpGet httpGet = new HttpGet(uri); // $ SSRF
|
||||
HttpGet httpGet2 = new HttpGet();
|
||||
httpGet2.setURI(uri); // $ SSRF
|
||||
|
||||
new HttpHead(uri); // $ SSRF
|
||||
new HttpPost(uri); // $ SSRF
|
||||
new HttpPut(uri); // $ SSRF
|
||||
new HttpDelete(uri); // $ SSRF
|
||||
new HttpOptions(uri); // $ SSRF
|
||||
new HttpTrace(uri); // $ SSRF
|
||||
new HttpPatch(uri); // $ SSRF
|
||||
|
||||
new BasicHttpRequest(new BasicRequestLine("GET", uri.toString(), null)); // $ SSRF
|
||||
new BasicHttpRequest("GET", uri.toString()); // $ SSRF
|
||||
new BasicHttpRequest("GET", uri.toString(), null); // $ SSRF
|
||||
|
||||
new BasicHttpEntityEnclosingRequest(new BasicRequestLine("GET", uri.toString(), null)); // $ SSRF
|
||||
new BasicHttpEntityEnclosingRequest("GET", uri.toString()); // $ SSRF
|
||||
new BasicHttpEntityEnclosingRequest("GET", uri.toString(), null); // $ SSRF
|
||||
|
||||
RequestBuilder.get(uri); // $ SSRF
|
||||
RequestBuilder.post(uri); // $ SSRF
|
||||
RequestBuilder.put(uri); // $ SSRF
|
||||
RequestBuilder.delete(uri); // $ SSRF
|
||||
RequestBuilder.options(uri); // $ SSRF
|
||||
RequestBuilder.head(uri); // $ SSRF
|
||||
RequestBuilder.trace(uri); // $ SSRF
|
||||
RequestBuilder.patch(uri); // $ SSRF
|
||||
RequestBuilder.get("").setUri(uri); // $ SSRF
|
||||
|
||||
} catch (Exception e) {
|
||||
// TODO: handle exception
|
||||
}
|
||||
}
|
||||
}
|
||||
18
java/ql/test/query-tests/security/CWE-918/JakartaWsSSRF.java
Normal file
18
java/ql/test/query-tests/security/CWE-918/JakartaWsSSRF.java
Normal file
@@ -0,0 +1,18 @@
|
||||
import jakarta.ws.rs.client.*;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
public class JakartaWsSSRF extends HttpServlet {
|
||||
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
Client client = ClientBuilder.newClient();
|
||||
String url = request.getParameter("url");
|
||||
client.target(url); // $ SSRF
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
import java.io.IOException;
|
||||
import java.net.Proxy;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.net.Proxy.Type;
|
||||
import java.io.InputStream;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
public class JavaNetHttpSSRF extends HttpServlet {
|
||||
private static final String VALID_URI = "http://lgtm.com";
|
||||
private HttpClient client = HttpClient.newHttpClient();
|
||||
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
try {
|
||||
|
||||
String sink = request.getParameter("uri");
|
||||
URI uri = new URI(sink);
|
||||
URI uri2 = new URI("http", sink, "fragement");
|
||||
URL url1 = new URL(sink);
|
||||
|
||||
URLConnection c1 = url1.openConnection(); // $ SSRF
|
||||
SocketAddress sa = new SocketAddress() {
|
||||
};
|
||||
URLConnection c2 = url1.openConnection(new Proxy(Type.HTTP, sa)); // $ SSRF
|
||||
InputStream c3 = url1.openStream(); // $ SSRF
|
||||
|
||||
// java.net.http
|
||||
HttpClient client = HttpClient.newHttpClient();
|
||||
HttpRequest request2 = HttpRequest.newBuilder().uri(uri2).build(); // $ SSRF
|
||||
HttpRequest request3 = HttpRequest.newBuilder(uri).build(); // $ SSRF
|
||||
|
||||
} catch (Exception e) {
|
||||
// TODO: handle exception
|
||||
}
|
||||
}
|
||||
}
|
||||
18
java/ql/test/query-tests/security/CWE-918/JaxWsSSRF.java
Normal file
18
java/ql/test/query-tests/security/CWE-918/JaxWsSSRF.java
Normal file
@@ -0,0 +1,18 @@
|
||||
import javax.ws.rs.client.*;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
public class JaxWsSSRF extends HttpServlet {
|
||||
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
Client client = ClientBuilder.newClient();
|
||||
String url = request.getParameter("url");
|
||||
client.target(url); // $ SSRF
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
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 ReactiveWebClientSSRF extends HttpServlet {
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
try {
|
||||
String url = request.getParameter("uri");
|
||||
WebClient webClient = WebClient.create(url); // $ SSRF
|
||||
|
||||
Mono<String> result = webClient.get()
|
||||
.uri("/")
|
||||
.retrieve()
|
||||
.bodyToMono(String.class);
|
||||
|
||||
result.block();
|
||||
} catch (Exception e) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
|
||||
protected void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
try {
|
||||
String url = request.getParameter("uri");
|
||||
WebClient webClient = WebClient.builder()
|
||||
.defaultHeader("User-Agent", "Java")
|
||||
.baseUrl(url) // $ SSRF
|
||||
.build();
|
||||
|
||||
|
||||
Mono<String> result = webClient.get()
|
||||
.uri("/")
|
||||
.retrieve()
|
||||
.bodyToMono(String.class);
|
||||
|
||||
result.block();
|
||||
} catch (Exception e) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
18
java/ql/test/query-tests/security/CWE-918/RequestForgery.ql
Normal file
18
java/ql/test/query-tests/security/CWE-918/RequestForgery.ql
Normal file
@@ -0,0 +1,18 @@
|
||||
import java
|
||||
import semmle.code.java.security.RequestForgeryConfig
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
|
||||
class HasFlowTest extends InlineExpectationsTest {
|
||||
HasFlowTest() { this = "HasFlowTest" }
|
||||
|
||||
override string getARelevantTag() { result = "SSRF" }
|
||||
|
||||
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "SSRF" and
|
||||
exists(RequestForgeryConfiguration conf, DataFlow::Node sink | conf.hasFlowTo(sink) |
|
||||
sink.getLocation() = location and
|
||||
element = sink.toString() and
|
||||
value = ""
|
||||
)
|
||||
}
|
||||
}
|
||||
123
java/ql/test/query-tests/security/CWE-918/SanitizationTests.java
Normal file
123
java/ql/test/query-tests/security/CWE-918/SanitizationTests.java
Normal file
@@ -0,0 +1,123 @@
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
public class SanitizationTests extends HttpServlet {
|
||||
private static final String VALID_URI = "http://lgtm.com";
|
||||
private HttpClient client = HttpClient.newHttpClient();
|
||||
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
try {
|
||||
|
||||
URI uri = new URI(request.getParameter("uri"));
|
||||
// BAD: a request parameter is incorporated without validation into a Http
|
||||
// request
|
||||
HttpRequest r = HttpRequest.newBuilder(uri).build(); // $ SSRF
|
||||
client.send(r, null);
|
||||
|
||||
// GOOD: sanitisation by concatenation with a prefix that prevents targeting an arbitrary host.
|
||||
// We test a few different ways of sanitisation: via string conctentation (perhaps nested),
|
||||
// via a stringbuilder (for which we consider appends done in the constructor, chained onto
|
||||
// the constructor and applied in subsequent statements) and via String.format.
|
||||
String safeUri3 = "https://example.com/" + request.getParameter("uri3");
|
||||
HttpRequest r3 = HttpRequest.newBuilder(new URI(safeUri3)).build();
|
||||
client.send(r3, null);
|
||||
|
||||
String safeUri4 = "https://example.com/" + ("someprefix" + request.getParameter("uri4"));
|
||||
HttpRequest r4 = HttpRequest.newBuilder(new URI(safeUri4)).build();
|
||||
client.send(r4, null);
|
||||
|
||||
StringBuilder safeUri5 = new StringBuilder();
|
||||
safeUri5.append("https://example.com/").append(request.getParameter("uri5"));
|
||||
HttpRequest r5 = HttpRequest.newBuilder(new URI(safeUri5.toString())).build();
|
||||
client.send(r5, null);
|
||||
|
||||
StringBuilder safeUri5a = new StringBuilder("https://example.com/");
|
||||
safeUri5a.append(request.getParameter("uri5a"));
|
||||
HttpRequest r5a = HttpRequest.newBuilder(new URI(safeUri5a.toString())).build();
|
||||
client.send(r5a, null);
|
||||
|
||||
StringBuilder safeUri5b = (new StringBuilder("https://example.com/")).append("dir/");
|
||||
safeUri5b.append(request.getParameter("uri5b"));
|
||||
HttpRequest r5b = HttpRequest.newBuilder(new URI(safeUri5b.toString())).build();
|
||||
client.send(r5b, null);
|
||||
|
||||
StringBuilder safeUri5c = (new StringBuilder("prefix")).append("https://example.com/dir/");
|
||||
safeUri5c.append(request.getParameter("uri5c"));
|
||||
HttpRequest r5c = HttpRequest.newBuilder(new URI(safeUri5c.toString())).build();
|
||||
client.send(r5c, null);
|
||||
|
||||
String safeUri6 = String.format("https://example.com/%s", request.getParameter("uri6"));
|
||||
HttpRequest r6 = HttpRequest.newBuilder(new URI(safeUri6)).build();
|
||||
client.send(r6, null);
|
||||
|
||||
String safeUri7 = String.format("%s/%s", "https://example.com", request.getParameter("uri7"));
|
||||
HttpRequest r7 = HttpRequest.newBuilder(new URI(safeUri7)).build();
|
||||
client.send(r7, null);
|
||||
|
||||
String safeUri8 = String.format("%s%s", "https://example.com/", request.getParameter("uri8"));
|
||||
HttpRequest r8 = HttpRequest.newBuilder(new URI(safeUri8)).build();
|
||||
client.send(r8, null);
|
||||
|
||||
String safeUri9 = String.format("http://%s", "myserver.com") + "/" + request.getParameter("uri9");
|
||||
HttpRequest r9 = HttpRequest.newBuilder(new URI(safeUri9)).build();
|
||||
client.send(r9, null);
|
||||
|
||||
// BAD: cases where a string that would sanitise is used, but occurs in the wrong
|
||||
// place to sanitise user input:
|
||||
String unsafeUri3 = request.getParameter("baduri3") + "https://example.com/";
|
||||
HttpRequest unsafer3 = HttpRequest.newBuilder(new URI(unsafeUri3)).build(); // $ SSRF
|
||||
client.send(unsafer3, null);
|
||||
|
||||
String unsafeUri4 = ("someprefix" + request.getParameter("baduri4")) + "https://example.com/";
|
||||
HttpRequest unsafer4 = HttpRequest.newBuilder(new URI(unsafeUri4)).build(); // $ SSRF
|
||||
client.send(unsafer4, null);
|
||||
|
||||
StringBuilder unsafeUri5 = new StringBuilder();
|
||||
unsafeUri5.append(request.getParameter("baduri5")).append("https://example.com/");
|
||||
HttpRequest unsafer5 = HttpRequest.newBuilder(new URI(unsafeUri5.toString())).build(); // $ SSRF
|
||||
client.send(unsafer5, null);
|
||||
|
||||
StringBuilder unafeUri5a = new StringBuilder(request.getParameter("uri5a"));
|
||||
unafeUri5a.append("https://example.com/");
|
||||
HttpRequest unsafer5a = HttpRequest.newBuilder(new URI(unafeUri5a.toString())).build(); // $ SSRF
|
||||
client.send(unsafer5a, null);
|
||||
|
||||
StringBuilder unsafeUri5b = (new StringBuilder(request.getParameter("uri5b"))).append("dir/");
|
||||
unsafeUri5b.append("https://example.com/");
|
||||
HttpRequest unsafer5b = HttpRequest.newBuilder(new URI(unsafeUri5b.toString())).build(); // $ SSRF
|
||||
client.send(unsafer5b, null);
|
||||
|
||||
StringBuilder unsafeUri5c = (new StringBuilder("https")).append(request.getParameter("uri5c"));
|
||||
unsafeUri5c.append("://example.com/dir/");
|
||||
HttpRequest unsafer5c = HttpRequest.newBuilder(new URI(unsafeUri5c.toString())).build(); // $ SSRF
|
||||
client.send(unsafer5c, null);
|
||||
|
||||
String unsafeUri6 = String.format("%shttps://example.com/", request.getParameter("baduri6"));
|
||||
HttpRequest unsafer6 = HttpRequest.newBuilder(new URI(unsafeUri6)).build(); // $ SSRF
|
||||
client.send(unsafer6, null);
|
||||
|
||||
String unsafeUri7 = String.format("%s/%s", request.getParameter("baduri7"), "https://example.com");
|
||||
HttpRequest unsafer7 = HttpRequest.newBuilder(new URI(unsafeUri7)).build(); // $ SSRF
|
||||
client.send(unsafer7, null);
|
||||
|
||||
String unsafeUri8 = String.format("%s%s", request.getParameter("baduri8"), "https://example.com/");
|
||||
HttpRequest unsafer8 = HttpRequest.newBuilder(new URI(unsafeUri8)).build(); // $ SSRF
|
||||
client.send(unsafer8, null);
|
||||
|
||||
String unsafeUri9 = request.getParameter("baduri9") + "/" + String.format("http://%s", "myserver.com");
|
||||
HttpRequest unsafer9 = HttpRequest.newBuilder(new URI(unsafeUri9)).build(); // $ SSRF
|
||||
client.send(unsafer9, null);
|
||||
|
||||
} catch (Exception e) {
|
||||
// TODO: handle exception
|
||||
}
|
||||
}
|
||||
}
|
||||
70
java/ql/test/query-tests/security/CWE-918/SpringSSRF.java
Normal file
70
java/ql/test/query-tests/security/CWE-918/SpringSSRF.java
Normal file
@@ -0,0 +1,70 @@
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.http.RequestEntity;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import java.net.URI;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.*;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.net.Proxy.Type;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
public class SpringSSRF extends HttpServlet {
|
||||
|
||||
protected void doGet(HttpServletRequest request2, HttpServletResponse response2)
|
||||
throws ServletException, IOException {
|
||||
String fooResourceUrl = request2.getParameter("uri");;
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
HttpEntity<String> request = new HttpEntity<>(new String("bar"));
|
||||
try {
|
||||
restTemplate.getForEntity(fooResourceUrl + "/1", String.class); // $ SSRF
|
||||
restTemplate.exchange(fooResourceUrl, HttpMethod.POST, request, String.class); // $ SSRF
|
||||
restTemplate.execute(fooResourceUrl, HttpMethod.POST, null, null, "test"); // $ SSRF
|
||||
restTemplate.getForObject(fooResourceUrl, String.class, "test"); // $ SSRF
|
||||
restTemplate.patchForObject(fooResourceUrl, new String("object"), String.class, "hi"); // $ SSRF
|
||||
restTemplate.postForEntity(new URI(fooResourceUrl), new String("object"), String.class); // $ SSRF
|
||||
restTemplate.postForLocation(fooResourceUrl, new String("object")); // $ SSRF
|
||||
restTemplate.postForObject(fooResourceUrl, new String("object"), String.class); // $ SSRF
|
||||
restTemplate.put(fooResourceUrl, new String("object")); // $ SSRF
|
||||
restTemplate.delete(fooResourceUrl); // $ SSRF
|
||||
restTemplate.headForHeaders(fooResourceUrl); // $ SSRF
|
||||
restTemplate.optionsForAllow(fooResourceUrl); // $ SSRF
|
||||
{
|
||||
String body = new String("body");
|
||||
URI uri = new URI(fooResourceUrl);
|
||||
RequestEntity<String> requestEntity =
|
||||
RequestEntity.post(uri).body(body); // $ SSRF
|
||||
ResponseEntity<String> response = restTemplate.exchange(requestEntity, String.class);
|
||||
RequestEntity.get(uri); // $ SSRF
|
||||
RequestEntity.put(uri); // $ SSRF
|
||||
RequestEntity.delete(uri); // $ SSRF
|
||||
RequestEntity.options(uri); // $ SSRF
|
||||
RequestEntity.patch(uri); // $ SSRF
|
||||
RequestEntity.head(uri); // $ SSRF
|
||||
RequestEntity.method(null, uri); // $ SSRF
|
||||
}
|
||||
{
|
||||
URI uri = new URI(fooResourceUrl);
|
||||
MultiValueMap<String, String> headers = null;
|
||||
java.lang.reflect.Type type = null;
|
||||
new RequestEntity<String>(null, uri); // $ SSRF
|
||||
new RequestEntity<String>(headers, null, uri); // $ SSRF
|
||||
new RequestEntity<String>("body", null, uri); // $ SSRF
|
||||
new RequestEntity<String>("body", headers, null, uri); // $ SSRF
|
||||
new RequestEntity<String>("body", null, uri, type); // $ SSRF
|
||||
new RequestEntity<String>("body", headers, null, uri, type); // $ SSRF
|
||||
}
|
||||
} catch (org.springframework.web.client.RestClientException | java.net.URISyntaxException e) {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.net.URLStreamHandlerFactory;
|
||||
|
||||
public class URLClassLoaderSSRF extends HttpServlet {
|
||||
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
try {
|
||||
String url = request.getParameter("uri");
|
||||
URI uri = new URI(url);
|
||||
URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{uri.toURL()}); // $ SSRF
|
||||
Class<?> test = urlClassLoader.loadClass("test");
|
||||
} catch (Exception e) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
|
||||
protected void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
try {
|
||||
String url = request.getParameter("uri");
|
||||
URI uri = new URI(url);
|
||||
URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{uri.toURL()}, URLClassLoaderSSRF.class.getClassLoader()); // $ SSRF
|
||||
Class<?> test = urlClassLoader.loadClass("test");
|
||||
} catch (Exception e) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
|
||||
protected void doPut(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
try {
|
||||
String url = request.getParameter("uri");
|
||||
URI uri = new URI(url);
|
||||
|
||||
URLStreamHandlerFactory urlStreamHandlerFactory = null;
|
||||
URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{uri.toURL()}, URLClassLoaderSSRF.class.getClassLoader(), urlStreamHandlerFactory); // $ SSRF
|
||||
urlClassLoader.findResource("test");
|
||||
} catch (Exception e) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
|
||||
protected void doDelete(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
try {
|
||||
String url = request.getParameter("uri");
|
||||
URI uri = new URI(url);
|
||||
URLClassLoader urlClassLoader = URLClassLoader.newInstance(new URL[]{uri.toURL()}); // $ SSRF
|
||||
urlClassLoader.getResourceAsStream("test");
|
||||
} catch (Exception e) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
|
||||
protected void doOptions(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
try {
|
||||
String url = request.getParameter("uri");
|
||||
URI uri = new URI(url);
|
||||
URLClassLoader urlClassLoader =
|
||||
new URLClassLoader("testClassLoader",
|
||||
new URL[]{uri.toURL()}, // $ SSRF
|
||||
URLClassLoaderSSRF.class.getClassLoader()
|
||||
);
|
||||
|
||||
Class<?> rceTest = urlClassLoader.loadClass("RCETest");
|
||||
} catch (Exception e) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
|
||||
protected void doTrace(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
try {
|
||||
String url = request.getParameter("uri");
|
||||
URI uri = new URI(url);
|
||||
URLStreamHandlerFactory urlStreamHandlerFactory = null;
|
||||
|
||||
URLClassLoader urlClassLoader =
|
||||
new URLClassLoader("testClassLoader",
|
||||
new URL[]{uri.toURL()}, // $ SSRF
|
||||
URLClassLoaderSSRF.class.getClassLoader(),
|
||||
urlStreamHandlerFactory
|
||||
);
|
||||
|
||||
Class<?> rceTest = urlClassLoader.loadClass("RCETest");
|
||||
} catch (Exception e) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
2
java/ql/test/query-tests/security/CWE-918/options
Normal file
2
java/ql/test/query-tests/security/CWE-918/options
Normal file
@@ -0,0 +1,2 @@
|
||||
//semmle-extractor-options: --javac-args -source 11 -target 11 -cp ${testdir}/../../../stubs/springframework-5.3.8:${testdir}/../../../stubs/javax-ws-rs-api-2.1.1:${testdir}/../../../stubs/javax-ws-rs-api-3.0.0:${testdir}/../../../stubs/apache-http-4.4.13/:${testdir}/../../../stubs/servlet-api-2.4/:${testdir}/../../../stubs/projectreactor-3.4.3/
|
||||
|
||||
Reference in New Issue
Block a user