Merge branch 'main' into inlineFlowTest

This commit is contained in:
Benjamin Muskalla
2021-09-13 17:15:37 +02:00
354 changed files with 12576 additions and 2394 deletions

View File

@@ -1,6 +1,8 @@
edges
| A2.java:15:15:15:28 | new Integer(...) : Number | A2.java:27:27:27:34 | o : Number |
| A2.java:27:27:27:34 | o : Number | A2.java:29:9:29:9 | o |
| A.java:6:28:6:35 | o : Number | A.java:8:11:8:11 | o : Number |
| A.java:6:28:6:35 | o : Number | A.java:8:11:8:11 | o : Number |
| A.java:14:29:14:36 | o : Number | A.java:16:9:16:9 | o |
| A.java:20:30:20:37 | o : Number | A.java:22:9:22:9 | o |
| A.java:26:31:26:38 | o : Number | A.java:28:9:28:9 | o |
@@ -15,12 +17,14 @@ edges
| A.java:66:25:66:38 | new Integer(...) : Number | A.java:43:36:43:43 | o : Number |
| A.java:67:25:67:38 | new Integer(...) : Number | A.java:43:36:43:43 | o : Number |
| A.java:68:25:68:38 | new Integer(...) : Number | A.java:43:36:43:43 | o : Number |
| A.java:69:20:69:33 | new Integer(...) : Number | A.java:6:28:6:35 | o : Number |
| A.java:69:20:69:33 | new Integer(...) : Number | A.java:69:8:69:40 | flowThrough(...) |
| A.java:71:25:71:38 | new Integer(...) : Number | A.java:43:36:43:43 | o : Number |
| A.java:84:18:84:31 | new Integer(...) : Number | A.java:14:29:14:36 | o : Number |
| A.java:85:19:85:32 | new Integer(...) : Number | A.java:20:30:20:37 | o : Number |
| A.java:86:20:86:33 | new Integer(...) : Number | A.java:26:31:26:38 | o : Number |
| A.java:87:24:87:37 | new Integer(...) : Number | A.java:32:35:32:42 | o : Number |
| A.java:88:20:88:33 | new Integer(...) : Number | A.java:6:28:6:35 | o : Number |
| A.java:88:20:88:33 | new Integer(...) : Number | A.java:88:8:88:37 | flowThrough(...) |
| A.java:99:20:99:33 | new Integer(...) : Number | A.java:106:30:106:37 | o : Number |
| A.java:100:21:100:34 | new Integer(...) : Number | A.java:113:31:113:38 | o : Number |
@@ -32,6 +36,10 @@ nodes
| A2.java:15:15:15:28 | new Integer(...) : Number | semmle.label | new Integer(...) : Number |
| A2.java:27:27:27:34 | o : Number | semmle.label | o : Number |
| A2.java:29:9:29:9 | o | semmle.label | o |
| A.java:6:28:6:35 | o : Number | semmle.label | o : Number |
| A.java:6:28:6:35 | o : Number | semmle.label | o : Number |
| A.java:8:11:8:11 | o : Number | semmle.label | o : Number |
| A.java:8:11:8:11 | o : Number | semmle.label | o : Number |
| A.java:14:29:14:36 | o : Number | semmle.label | o : Number |
| A.java:16:9:16:9 | o | semmle.label | o |
| A.java:20:30:20:37 | o : Number | semmle.label | o : Number |
@@ -69,6 +77,9 @@ nodes
| A.java:115:10:115:10 | o | semmle.label | o |
| A.java:120:36:120:43 | o : Number | semmle.label | o : Number |
| A.java:128:9:128:10 | o3 | semmle.label | o3 |
subpaths
| A.java:69:20:69:33 | new Integer(...) : Number | A.java:6:28:6:35 | o : Number | A.java:8:11:8:11 | o : Number | A.java:69:8:69:40 | flowThrough(...) : Number |
| A.java:88:20:88:33 | new Integer(...) : Number | A.java:6:28:6:35 | o : Number | A.java:8:11:8:11 | o : Number | A.java:88:8:88:37 | flowThrough(...) : Number |
#select
| A2.java:15:15:15:28 | new Integer(...) : Number | A2.java:15:15:15:28 | new Integer(...) : Number | A2.java:29:9:29:9 | o | $@ | A2.java:29:9:29:9 | o | o |
| A.java:62:18:62:31 | new Integer(...) : Number | A.java:62:18:62:31 | new Integer(...) : Number | A.java:16:9:16:9 | o | $@ | A.java:16:9:16:9 | o | o |

