diff --git a/infer/src/quandary/JavaTrace.ml b/infer/src/quandary/JavaTrace.ml index c1ea659f4..71bc3ea68 100644 --- a/infer/src/quandary/JavaTrace.ml +++ b/infer/src/quandary/JavaTrace.ml @@ -174,6 +174,7 @@ module SinkKind = struct type t = | CreateFile (** sink that creates a file *) | CreateIntent (** sink that creates an Intent *) + | Deserialization (** sink that deserializes a Java object *) | HTML (** sink that creates HTML *) | JavaScript (** sink that passes its arguments to untrusted JS code *) | Logging (** sink that logs one or more of its arguments *) @@ -186,6 +187,8 @@ module SinkKind = struct -> CreateFile | "CreateIntent" -> CreateIntent + | "Deserialization" + -> Deserialization | "HTML" -> HTML | "JavaScript" @@ -233,6 +236,8 @@ module SinkKind = struct | "java.nio.file.FileSystem", "getPath" | "java.nio.file.Paths", "get" -> taint_all CreateFile + | "java.io.ObjectInputStream", "" + -> taint_all Deserialization | "com.facebook.infer.builtins.InferTaint", "inferSensitiveSink" -> taint_nth 0 Other | class_name, method_name @@ -295,6 +300,8 @@ module SinkKind = struct -> "CreateFile" | CreateIntent -> "CreateIntent" + | Deserialization + -> "Deserialization" | HTML -> "HTML" | JavaScript @@ -332,6 +339,9 @@ include Trace.Make (struct | UserControlledString, (StartComponent | CreateIntent | JavaScript | CreateFile | HTML) -> (* do something sensitive with a user-controlled string *) true + | (Intent | UserControlledURI | UserControlledString), Deserialization + -> (* shouldn't let anyone external control what we deserialize *) + true | Other, _ | _, Other -> (* for testing purposes, Other matches everything *) true diff --git a/infer/tests/codetoanalyze/java/quandary/Serialization.java b/infer/tests/codetoanalyze/java/quandary/Serialization.java new file mode 100644 index 000000000..2c237cccd --- /dev/null +++ b/infer/tests/codetoanalyze/java/quandary/Serialization.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2017 - present Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +package codetoanalyze.java.quandary; + +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; + +import com.facebook.infer.builtins.InferTaint; + +public class Serialization { + + + // we could warn on only particular calls to the tainted ObjectInputStream (e.g., readObject, + // readUnshared, but nothing good can come from creating a tainted ObjectInputStream + Object taintedObjectInputStreamBad() throws IOException, ClassNotFoundException { + Object source = InferTaint.inferSecretSource(); + ObjectInputStream stream = new ObjectInputStream((InputStream) source); // report here + return stream.readObject(); + } +} diff --git a/infer/tests/codetoanalyze/java/quandary/issues.exp b/infer/tests/codetoanalyze/java/quandary/issues.exp index 059275997..b70fd57bb 100644 --- a/infer/tests/codetoanalyze/java/quandary/issues.exp +++ b/infer/tests/codetoanalyze/java/quandary/issues.exp @@ -190,6 +190,7 @@ codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.log codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 39, QUANDARY_TAINT_ERROR, [Return from double Location.getLongitude(),Call to int Log.wtf(String,String)] codetoanalyze/java/quandary/Recursion.java, void Recursion.callSinkThenDivergeBad(), 1, QUANDARY_TAINT_ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void Recursion.callSinkThenDiverge(Object),Call to void InferTaint.inferSensitiveSink(Object)] codetoanalyze/java/quandary/Recursion.java, void Recursion.safeRecursionCallSinkBad(), 1, QUANDARY_TAINT_ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void Recursion.safeRecursionCallSink(int,Object),Call to void InferTaint.inferSensitiveSink(Object)] +codetoanalyze/java/quandary/Serialization.java, Object Serialization.taintedObjectInputStreamBad(), 2, QUANDARY_TAINT_ERROR, [Return from Object InferTaint.inferSecretSource(),Call to ObjectInputStream.(InputStream)] codetoanalyze/java/quandary/Strings.java, void Strings.viaFormatterBad(), 3, QUANDARY_TAINT_ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object)] codetoanalyze/java/quandary/Strings.java, void Strings.viaFormatterIgnoreReturnBad(), 4, QUANDARY_TAINT_ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object)] codetoanalyze/java/quandary/Strings.java, void Strings.viaStringBufferBad(), 3, QUANDARY_TAINT_ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object)]