Skip to content

Commit 68ed325

Browse files
authored
Merge pull request github#6478 from smowton/smowton/feature/jax-rs-request-filters
Java: Add sources for Jax-RS filters
2 parents c86311e + 95046b9 commit 68ed325

File tree

13 files changed

+1363
-346
lines changed

13 files changed

+1363
-346
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
lgtm,codescanning
2+
* Remote information sources relating to JAX-RS request filters are now recognised. This may lead to additional results from any query where a filter uses user-controlled data in a dangerous way.

java/ql/lib/semmle/code/java/frameworks/JaxWS.qll

Lines changed: 180 additions & 326 deletions
Large diffs are not rendered by default.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import jakarta.ws.rs.container.ContainerRequestContext;
2+
3+
public class JakartaContainerRequestContextSources {
4+
void sink(Object o) {}
5+
6+
void test(ContainerRequestContext context) throws Exception {
7+
sink(context.getAcceptableLanguages()); // $ hasValueFlow
8+
sink(context.getAcceptableMediaTypes().get(0).getType()); // $ hasTaintFlow
9+
sink(context.getCookies().get("someKey").getValue()); // $ hasTaintFlow
10+
byte[] buf = new byte[1024];
11+
context.getEntityStream().read(buf);
12+
sink(buf); // $ hasTaintFlow
13+
sink(context.getHeaders().getFirst("someKey")); // $ hasTaintFlow
14+
sink(context.getHeaderString("someKey")); // $ hasValueFlow
15+
sink(context.getLanguage()); // $ hasValueFlow
16+
sink(context.getMediaType().getType()); // $ hasTaintFlow
17+
sink(context.getUriInfo().getPath()); // $ hasTaintFlow
18+
}
19+
}