View File

@@ -46,6 +46,9 @@ public class B {
// tainted - tokenized string
String token = new StringTokenizer(badEscape).nextToken();
sink(token);
// tainted - fluent concatenation
String fluentConcat = "".concat("str").concat(token).concat("bar");
sink(fluentConcat);
// not tainted
String safe = notTainty(complex);

View File

@@ -0,0 +1,13 @@
public class CharSeq {
public static String taint() { return "tainted"; }
public static void sink(Object o) { }
void test1() {
CharSequence seq = taint().subSequence(0,1);
sink(seq);
CharSequence seqFromSeq = seq.subSequence(0, 1);
sink(seqFromSeq);
}
}

View File

@@ -14,29 +14,32 @@
| B.java:15:21:15:27 | taint(...) | B.java:42:10:42:25 | valueOfSubstring |
| B.java:15:21:15:27 | taint(...) | B.java:45:10:45:18 | badEscape |
| B.java:15:21:15:27 | taint(...) | B.java:48:10:48:14 | token |
| B.java:15:21:15:27 | taint(...) | B.java:65:10:65:13 | cond |
| B.java:15:21:15:27 | taint(...) | B.java:68:10:68:14 | logic |
| B.java:15:21:15:27 | taint(...) | B.java:70:10:70:39 | endsWith(...) |
| B.java:15:21:15:27 | taint(...) | B.java:73:10:73:14 | logic |
| B.java:15:21:15:27 | taint(...) | B.java:51:10:51:21 | fluentConcat |
| B.java:15:21:15:27 | taint(...) | B.java:68:10:68:13 | cond |
| B.java:15:21:15:27 | taint(...) | B.java:71:10:71:14 | logic |
| B.java:15:21:15:27 | taint(...) | B.java:73:10:73:39 | endsWith(...) |
| B.java:15:21:15:27 | taint(...) | B.java:76:10:76:14 | logic |
| B.java:15:21:15:27 | taint(...) | B.java:84:10:84:16 | trimmed |
| B.java:15:21:15:27 | taint(...) | B.java:86:10:86:14 | split |
| B.java:15:21:15:27 | taint(...) | B.java:88:10:88:14 | lower |
| B.java:15:21:15:27 | taint(...) | B.java:90:10:90:14 | upper |
| B.java:15:21:15:27 | taint(...) | B.java:92:10:92:14 | bytes |
| B.java:15:21:15:27 | taint(...) | B.java:94:10:94:17 | toString |
| B.java:15:21:15:27 | taint(...) | B.java:96:10:96:13 | subs |
| B.java:15:21:15:27 | taint(...) | B.java:98:10:98:13 | repl |
| B.java:15:21:15:27 | taint(...) | B.java:100:10:100:16 | replAll |
| B.java:15:21:15:27 | taint(...) | B.java:102:10:102:18 | replFirst |
| B.java:15:21:15:27 | taint(...) | B.java:115:12:115:25 | serializedData |
| B.java:15:21:15:27 | taint(...) | B.java:127:12:127:27 | deserializedData |
| B.java:15:21:15:27 | taint(...) | B.java:136:10:136:21 | taintedArray |
| B.java:15:21:15:27 | taint(...) | B.java:138:10:138:22 | taintedArray2 |
| B.java:15:21:15:27 | taint(...) | B.java:140:10:140:22 | taintedArray3 |
| B.java:15:21:15:27 | taint(...) | B.java:143:10:143:44 | toURL(...) |
| B.java:15:21:15:27 | taint(...) | B.java:146:10:146:37 | toPath(...) |
| B.java:15:21:15:27 | taint(...) | B.java:149:10:149:46 | toFile(...) |
| B.java:15:21:15:27 | taint(...) | B.java:79:10:79:14 | logic |
| B.java:15:21:15:27 | taint(...) | B.java:87:10:87:16 | trimmed |
| B.java:15:21:15:27 | taint(...) | B.java:89:10:89:14 | split |
| B.java:15:21:15:27 | taint(...) | B.java:91:10:91:14 | lower |
| B.java:15:21:15:27 | taint(...) | B.java:93:10:93:14 | upper |
| B.java:15:21:15:27 | taint(...) | B.java:95:10:95:14 | bytes |
| B.java:15:21:15:27 | taint(...) | B.java:97:10:97:17 | toString |
| B.java:15:21:15:27 | taint(...) | B.java:99:10:99:13 | subs |
| B.java:15:21:15:27 | taint(...) | B.java:101:10:101:13 | repl |
| B.java:15:21:15:27 | taint(...) | B.java:103:10:103:16 | replAll |
| B.java:15:21:15:27 | taint(...) | B.java:105:10:105:18 | replFirst |
| B.java:15:21:15:27 | taint(...) | B.java:118:12:118:25 | serializedData |
| B.java:15:21:15:27 | taint(...) | B.java:130:12:130:27 | deserializedData |
| B.java:15:21:15:27 | taint(...) | B.java:139:10:139:21 | taintedArray |
| B.java:15:21:15:27 | taint(...) | B.java:141:10:141:22 | taintedArray2 |
| B.java:15:21:15:27 | taint(...) | B.java:143:10:143:22 | taintedArray3 |
| B.java:15:21:15:27 | taint(...) | B.java:146:10:146:44 | toURL(...) |
| B.java:15:21:15:27 | taint(...) | B.java:149:10:149:37 | toPath(...) |
| B.java:15:21:15:27 | taint(...) | B.java:152:10:152:46 | toFile(...) |
| CharSeq.java:7:26:7:32 | taint(...) | CharSeq.java:8:12:8:14 | seq |
| CharSeq.java:7:26:7:32 | taint(...) | CharSeq.java:11:12:11:21 | seqFromSeq |
| MethodFlow.java:7:22:7:28 | taint(...) | MethodFlow.java:8:10:8:16 | tainted |
| MethodFlow.java:9:31:9:37 | taint(...) | MethodFlow.java:10:10:10:17 | tainted2 |
| MethodFlow.java:11:35:11:41 | taint(...) | MethodFlow.java:12:10:12:17 | tainted3 |

View File

@@ -0,0 +1,19 @@
import jakarta.ws.rs.container.ContainerRequestContext;
public class JakartaContainerRequestContextSources {
void sink(Object o) {}
void test(ContainerRequestContext context) throws Exception {
sink(context.getAcceptableLanguages()); // $ hasValueFlow
sink(context.getAcceptableMediaTypes().get(0).getType()); // $ hasTaintFlow
sink(context.getCookies().get("someKey").getValue()); // $ hasTaintFlow
byte[] buf = new byte[1024];
context.getEntityStream().read(buf);
sink(buf); // $ hasTaintFlow
sink(context.getHeaders().getFirst("someKey")); // $ hasTaintFlow
sink(context.getHeaderString("someKey")); // $ hasValueFlow
sink(context.getLanguage()); // $ hasValueFlow
sink(context.getMediaType().getType()); // $ hasTaintFlow
sink(context.getUriInfo().getPath()); // $ hasTaintFlow
}
}

View File

@@ -57,11 +57,11 @@ public class JakartaRsFlow {
static PathSegment taint(PathSegment ps) { return ps; }
static UriInfo taint(UriInfo ui) { return ui; }
static Map taint(Map m) { return m; }
static Link taint(Link l) { return l; }
static Class taint(Class c) { return c; }
private static class UriSource {
@@ -196,12 +196,21 @@ public class JakartaRsFlow {
sink(taint(ps2).getPath()); // $ hasTaintFlow
}
void testUriInfo(UriInfo ui1, UriInfo ui2, UriInfo ui3, UriInfo ui4, UriInfo ui5) {
sink(taint(ui1).getPathParameters()); // $ hasTaintFlow
sink(taint(ui2).getPathSegments()); // $ hasTaintFlow
sink(taint(ui2).getQueryParameters()); // $ hasTaintFlow
sink(taint(ui2).getRequestUri()); // $ hasTaintFlow
sink(taint(ui2).getRequestUriBuilder()); // $ hasTaintFlow
void testUriInfo(UriInfo ui, UriInfo untaintedUriInfo) throws Exception {
ui = taint(ui);
sink(ui.getPathParameters()); // $ hasTaintFlow
sink(ui.getPathSegments()); // $ hasTaintFlow
sink(ui.getQueryParameters()); // $ hasTaintFlow
sink(ui.getRequestUri()); // $ hasTaintFlow
sink(ui.getRequestUriBuilder()); // $ hasTaintFlow
sink(ui.getQueryParameters().getFirst("someKey")); // $ hasTaintFlow
sink(ui.getRequestUri()); // $ hasTaintFlow
sink(ui.getRequestUriBuilder().build()); // $ hasTaintFlow
URI taintedUri = UriSource.taint();
URI untaintedUri = new URI("");
sink(untaintedUriInfo.relativize(taintedUri)); // $ hasTaintFlow
sink(untaintedUriInfo.resolve(taintedUri)); // $ hasTaintFlow
sink(ui.resolve(untaintedUri)); // $ hasTaintFlow
}
void testCookie() {
@@ -341,7 +350,7 @@ public class JakartaRsFlow {
sink(UriBuilder.fromPath(taint()).buildFromEncodedMap(new HashMap<String, String>())); // $ hasTaintFlow
sink(UriBuilder.fromPath("").buildFromMap(taint(new HashMap<String, String>()), false)); // $ hasTaintFlow
sink(UriBuilder.fromPath(taint()).buildFromMap(new HashMap<String, String>(), true)); // $ hasTaintFlow
sink(UriBuilder.fromPath(taint()).clone()); // $ hasTaintFlow
sink(UriBuilder.fromPath("").fragment(taint())); // $ hasTaintFlow
sink(UriBuilder.fromPath(taint()).fragment("")); // $ hasTaintFlow

View File

@@ -0,0 +1,19 @@
import javax.ws.rs.container.ContainerRequestContext;
public class JaxRsContainerRequestContextSources {
void sink(Object o) {}
void test(ContainerRequestContext context) throws Exception {
sink(context.getAcceptableLanguages()); // $ hasValueFlow
sink(context.getAcceptableMediaTypes().get(0).getType()); // $ hasTaintFlow
sink(context.getCookies().get("someKey").getValue()); // $ hasTaintFlow
byte[] buf = new byte[1024];
context.getEntityStream().read(buf);
sink(buf); // $ hasTaintFlow
sink(context.getHeaders().getFirst("someKey")); // $ hasTaintFlow
sink(context.getHeaderString("someKey")); // $ hasValueFlow
sink(context.getLanguage()); // $ hasValueFlow
sink(context.getMediaType().getType()); // $ hasTaintFlow
sink(context.getUriInfo().getPath()); // $ hasTaintFlow
}
}

View File

@@ -57,11 +57,11 @@ public class JaxRsFlow {
static PathSegment taint(PathSegment ps) { return ps; }
static UriInfo taint(UriInfo ui) { return ui; }
static Map taint(Map m) { return m; }
static Link taint(Link l) { return l; }
static Class taint(Class c) { return c; }
private static class UriSource {
@@ -192,12 +192,21 @@ public class JaxRsFlow {
sink(taint(ps2).getPath()); // $ hasTaintFlow
}
void testUriInfo(UriInfo ui1, UriInfo ui2, UriInfo ui3, UriInfo ui4, UriInfo ui5) {
sink(taint(ui1).getPathParameters()); // $ hasTaintFlow
sink(taint(ui2).getPathSegments()); // $ hasTaintFlow
sink(taint(ui2).getQueryParameters()); // $ hasTaintFlow
sink(taint(ui2).getRequestUri()); // $ hasTaintFlow
sink(taint(ui2).getRequestUriBuilder()); // $ hasTaintFlow
void testUriInfo(UriInfo ui, UriInfo untaintedUriInfo) throws Exception {
ui = taint(ui);
sink(ui.getPathParameters()); // $ hasTaintFlow
sink(ui.getPathSegments()); // $ hasTaintFlow
sink(ui.getQueryParameters()); // $ hasTaintFlow
sink(ui.getRequestUri()); // $ hasTaintFlow
sink(ui.getRequestUriBuilder()); // $ hasTaintFlow
sink(ui.getQueryParameters().getFirst("someKey")); // $ hasTaintFlow
sink(ui.getRequestUri()); // $ hasTaintFlow
sink(ui.getRequestUriBuilder().build()); // $ hasTaintFlow
URI taintedUri = UriSource.taint();
URI untaintedUri = new URI("");
sink(untaintedUriInfo.relativize(taintedUri)); // $ hasTaintFlow
sink(untaintedUriInfo.resolve(taintedUri)); // $ hasTaintFlow
sink(ui.resolve(untaintedUri)); // $ hasTaintFlow
}
void testCookie() {
@@ -337,7 +346,7 @@ public class JaxRsFlow {
sink(UriBuilder.fromPath(taint()).buildFromEncodedMap(new HashMap<String, String>())); // $ hasTaintFlow
sink(UriBuilder.fromPath("").buildFromMap(taint(new HashMap<String, String>()), false)); // $ hasTaintFlow
sink(UriBuilder.fromPath(taint()).buildFromMap(new HashMap<String, String>(), true)); // $ hasTaintFlow
sink(UriBuilder.fromPath(taint()).clone()); // $ hasTaintFlow
sink(UriBuilder.fromPath("").fragment(taint())); // $ hasTaintFlow
sink(UriBuilder.fromPath(taint()).fragment("")); // $ hasTaintFlow

View File

@@ -1,2 +1,20 @@
import java
import semmle.code.java.dataflow.TaintTracking
import semmle.code.java.dataflow.FlowSources
import TestUtilities.InlineFlowTest
class TaintFlowConf extends DefaultTaintFlowConf {
override predicate isSource(DataFlow::Node n) {
super.isSource(n)
or
n instanceof RemoteFlowSource
}
}
class ValueFlowConf extends DefaultValueFlowConf {
override predicate isSource(DataFlow::Node n) {
super.isSource(n)
or
n instanceof RemoteFlowSource
}
}

View File

@@ -12,6 +12,7 @@ nodes
| UrlRedirectJax.java:10:32:10:61 | getParameter(...) : String | semmle.label | getParameter(...) : String |
| UrlRedirectJax.java:13:33:13:71 | new URI(...) | semmle.label | new URI(...) |
| UrlRedirectJax.java:13:41:13:70 | getParameter(...) : String | semmle.label | getParameter(...) : String |
subpaths
#select
| UrlRedirectJakarta.java:10:24:10:62 | new URI(...) | UrlRedirectJakarta.java:10:32:10:61 | getParameter(...) : String | UrlRedirectJakarta.java:10:24:10:62 | new URI(...) | Potentially untrusted URL redirection due to $@. | UrlRedirectJakarta.java:10:32:10:61 | getParameter(...) | user-provided value |
| UrlRedirectJakarta.java:13:33:13:71 | new URI(...) | UrlRedirectJakarta.java:13:41:13:70 | getParameter(...) : String | UrlRedirectJakarta.java:13:33:13:71 | new URI(...) | Potentially untrusted URL redirection due to $@. | UrlRedirectJakarta.java:13:41:13:70 | getParameter(...) | user-provided value |

View File

@@ -0,0 +1,39 @@
public class Test {
interface Functional {
int f();
}
class Concrete implements Functional {
public int f() { return 0; }
}
interface FunctionalWithDefaults {
int f();
default int g() { return 1; }
}
interface NotFunctional {
default int g() { return 1; }
}
interface FunctionalWithObjectMethods {
int f();
// Not actually abstract; implementation comes from Object
boolean equals(Object obj);
int hashCode();
String toString();
}
interface NotFunctionalWithObjectMethods {
int f();
// Increases their visibility from `protected` to `public`; this requires subclasses to implement them
// See also JLS section "Functional Interfaces" which explicitly covers this
Object clone();
void finalize();
}
}

View File

@@ -0,0 +1,3 @@
| Test.java:3:13:3:22 | Functional |
| Test.java:11:13:11:34 | FunctionalWithDefaults |
| Test.java:21:13:21:39 | FunctionalWithObjectMethods |

View File

@@ -0,0 +1,3 @@
import java
select any(FunctionalInterface fi | fi.fromSource())

View File

@@ -15,6 +15,6 @@
| literals/Literals.java:130:3:130:13 | "\\u1234567" | \u1234567 | \u1234567 |
| literals/Literals.java:131:3:131:18 | "\\uaBcDeF\\u0aB1" | \uabcdeF\u0ab1 | \uabcdeF\u0ab1 |
| literals/Literals.java:132:3:132:16 | "\\uD800\\uDC00" | \ud800\udc00 | \ud800\udc00 |
| literals/Literals.java:134:3:134:10 | "\\uD800" | ? | ? |
| literals/Literals.java:135:3:135:10 | "\\uDC00" | ? | ? |
| literals/Literals.java:136:3:136:31 | "hello\\uD800hello\\uDC00world" | hello?hello?world | hello?hello?world |
| literals/Literals.java:134:3:134:10 | "\\uD800" | \ufffd | \ufffd |
| literals/Literals.java:135:3:135:10 | "\\uDC00" | \ufffd | \ufffd |
| literals/Literals.java:136:3:136:31 | "hello\\uD800hello\\uDC00world" | hello\ufffdhello\ufffdworld | hello\ufffdhello\ufffdworld |