mirror of
https://github.com/github/codeql.git
synced 2026-05-03 12:45:27 +02:00
Java: Move some taint tests.
This commit is contained in:
65
java/ql/test/library-tests/dataflow/taint-ioutils/Test.java
Normal file
65
java/ql/test/library-tests/dataflow/taint-ioutils/Test.java
Normal file
@@ -0,0 +1,65 @@
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.io.StringWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
class Test {
|
||||
public static void ioutils() {
|
||||
InputStream inp = new FileInputStream("test"); // user input
|
||||
|
||||
InputStream buf = IOUtils.buffer(inp);
|
||||
List<String> lines = IOUtils.readLines(inp, "UTF-8");
|
||||
byte[] bytes = IOUtils.readFully(inp, 1000);
|
||||
InputStream buf2 = IOUtils.toBufferedInputStream(inp);
|
||||
Reader bufread = IOUtils.toBufferedReader(new InputStreamReader(inp));
|
||||
byte[] bytes2 = IOUtils.toByteArray(inp, 1000);
|
||||
char[] chars = IOUtils.toCharArray(inp, "UTF-8");
|
||||
String s = IOUtils.toString(inp, "UTF-8");
|
||||
InputStream is = IOUtils.toInputStream(s, "UTF-8");
|
||||
|
||||
StringWriter writer = new StringWriter();
|
||||
writer.toString(); // not tainted
|
||||
IOUtils.copy(inp, writer, "UTF-8");
|
||||
writer.toString(); // tainted
|
||||
|
||||
writer = new StringWriter();
|
||||
writer.toString(); // not tainted
|
||||
IOUtils.copyLarge(bufread, writer);
|
||||
writer.toString(); // tainted
|
||||
|
||||
byte x;
|
||||
byte[] tgt = new byte[100];
|
||||
x = tgt[0]; // not tainted
|
||||
IOUtils.read(inp, tgt);
|
||||
x = tgt[0]; // tainted
|
||||
|
||||
tgt = new byte[100];
|
||||
x = tgt[0]; // not tainted
|
||||
IOUtils.readFully(inp, tgt);
|
||||
x = tgt[0]; // tainted
|
||||
|
||||
writer = new StringWriter();
|
||||
writer.toString(); // not tainted
|
||||
IOUtils.write(chars, writer);
|
||||
writer.toString(); // tainted
|
||||
|
||||
writer = new StringWriter();
|
||||
writer.toString(); // not tainted
|
||||
IOUtils.writeChunked(chars, writer);
|
||||
writer.toString(); // tainted
|
||||
|
||||
writer = new StringWriter();
|
||||
writer.toString(); // not tainted
|
||||
IOUtils.writeLines(lines, "\n", writer);
|
||||
writer.toString(); // tainted
|
||||
|
||||
writer = new StringWriter();
|
||||
writer.toString(); // not tainted
|
||||
IOUtils.writeLines(new ArrayList<String>(), s, writer);
|
||||
writer.toString(); // tainted
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
| Test.java:12:21:12:47 | new FileInputStream(...) |
|
||||
| Test.java:14:21:14:39 | buffer(...) |
|
||||
| Test.java:14:36:14:38 | inp |
|
||||
| Test.java:15:24:15:54 | readLines(...) |
|
||||
| Test.java:15:42:15:44 | inp |
|
||||
| Test.java:16:18:16:45 | readFully(...) |
|
||||
| Test.java:16:36:16:38 | inp |
|
||||
| Test.java:17:22:17:55 | toBufferedInputStream(...) |
|
||||
| Test.java:17:52:17:54 | inp |
|
||||
| Test.java:18:20:18:71 | toBufferedReader(...) |
|
||||
| Test.java:18:45:18:70 | new InputStreamReader(...) |
|
||||
| Test.java:18:67:18:69 | inp |
|
||||
| Test.java:19:19:19:48 | toByteArray(...) |
|
||||
| Test.java:19:39:19:41 | inp |
|
||||
| Test.java:20:18:20:50 | toCharArray(...) |
|
||||
| Test.java:20:38:20:40 | inp |
|
||||
| Test.java:21:14:21:43 | toString(...) |
|
||||
| Test.java:21:31:21:33 | inp |
|
||||
| Test.java:22:20:22:52 | toInputStream(...) |
|
||||
| Test.java:22:42:22:42 | s |
|
||||
| Test.java:26:16:26:18 | inp |
|
||||
| Test.java:26:21:26:26 | writer |
|
||||
| Test.java:27:3:27:8 | writer |
|
||||
| Test.java:27:3:27:19 | toString(...) |
|
||||
| Test.java:31:21:31:27 | bufread |
|
||||
| Test.java:31:30:31:35 | writer |
|
||||
| Test.java:32:3:32:8 | writer |
|
||||
| Test.java:32:3:32:19 | toString(...) |
|
||||
| Test.java:37:16:37:18 | inp |
|
||||
| Test.java:37:21:37:23 | tgt |
|
||||
| Test.java:38:3:38:12 | ...=... |
|
||||
| Test.java:38:7:38:9 | tgt |
|
||||
| Test.java:38:7:38:12 | ...[...] |
|
||||
| Test.java:42:21:42:23 | inp |
|
||||
| Test.java:42:26:42:28 | tgt |
|
||||
| Test.java:43:3:43:12 | ...=... |
|
||||
| Test.java:43:7:43:9 | tgt |
|
||||
| Test.java:43:7:43:12 | ...[...] |
|
||||
| Test.java:47:17:47:21 | chars |
|
||||
| Test.java:47:24:47:29 | writer |
|
||||
| Test.java:48:3:48:8 | writer |
|
||||
| Test.java:48:3:48:19 | toString(...) |
|
||||
| Test.java:52:24:52:28 | chars |
|
||||
| Test.java:52:31:52:36 | writer |
|
||||
| Test.java:53:3:53:8 | writer |
|
||||
| Test.java:53:3:53:19 | toString(...) |
|
||||
| Test.java:57:22:57:26 | lines |
|
||||
| Test.java:57:35:57:40 | writer |
|
||||
| Test.java:58:3:58:8 | writer |
|
||||
| Test.java:58:3:58:19 | toString(...) |
|
||||
| Test.java:62:47:62:47 | s |
|
||||
| Test.java:62:50:62:55 | writer |
|
||||
| Test.java:63:3:63:8 | writer |
|
||||
| Test.java:63:3:63:19 | toString(...) |
|
||||
@@ -0,0 +1,15 @@
|
||||
import semmle.code.java.dataflow.DataFlow
|
||||
import semmle.code.java.dataflow.TaintTracking
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
|
||||
class Conf extends TaintTracking::Configuration {
|
||||
Conf() { this = "qltest:dataflow:ioutils" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof UserInput }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { any() }
|
||||
}
|
||||
|
||||
from UserInput u, DataFlow::Node e, Conf config
|
||||
where config.hasFlow(u, e) and e.getEnclosingCallable().hasName("ioutils")
|
||||
select e
|
||||
@@ -0,0 +1 @@
|
||||
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/apache-commons-io-2.6
|
||||
159
java/ql/test/library-tests/dataflow/taint/B.java
Normal file
159
java/ql/test/library-tests/dataflow/taint/B.java
Normal file
@@ -0,0 +1,159 @@
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutput;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
public class B {
|
||||
public static String[] taint() { return new String[] { "tainted" }; }
|
||||
|
||||
public static void sink(Object o) { }
|
||||
|
||||
public static void maintest() {
|
||||
String[] args = taint();
|
||||
// tainted - access to main args
|
||||
String[] aaaargs = args;
|
||||
sink(aaaargs);
|
||||
// tainted - access to tainted array
|
||||
String s = args[0];
|
||||
sink(s);
|
||||
// tainted - concatenation of tainted string
|
||||
String concat = "Look at me " + s + ", I'm tainted!";
|
||||
sink(concat);
|
||||
// tainted - parenthesised
|
||||
String pars = (concat);
|
||||
sink(pars);
|
||||
// tainted method argument, implies tainted return value
|
||||
String method = tainty(pars);
|
||||
sink(method);
|
||||
// tainted - complex
|
||||
String complex = ("Look at me " + args[0]) + ", I'm tainted!";
|
||||
sink(complex);
|
||||
// tainted - data preserving constructors
|
||||
String constructed = new String(complex);
|
||||
sink(constructed);
|
||||
// tainted - unsafe escape
|
||||
String badEscape = constructed.replaceAll("(<script>)", "");
|
||||
sink(badEscape);
|
||||
// tainted - tokenized string
|
||||
String token = new StringTokenizer(badEscape).nextToken();
|
||||
sink(token);
|
||||
|
||||
// not tainted
|
||||
String safe = notTainty(complex);
|
||||
sink(safe);
|
||||
String shouldBeFine = taintyOtherArg(safe, complex);
|
||||
sink(shouldBeFine);
|
||||
// non-whitelisted constructors don't pass taint
|
||||
StringWrapper herring = new StringWrapper(complex);
|
||||
sink(herring);
|
||||
|
||||
// tainted equality check with constant
|
||||
boolean cond = "foo" == s;
|
||||
sink(cond);
|
||||
// tainted logic with tainted operand
|
||||
boolean logic = cond && safe();
|
||||
sink(logic);
|
||||
// tainted condition
|
||||
sink(concat.endsWith("I'm tainted"));
|
||||
// tainted
|
||||
logic = safe() || cond;
|
||||
sink(logic);
|
||||
// tainted, use of equals
|
||||
logic = badEscape.equals("constant");
|
||||
sink(logic);
|
||||
|
||||
// not tainted
|
||||
boolean okay = s == shouldBeFine;
|
||||
sink(okay);
|
||||
|
||||
// methods on string that pass on taint
|
||||
String trimmed = s.trim();
|
||||
sink(trimmed);
|
||||
String[] split = s.split(" ");
|
||||
sink(split);
|
||||
String lower = s.toLowerCase();
|
||||
sink(lower);
|
||||
String upper = s.toUpperCase();
|
||||
sink(upper);
|
||||
byte[] bytes = s.getBytes("UTF-8");
|
||||
sink(bytes);
|
||||
String toString = s.toString();
|
||||
sink(toString);
|
||||
String subs = s.substring(1, 10);
|
||||
sink(subs);
|
||||
String repl = "some constant".replace(" ", s);
|
||||
sink(repl);
|
||||
String replAll = "some constant".replaceAll(" ", s);
|
||||
sink(replAll);
|
||||
String replFirst = "some constant".replaceFirst(" ", s);
|
||||
sink(replFirst);
|
||||
|
||||
ByteArrayOutputStream baos = null;
|
||||
ObjectOutput oos = null;
|
||||
ByteArrayInputStream bais = null;
|
||||
ObjectInputStream ois = null;
|
||||
try
|
||||
{
|
||||
// serialization of tainted string
|
||||
baos = new ByteArrayOutputStream();
|
||||
oos = new ObjectOutputStream(baos);
|
||||
oos.writeObject(s);
|
||||
byte[] serializedData = baos.toByteArray(); // tainted
|
||||
sink(serializedData);
|
||||
// serialization of fixed string
|
||||
baos = new ByteArrayOutputStream();
|
||||
oos = new ObjectOutputStream(baos);
|
||||
oos.writeObject("not tainted");
|
||||
byte[] serializedData2 = baos.toByteArray(); // *not* tainted
|
||||
sink(serializedData2);
|
||||
|
||||
// de-serialization of tainted string
|
||||
bais = new ByteArrayInputStream(serializedData);
|
||||
ois = new ObjectInputStream(bais);
|
||||
String deserializedData = (String)ois.readObject(); // tainted
|
||||
sink(deserializedData);
|
||||
} catch (IOException e) {
|
||||
// ignored in test code
|
||||
} catch (ClassNotFoundException e) {
|
||||
// ignored in test code
|
||||
}
|
||||
|
||||
// tainted array initializers
|
||||
String[] taintedArray = new String[] { s };
|
||||
sink(taintedArray);
|
||||
String[][] taintedArray2 = new String[][] { { s } };
|
||||
sink(taintedArray2);
|
||||
String[][][] taintedArray3 = new String[][][] { { { s } } };
|
||||
sink(taintedArray3);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
public static String tainty(String arg) {
|
||||
// tainted return value
|
||||
return arg;
|
||||
}
|
||||
|
||||
public static String taintyOtherArg(String safe, String tainted) {
|
||||
return safe;
|
||||
}
|
||||
|
||||
public static String notTainty(String arg) {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
public static class StringWrapper {
|
||||
public String wrapped;
|
||||
|
||||
public StringWrapper(String s) {
|
||||
this.wrapped = s;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean safe() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
38
java/ql/test/library-tests/dataflow/taint/MethodFlow.java
Normal file
38
java/ql/test/library-tests/dataflow/taint/MethodFlow.java
Normal file
@@ -0,0 +1,38 @@
|
||||
public class MethodFlow {
|
||||
public static String taint() { return "tainted"; }
|
||||
|
||||
public static void sink(String s) { }
|
||||
|
||||
public void test() {
|
||||
String tainted = taint();
|
||||
sink(tainted);
|
||||
String tainted2 = notNull(taint());
|
||||
sink(tainted2);
|
||||
String tainted3 = wrapNotNull(taint());
|
||||
sink(tainted3);
|
||||
|
||||
String safe = notNull("a constant");
|
||||
sink(safe);
|
||||
|
||||
String diffString = returnDiffString(taint());
|
||||
sink(diffString);
|
||||
}
|
||||
|
||||
public <T> T notNull(T x) {
|
||||
if (x == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
public <T> T wrapNotNull(T x) {
|
||||
T res = notNull(x);
|
||||
sink("Logged: " + res);
|
||||
return res;
|
||||
}
|
||||
|
||||
public String returnDiffString(String x) {
|
||||
sink("Received: " + x);
|
||||
return "OK";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
public class StringBuilderTests {
|
||||
public static String taint() { return "tainted"; }
|
||||
|
||||
public static void sink(String s) { }
|
||||
|
||||
static void stringBuilderBad() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("from preferences select locale where user='");
|
||||
sb.append(taint());
|
||||
sb.append("'");
|
||||
sink(sb.toString());
|
||||
}
|
||||
|
||||
static void stringBuilderOkay() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("from preferences select locale where user='");
|
||||
sb.append("fred");
|
||||
sb.append("'");
|
||||
sink(sb.toString());
|
||||
}
|
||||
|
||||
static void stringBufferBad() {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append("from preferences select locale where user='");
|
||||
sb.append(taint());
|
||||
sb.append("'");
|
||||
sink(sb.toString());
|
||||
}
|
||||
|
||||
static void stringBuilderNoVarBad() {
|
||||
sink(new StringBuilder()
|
||||
.append("from preferences select locale where user='")
|
||||
.append(taint())
|
||||
.append("'").toString()
|
||||
);
|
||||
}
|
||||
|
||||
static void stringBuilderConstructorBad() {
|
||||
StringBuilder sb = new StringBuilder(taint());
|
||||
sb.append("from preferences select locale where user='");
|
||||
sb.append("fred");
|
||||
sb.append("'");
|
||||
sink(sb.toString());
|
||||
}
|
||||
|
||||
static void stringBuilderMultipleAppendsBad() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("from preferences select locale where user='").append(taint());
|
||||
sb.append("'");
|
||||
sink(sb.toString());
|
||||
}
|
||||
|
||||
static void stringBuilderReplaceBad() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("from preferences select locale where user='placeholder'");
|
||||
sb.replace(45, 57, taint());
|
||||
sink(sb.toString());
|
||||
}
|
||||
|
||||
static void stringBuilderInsertBad() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("from preferences select locale where user=''");
|
||||
sb.insert(45, taint());
|
||||
sink(sb.toString());
|
||||
}
|
||||
}
|
||||
26
java/ql/test/library-tests/dataflow/taint/Varargs.java
Normal file
26
java/ql/test/library-tests/dataflow/taint/Varargs.java
Normal file
@@ -0,0 +1,26 @@
|
||||
public class Varargs {
|
||||
public String taint() { return "tainted"; }
|
||||
|
||||
public void sink(String s) { }
|
||||
|
||||
public void sources() {
|
||||
f1(taint());
|
||||
f2(taint(), taint());
|
||||
f3(new String[] { taint(), "" });
|
||||
}
|
||||
|
||||
public void f1(String... ss) {
|
||||
String s = ss[0];
|
||||
sink(s);
|
||||
}
|
||||
|
||||
public void f2(String... ss) {
|
||||
String s = ss[0];
|
||||
sink(s);
|
||||
}
|
||||
|
||||
public void f3(String... ss) {
|
||||
String s = ss[0];
|
||||
sink(s);
|
||||
}
|
||||
}
|
||||
@@ -1,2 +1,47 @@
|
||||
| A.java:10:19:10:25 | taint(...) | A.java:15:10:15:11 | b2 |
|
||||
| A.java:20:19:20:25 | taint(...) | A.java:25:10:25:11 | b2 |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:18:10:18:16 | aaaargs |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:21:10:21:10 | s |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:24:10:24:15 | concat |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:27:10:27:13 | pars |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:30:10:30:15 | method |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:33:10:33:16 | complex |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:36:10:36:20 | constructed |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:39:10:39:18 | badEscape |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:42:10:42:14 | token |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:55:10:55:13 | cond |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:58:10:58:14 | logic |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:60:10:60:39 | endsWith(...) |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:63:10:63:14 | logic |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:66:10:66:14 | logic |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:74:10:74:16 | trimmed |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:76:10:76:14 | split |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:78:10:78:14 | lower |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:80:10:80:14 | upper |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:82:10:82:14 | bytes |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:84:10:84:17 | toString |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:86:10:86:13 | subs |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:88:10:88:13 | repl |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:90:10:90:16 | replAll |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:92:10:92:18 | replFirst |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:105:12:105:25 | serializedData |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:117:12:117:27 | deserializedData |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:126:10:126:21 | taintedArray |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:128:10:128:22 | taintedArray2 |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:130:10:130:22 | taintedArray3 |
|
||||
| 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 |
|
||||
| MethodFlow.java:11:35:11:41 | taint(...) | MethodFlow.java:30:10:30:25 | ... + ... |
|
||||
| MethodFlow.java:17:42:17:48 | taint(...) | MethodFlow.java:35:10:35:25 | ... + ... |
|
||||
| StringBuilderTests.java:9:15:9:21 | taint(...) | StringBuilderTests.java:11:10:11:22 | toString(...) |
|
||||
| StringBuilderTests.java:25:15:25:21 | taint(...) | StringBuilderTests.java:27:10:27:22 | toString(...) |
|
||||
| StringBuilderTests.java:33:15:33:21 | taint(...) | StringBuilderTests.java:31:10:34:29 | toString(...) |
|
||||
| StringBuilderTests.java:39:42:39:48 | taint(...) | StringBuilderTests.java:43:10:43:22 | toString(...) |
|
||||
| StringBuilderTests.java:48:69:48:75 | taint(...) | StringBuilderTests.java:50:10:50:22 | toString(...) |
|
||||
| StringBuilderTests.java:56:24:56:30 | taint(...) | StringBuilderTests.java:57:10:57:22 | toString(...) |
|
||||
| StringBuilderTests.java:63:19:63:25 | taint(...) | StringBuilderTests.java:64:10:64:22 | toString(...) |
|
||||
| Varargs.java:7:8:7:14 | taint(...) | Varargs.java:14:10:14:10 | s |
|
||||
| Varargs.java:8:8:8:14 | taint(...) | Varargs.java:19:10:19:10 | s |
|
||||
| Varargs.java:8:17:8:23 | taint(...) | Varargs.java:19:10:19:10 | s |
|
||||
| Varargs.java:9:23:9:29 | taint(...) | Varargs.java:24:10:24:10 | s |
|
||||
|
||||
49
java/ql/test/library-tests/dataflow/taintsources/A.java
Normal file
49
java/ql/test/library-tests/dataflow/taintsources/A.java
Normal file
@@ -0,0 +1,49 @@
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.Socket;
|
||||
import java.net.URL;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
public class A {
|
||||
public static void main(String[] args) {
|
||||
String[] a = args; // user input
|
||||
String s = args[0]; // user input
|
||||
}
|
||||
|
||||
public static void userInput() throws SQLException, IOException, MalformedURLException {
|
||||
System.getenv("test"); // user input
|
||||
class TestServlet extends HttpServlet {
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
|
||||
throws ServletException, IOException {
|
||||
req.getParameter("test"); // remote user input
|
||||
req.getHeader("test"); // remote user input
|
||||
req.getQueryString(); // remote user input
|
||||
req.getCookies()[0].getValue(); // remote user input
|
||||
}
|
||||
}
|
||||
new Properties().getProperty("test"); // user input
|
||||
System.getProperty("test"); // user input
|
||||
new Object() {
|
||||
public void test(ResultSet rs) throws SQLException {
|
||||
rs.getString(0); // user input
|
||||
}
|
||||
};
|
||||
new URL("test").openConnection().getInputStream(); // remote user input
|
||||
new Socket("test", 1234).getInputStream(); // remote user input
|
||||
InetAddress.getByName("test").getHostName(); // remote user input
|
||||
|
||||
System.in.read(); // user input
|
||||
new FileInputStream("test").read(); // user input
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package security.library.dataflow;
|
||||
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.RemoteException;
|
||||
|
||||
public interface RmiFlow extends Remote {
|
||||
String listDirectory(String path);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package security.library.dataflow;
|
||||
|
||||
public class RmiFlowImpl implements RmiFlow {
|
||||
public String listDirectory(String path) {
|
||||
String command = "ls " + path;
|
||||
Runtime.getRuntime().exec(command);
|
||||
return "pretend there are some results here";
|
||||
}
|
||||
|
||||
public String notRemotable(String path) {
|
||||
String command = "ls " + path;
|
||||
Runtime.getRuntime().exec(command);
|
||||
return "pretend there are some results here";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
| A.java:17:27:17:39 | args | A.java:17:27:17:39 | args |
|
||||
| A.java:17:27:17:39 | args | A.java:18:18:18:21 | args |
|
||||
| A.java:17:27:17:39 | args | A.java:19:16:19:19 | args |
|
||||
| A.java:17:27:17:39 | args | A.java:19:16:19:22 | ...[...] |
|
||||
| A.java:23:5:23:25 | getenv(...) | A.java:23:5:23:25 | getenv(...) |
|
||||
| A.java:34:5:34:40 | getProperty(...) | A.java:34:5:34:40 | getProperty(...) |
|
||||
| A.java:35:5:35:30 | getProperty(...) | A.java:35:5:35:30 | getProperty(...) |
|
||||
| A.java:38:9:38:23 | getString(...) | A.java:38:9:38:23 | getString(...) |
|
||||
| A.java:45:5:45:13 | System.in | A.java:45:5:45:13 | System.in |
|
||||
| A.java:46:5:46:31 | new FileInputStream(...) | A.java:46:5:46:31 | new FileInputStream(...) |
|
||||
18
java/ql/test/library-tests/dataflow/taintsources/local.ql
Normal file
18
java/ql/test/library-tests/dataflow/taintsources/local.ql
Normal file
@@ -0,0 +1,18 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.TaintTracking
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
|
||||
class Conf extends TaintTracking::Configuration {
|
||||
Conf() { this = "remote taint conf" }
|
||||
|
||||
override predicate isSource(DataFlow::Node n) {
|
||||
n instanceof UserInput and
|
||||
not n instanceof RemoteFlowSource
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node n) { any() }
|
||||
}
|
||||
|
||||
from DataFlow::Node src, DataFlow::Node sink, Conf conf
|
||||
where conf.hasFlow(src, sink)
|
||||
select src, sink
|
||||
1
java/ql/test/library-tests/dataflow/taintsources/options
Normal file
1
java/ql/test/library-tests/dataflow/taintsources/options
Normal file
@@ -0,0 +1 @@
|
||||
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/servlet-api-2.4
|
||||
@@ -0,0 +1,11 @@
|
||||
| A.java:28:9:28:32 | getParameter(...) | A.java:28:9:28:32 | getParameter(...) |
|
||||
| A.java:29:9:29:29 | getHeader(...) | A.java:29:9:29:29 | getHeader(...) |
|
||||
| A.java:30:9:30:28 | getQueryString(...) | A.java:30:9:30:28 | getQueryString(...) |
|
||||
| A.java:31:9:31:38 | getValue(...) | A.java:31:9:31:38 | getValue(...) |
|
||||
| A.java:41:5:41:53 | getInputStream(...) | A.java:41:5:41:53 | getInputStream(...) |
|
||||
| A.java:42:5:42:45 | getInputStream(...) | A.java:42:5:42:45 | getInputStream(...) |
|
||||
| A.java:43:5:43:47 | getHostName(...) | A.java:43:5:43:47 | getHostName(...) |
|
||||
| RmiFlowImpl.java:4:30:4:40 | path | RmiFlowImpl.java:4:30:4:40 | path |
|
||||
| RmiFlowImpl.java:4:30:4:40 | path | RmiFlowImpl.java:5:20:5:31 | ... + ... |
|
||||
| RmiFlowImpl.java:4:30:4:40 | path | RmiFlowImpl.java:5:28:5:31 | path |
|
||||
| RmiFlowImpl.java:4:30:4:40 | path | RmiFlowImpl.java:6:29:6:35 | command |
|
||||
15
java/ql/test/library-tests/dataflow/taintsources/remote.ql
Normal file
15
java/ql/test/library-tests/dataflow/taintsources/remote.ql
Normal file
@@ -0,0 +1,15 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.TaintTracking
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
|
||||
class Conf extends TaintTracking::Configuration {
|
||||
Conf() { this = "remote taint conf" }
|
||||
|
||||
override predicate isSource(DataFlow::Node n) { n instanceof RemoteFlowSource }
|
||||
|
||||
override predicate isSink(DataFlow::Node n) { any() }
|
||||
}
|
||||
|
||||
from DataFlow::Node src, DataFlow::Node sink, Conf conf
|
||||
where conf.hasFlow(src, sink)
|
||||
select src, sink
|
||||
@@ -0,0 +1,22 @@
|
||||
package org.apache.commons.io;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
public class IOUtils {
|
||||
public static BufferedInputStream buffer(InputStream inputStream) { return null; }
|
||||
public static void copy(InputStream input, Writer output, String inputEncoding) throws IOException { }
|
||||
public static long copyLarge(Reader input, Writer output) throws IOException { return 42; }
|
||||
public static int read(InputStream input, byte[] buffer) throws IOException { return 42; }
|
||||
public static void readFully(InputStream input, byte[] buffer) throws IOException { }
|
||||
public static byte[] readFully(InputStream input, int length) throws IOException { return null; }
|
||||
public static List<String> readLines(InputStream input, String encoding) throws IOException { return null; }
|
||||
public static InputStream toBufferedInputStream(InputStream input) throws IOException { return null; }
|
||||
public static BufferedReader toBufferedReader(Reader reader) { return null; }
|
||||
public static byte[] toByteArray(InputStream input, int size) throws IOException { return null; }
|
||||
public static char[] toCharArray(InputStream is, String encoding) throws IOException { return null; }
|
||||
public static InputStream toInputStream(String input, String encoding) throws IOException { return null; }
|
||||
public static String toString(InputStream input, String encoding) throws IOException { return null; }
|
||||
public static void write(char[] data, Writer output) throws IOException { }
|
||||
public static void writeChunked(char[] data, Writer output) throws IOException { }
|
||||
public static void writeLines(Collection<?> lines, String lineEnding, Writer writer) throws IOException { }
|
||||
}
|
||||
Reference in New Issue
Block a user