diff --git a/infer/src/quandary/JavaTrace.ml b/infer/src/quandary/JavaTrace.ml index 8255c5773..746c1310e 100644 --- a/infer/src/quandary/JavaTrace.ml +++ b/infer/src/quandary/JavaTrace.ml @@ -244,6 +244,7 @@ module SinkKind = struct | 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 *) + | ShellExec (** sink that runs a shell command *) | StartComponent (** sink that launches an Activity, Service, etc. *) | Other (** for testing or uncategorized sinks *) [@@deriving compare] @@ -265,6 +266,8 @@ module SinkKind = struct Logging | "OpenDrawableResource" -> OpenDrawableResource + | "ShellExec" -> + ShellExec | "StartComponent" -> StartComponent | _ -> @@ -364,6 +367,8 @@ module SinkKind = struct | "postUrl" | "postWebMessage" ) ) -> taint_all JavaScript + | "java.lang.Runtime", "exec" -> + taint_nth 0 ShellExec | class_name, method_name -> (* check the list of externally specified sinks *) let procedure = class_name ^ "." ^ method_name in @@ -405,6 +410,8 @@ module SinkKind = struct "Logging" | OpenDrawableResource -> "OpenDrawableResource" + | ShellExec -> + "ShellExec" | StartComponent -> "StartComponent" | Other -> @@ -474,6 +481,8 @@ include Trace.Make (struct Some IssueType.create_intent_from_uri | PrivateData, Logging -> Some IssueType.logging_private_data + | (Intent | UserControlledString | UserControlledURI), ShellExec -> + Some IssueType.shell_injection | Other, _ | _, Other -> (* for testing purposes, Other matches everything *) Some IssueType.quandary_taint_error diff --git a/infer/tests/codetoanalyze/java/quandary/UserControlledStrings.java b/infer/tests/codetoanalyze/java/quandary/UserControlledStrings.java index 28a95c224..e8f13cd4d 100644 --- a/infer/tests/codetoanalyze/java/quandary/UserControlledStrings.java +++ b/infer/tests/codetoanalyze/java/quandary/UserControlledStrings.java @@ -14,6 +14,8 @@ import android.content.ClipboardManager; import android.text.Html; import android.text.Spanned; import android.widget.EditText; +import java.io.IOException; +import java.lang.Runtime; import com.facebook.infer.builtins.InferTaint; @@ -38,4 +40,14 @@ public class UserControlledStrings { return Html.fromHtml(mEditText.getText().toString()); } + void clipboardToShellDirectBad() throws IOException { + Runtime.getRuntime().exec(clipboard.getText().toString()); + } + + void clipboardToShellArrayBad() throws IOException { + String[] cmds = new String[] { "ls", clipboard.getText().toString() }; + Runtime.getRuntime().exec(cmds); + } + + } diff --git a/infer/tests/codetoanalyze/java/quandary/issues.exp b/infer/tests/codetoanalyze/java/quandary/issues.exp index 487c106b5..4bd81d090 100644 --- a/infer/tests/codetoanalyze/java/quandary/issues.exp +++ b/infer/tests/codetoanalyze/java/quandary/issues.exp @@ -204,6 +204,8 @@ codetoanalyze/java/quandary/UnknownCode.java, void UnknownCode.propagateViaUnkno codetoanalyze/java/quandary/UnknownCode.java, void UnknownCode.propagateViaUnknownNativeCodeBad(), 3, QUANDARY_TAINT_ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] codetoanalyze/java/quandary/UserControlledStrings.java, Spanned UserControlledStrings.clipboardToHtmlBad(), 1, CROSS_SITE_SCRIPTING, [Return from CharSequence ClipboardManager.getText(),Call to Spanned Html.fromHtml(String) with tainted index 0] codetoanalyze/java/quandary/UserControlledStrings.java, Spanned UserControlledStrings.editTextToHtmlBad(), 1, CROSS_SITE_SCRIPTING, [Return from Editable EditText.getText(),Call to Spanned Html.fromHtml(String) with tainted index 0] +codetoanalyze/java/quandary/UserControlledStrings.java, void UserControlledStrings.clipboardToShellArrayBad(), 2, SHELL_INJECTION, [Return from CharSequence ClipboardManager.getText(),Call to Process Runtime.exec(java.lang.String[]) with tainted index 1] +codetoanalyze/java/quandary/UserControlledStrings.java, void UserControlledStrings.clipboardToShellDirectBad(), 1, SHELL_INJECTION, [Return from CharSequence ClipboardManager.getText(),Call to Process Runtime.exec(String) with tainted index 1] codetoanalyze/java/quandary/UserControlledStrings.java, void UserControlledStrings.readClipboardSourcesBad(), 1, QUANDARY_TAINT_ERROR, [Return from CharSequence ClipboardManager.getText(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] codetoanalyze/java/quandary/UserControlledStrings.java, void UserControlledStrings.readClipboardSourcesBad(), 2, QUANDARY_TAINT_ERROR, [Return from ClipData ClipboardManager.getPrimaryClip(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] codetoanalyze/java/quandary/UserControlledStrings.java, void UserControlledStrings.readClipboardSourcesBad(), 3, QUANDARY_TAINT_ERROR, [Return from ClipData ClipboardManager.getPrimaryClip(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0]