Merge pull request #2726 from aschackmull/java/outputstream-write-taint

Java: Improve taint for OutputStream.write and InputStream.read.
This commit is contained in:
yo-h
2020-01-30 18:24:00 -05:00
committed by GitHub
4 changed files with 59 additions and 6 deletions

View File

@@ -256,9 +256,12 @@ private predicate taintPreservingQualifierToArgument(Method m, int arg) {
m.hasName("writeTo") and
arg = 0
or
m.getDeclaringType().hasQualifiedName("java.io", "InputStream") and
m.hasName("read") and
arg = 0
exists(Method read |
m.overrides*(read) and
read.getDeclaringType().hasQualifiedName("java.io", "InputStream") and
read.hasName("read") and
arg = 0
)
or
m.getDeclaringType().getASupertype*().hasQualifiedName("java.io", "Reader") and
m.hasName("read") and
@@ -515,9 +518,12 @@ private predicate argToQualifierStep(Expr tracked, Expr sink) {
* `arg` is the index of the argument.
*/
private predicate taintPreservingArgumentToQualifier(Method method, int arg) {
method.getDeclaringType().hasQualifiedName("java.io", "ByteArrayOutputStream") and
method.hasName("write") and
arg = 0
exists(Method write |
method.overrides*(write) and
write.getDeclaringType().hasQualifiedName("java.io", "OutputStream") and
write.hasName("write") and
arg = 0
)
}
/** A comparison or equality test with a constant. */

View File

@@ -0,0 +1,27 @@
import java.io.*;
public class A {
byte[] taint() { return new byte[2]; }
void sink(Object o) { }
void test1() {
ByteArrayOutputStream bOutput = new ByteArrayOutputStream();
bOutput.write(taint(), 0, 1);
byte[] b = bOutput.toByteArray();
ByteArrayInputStream bInput = new ByteArrayInputStream(b);
byte[] b2 = new byte[10];
bInput.read(b2, 0, 1);
sink(b2);
}
void test2() {
ByteArrayOutputStream bOutput = new ByteArrayOutputStream();
bOutput.write(taint());
byte[] b = bOutput.toByteArray();
ByteArrayInputStream bInput = new ByteArrayInputStream(b);
byte[] b2 = new byte[10];
bInput.read(b2);
sink(b2);
}
}

View File

@@ -0,0 +1,2 @@
| 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 |

View File

@@ -0,0 +1,18 @@
import java
import semmle.code.java.dataflow.TaintTracking
class Conf extends TaintTracking::Configuration {
Conf() { this = "qqconf" }
override predicate isSource(DataFlow::Node n) {
n.asExpr().(MethodAccess).getMethod().hasName("taint")
}
override predicate isSink(DataFlow::Node n) {
n.asExpr().(Argument).getCall().getCallee().hasName("sink")
}
}
from DataFlow::Node src, DataFlow::Node sink, Conf conf
where conf.hasFlow(src, sink)
select src, sink