java/ql/test/library-tests/frameworks/JaxWs/JakartaRsFlow.java

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,11 @@ private static class SetStringSource {
5757
static PathSegment taint(PathSegment ps) { return ps; }
5858

5959
static UriInfo taint(UriInfo ui) { return ui; }
60-
60+
6161
static Map taint(Map m) { return m; }
62-
62+
6363
static Link taint(Link l) { return l; }
64-
64+
6565
static Class taint(Class c) { return c; }
6666

6767
private static class UriSource {
@@ -196,12 +196,21 @@ void testPathSegment(PathSegment ps1, PathSegment ps2) {
196196
sink(taint(ps2).getPath()); // $ hasTaintFlow
197197
}
198198

199-
void testUriInfo(UriInfo ui1, UriInfo ui2, UriInfo ui3, UriInfo ui4, UriInfo ui5) {
200-
sink(taint(ui1).getPathParameters()); // $ hasTaintFlow
201-
sink(taint(ui2).getPathSegments()); // $ hasTaintFlow
202-
sink(taint(ui2).getQueryParameters()); // $ hasTaintFlow
203-
sink(taint(ui2).getRequestUri()); // $ hasTaintFlow
204-
sink(taint(ui2).getRequestUriBuilder()); // $ hasTaintFlow
199+
void testUriInfo(UriInfo ui, UriInfo untaintedUriInfo) throws Exception {
200+
ui = taint(ui);
201+
sink(ui.getPathParameters()); // $ hasTaintFlow
202+
sink(ui.getPathSegments()); // $ hasTaintFlow
203+
sink(ui.getQueryParameters()); // $ hasTaintFlow
204+
sink(ui.getRequestUri()); // $ hasTaintFlow
205+
sink(ui.getRequestUriBuilder()); // $ hasTaintFlow
206+
sink(ui.getQueryParameters().getFirst("someKey")); // $ hasTaintFlow
207+
sink(ui.getRequestUri()); // $ hasTaintFlow
208+
sink(ui.getRequestUriBuilder().build()); // $ hasTaintFlow
209+
URI taintedUri = UriSource.taint();
210+
URI untaintedUri = new URI("");
211+
sink(untaintedUriInfo.relativize(taintedUri)); // $ hasTaintFlow
212+
sink(untaintedUriInfo.resolve(taintedUri)); // $ hasTaintFlow
213+
sink(ui.resolve(untaintedUri)); // $ hasTaintFlow
205214
}
206215

207216
void testCookie() {
@@ -341,7 +350,7 @@ void testUriBuilder() throws Exception {
341350
sink(UriBuilder.fromPath(taint()).buildFromEncodedMap(new HashMap<String, String>())); // $ hasTaintFlow
342351
sink(UriBuilder.fromPath("").buildFromMap(taint(new HashMap<String, String>()), false)); // $ hasTaintFlow
343352
sink(UriBuilder.fromPath(taint()).buildFromMap(new HashMap<String, String>(), true)); // $ hasTaintFlow
344-
353+
345354
sink(UriBuilder.fromPath(taint()).clone()); // $ hasTaintFlow
346355
sink(UriBuilder.fromPath("").fragment(taint())); // $ hasTaintFlow
347356
sink(UriBuilder.fromPath(taint()).fragment("")); // $ hasTaintFlow
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import javax.ws.rs.container.ContainerRequestContext;
2+
3+
public class JaxRsContainerRequestContextSources {
4+
void sink(Object o) {}
5+
6+
void test(ContainerRequestContext context) throws Exception {
7+
sink(context.getAcceptableLanguages()); // $ hasValueFlow
8+
sink(context.getAcceptableMediaTypes().get(0).getType()); // $ hasTaintFlow
9+
sink(context.getCookies().get("someKey").getValue()); // $ hasTaintFlow
10+
byte[] buf = new byte[1024];
11+
context.getEntityStream().read(buf);
12+
sink(buf); // $ hasTaintFlow
13+
sink(context.getHeaders().getFirst("someKey")); // $ hasTaintFlow
14+
sink(context.getHeaderString("someKey")); // $ hasValueFlow
15+
sink(context.getLanguage()); // $ hasValueFlow
16+
sink(context.getMediaType().getType()); // $ hasTaintFlow
17+
sink(context.getUriInfo().getPath()); // $ hasTaintFlow
18+
}
19+
}

java/ql/test/library-tests/frameworks/JaxWs/JaxRsFlow.java

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,11 @@ private static class SetStringSource {
5757
static PathSegment taint(PathSegment ps) { return ps; }
5858

5959
static UriInfo taint(UriInfo ui) { return ui; }
60-
60+
6161
static Map taint(Map m) { return m; }
62-
62+
6363
static Link taint(Link l) { return l; }
64-
64+
6565
static Class taint(Class c) { return c; }
6666

6767
private static class UriSource {
@@ -192,12 +192,21 @@ void testPathSegment(PathSegment ps1, PathSegment ps2) {
192192
sink(taint(ps2).getPath()); // $ hasTaintFlow
193193
}
194194

195-
void testUriInfo(UriInfo ui1, UriInfo ui2, UriInfo ui3, UriInfo ui4, UriInfo ui5) {
196-
sink(taint(ui1).getPathParameters()); // $ hasTaintFlow
197-
sink(taint(ui2).getPathSegments()); // $ hasTaintFlow
198-
sink(taint(ui2).getQueryParameters()); // $ hasTaintFlow
199-
sink(taint(ui2).getRequestUri()); // $ hasTaintFlow
200-
sink(taint(ui2).getRequestUriBuilder()); // $ hasTaintFlow
195+
void testUriInfo(UriInfo ui, UriInfo untaintedUriInfo) throws Exception {
196+
ui = taint(ui);
197+
sink(ui.getPathParameters()); // $ hasTaintFlow
198+
sink(ui.getPathSegments()); // $ hasTaintFlow
199+
sink(ui.getQueryParameters()); // $ hasTaintFlow
200+
sink(ui.getRequestUri()); // $ hasTaintFlow
201+
sink(ui.getRequestUriBuilder()); // $ hasTaintFlow
202+
sink(ui.getQueryParameters().getFirst("someKey")); // $ hasTaintFlow
203+
sink(ui.getRequestUri()); // $ hasTaintFlow
204+
sink(ui.getRequestUriBuilder().build()); // $ hasTaintFlow
205+
URI taintedUri = UriSource.taint();
206+
URI untaintedUri = new URI("");
207+
sink(untaintedUriInfo.relativize(taintedUri)); // $ hasTaintFlow
208+
sink(untaintedUriInfo.resolve(taintedUri)); // $ hasTaintFlow
209+
sink(ui.resolve(untaintedUri)); // $ hasTaintFlow
201210
}
202211

203212
void testCookie() {
@@ -337,7 +346,7 @@ void testUriBuilder() throws Exception {
337346
sink(UriBuilder.fromPath(taint()).buildFromEncodedMap(new HashMap<String, String>())); // $ hasTaintFlow
338347
sink(UriBuilder.fromPath("").buildFromMap(taint(new HashMap<String, String>()), false)); // $ hasTaintFlow
339348
sink(UriBuilder.fromPath(taint()).buildFromMap(new HashMap<String, String>(), true)); // $ hasTaintFlow
340-
349+
341350
sink(UriBuilder.fromPath(taint()).clone()); // $ hasTaintFlow
342351
sink(UriBuilder.fromPath("").fragment(taint())); // $ hasTaintFlow
343352
sink(UriBuilder.fromPath(taint()).fragment("")); // $ hasTaintFlow

java/ql/test/library-tests/frameworks/JaxWs/JaxRsFlow.ql

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
import java
22
import semmle.code.java.dataflow.TaintTracking
3+
import semmle.code.java.dataflow.FlowSources
34
import TestUtilities.InlineExpectationsTest
45

56
class TaintFlowConf extends TaintTracking::Configuration {
67
TaintFlowConf() { this = "qltest:frameworks:jax-rs-taint" }
78

89
override predicate isSource(DataFlow::Node n) {
910
n.asExpr().(MethodAccess).getMethod().hasName("taint")
11+
or
12+
n instanceof RemoteFlowSource
1013
}
1114

1215
override predicate isSink(DataFlow::Node n) {
@@ -21,6 +24,8 @@ class ValueFlowConf extends DataFlow::Configuration {
2124

2225
override predicate isSource(DataFlow::Node n) {
2326
n.asExpr().(MethodAccess).getMethod().hasName("taint")
27+
or
28+
n instanceof RemoteFlowSource
2429
}
2530

2631
override predicate isSink(DataFlow::Node n) {

0 commit comments

Comments
 (0)