[quandary] checking for flows from Intents parsed via Uris -> startActivity (and similar)

Reviewed By: mburman

Differential Revision: D3905877

fbshipit-source-id: 03fe2f6
master
Sam Blackshear 8 years ago committed by Facebook Github Bot
parent d6cf024c1b
commit af9f34bb60

@ -18,6 +18,7 @@ module JavaSource = struct
type t = type t =
| SharedPreferences (** private data read from SharedPreferences *) | SharedPreferences (** private data read from SharedPreferences *)
| Footprint of AccessPath.t (** source that was read from the environment. *) | Footprint of AccessPath.t (** source that was read from the environment. *)
| Intent
| Other (** for testing or uncategorized sources *) | Other (** for testing or uncategorized sources *)
let compare sk1 sk2 = match sk1, sk2 with let compare sk1 sk2 = match sk1, sk2 with
@ -27,6 +28,9 @@ module JavaSource = struct
| Footprint ap1, Footprint ap2 -> AccessPath.compare ap1 ap2 | Footprint ap1, Footprint ap2 -> AccessPath.compare ap1 ap2
| Footprint _, _ -> (-1) | Footprint _, _ -> (-1)
| _, Footprint _ -> 1 | _, Footprint _ -> 1
| Intent, Intent -> 0
| Intent, _ -> (-1)
| _, Intent -> 1
| Other, Other -> 0 | Other, Other -> 0
end end
@ -62,6 +66,8 @@ module JavaSource = struct
| Procname.Java pname -> | Procname.Java pname ->
begin begin
match Procname.java_get_class_name pname, Procname.java_get_method pname with match Procname.java_get_class_name pname, Procname.java_get_method pname with
| "android.content.Intent", ("parseUri" | "parseIntent") ->
[0, make Intent site]
| "android.content.SharedPreferences", "getString" -> | "android.content.SharedPreferences", "getString" ->
[0, make SharedPreferences site] [0, make SharedPreferences site]
| "com.facebook.infer.models.InferTaint", "inferSecretSource" -> | "com.facebook.infer.models.InferTaint", "inferSecretSource" ->
@ -84,6 +90,7 @@ module JavaSource = struct
compare t1 t2 = 0 compare t1 t2 = 0
let pp_kind fmt (kind : kind) = match kind with let pp_kind fmt (kind : kind) = match kind with
| Intent -> F.fprintf fmt "Intent"
| SharedPreferences -> F.fprintf fmt "SharedPreferences" | SharedPreferences -> F.fprintf fmt "SharedPreferences"
| Footprint ap -> F.fprintf fmt "Footprint[%a]" AccessPath.pp ap | Footprint ap -> F.fprintf fmt "Footprint[%a]" AccessPath.pp ap
| Other -> F.fprintf fmt "Other" | Other -> F.fprintf fmt "Other"
@ -102,6 +109,7 @@ module JavaSink = struct
module SinkKind = struct module SinkKind = struct
type t = type t =
| Intent (** sink that trusts an Intent *)
| Logging (** sink that logs one or more of its arguments *) | Logging (** sink that logs one or more of its arguments *)
| Other (** for testing or uncategorized sinks *) | Other (** for testing or uncategorized sinks *)
@ -109,6 +117,9 @@ module JavaSink = struct
| Logging, Logging -> 0 | Logging, Logging -> 0
| Logging, _ -> (-1) | Logging, _ -> (-1)
| _, Logging -> 1 | _, Logging -> 1
| Intent, Intent -> 0
| Intent, _ -> (-1)
| _, Intent -> 1
| Other, Other -> 0 | Other, Other -> 0
end end
@ -130,15 +141,43 @@ module JavaSink = struct
{ kind; site; } { kind; site; }
let get site = let get site =
(* taint all the inputs of [pname] *) (* taint all the inputs of [pname]. for non-static procedures, taints the "this" parameter only
let taint_all pname kind site ~report_reachable = if [taint_this] is true. *)
let taint_all ?(taint_this=false) pname kind site ~report_reachable =
let params =
let all_params = Procname.java_get_parameters pname in
if Procname.java_is_static (CallSite.pname site) || taint_this
then all_params
else IList.tl all_params in
IList.mapi IList.mapi
(fun param_num _ -> Sink.make_sink_param (make kind site) param_num ~report_reachable) (fun param_num _ -> Sink.make_sink_param (make kind site) param_num ~report_reachable)
(Procname.java_get_parameters pname) in params in
(* taint the nth non-"this" parameter (0-indexed) *)
let taint_nth n kind site ~report_reachable =
let first_index = if Procname.java_is_static (CallSite.pname site) then n else n + 1 in
[Sink.make_sink_param (make kind site) first_index ~report_reachable] in
match CallSite.pname site with match CallSite.pname site with
| Procname.Java pname -> | Procname.Java pname ->
begin begin
match Procname.java_get_class_name pname, Procname.java_get_method pname with match Procname.java_get_class_name pname, Procname.java_get_method pname with
| ("android.app.Activity" | "android.content.ContextWrapper" | "android.content.Context"),
("bindService" |
"sendBroadcast" |
"sendBroadcastAsUser" |
"sendOrderedBroadcast" |
"sendStickyBroadcast" |
"sendStickyBroadcastAsUser" |
"sendStickyOrderedBroadcast" |
"sendStickyOrderedBroadcastAsUser" |
"startActivities" |
"startActivity" |
"startActivityForResult" |
"startActivityIfNeeded" |
"startNextMatchingActivity" |
"startService") ->
taint_nth 0 Intent site ~report_reachable:true
| "android.app.Activity", ("startActivityFromChild" | "startActivityFromFragment") ->
taint_nth 1 Intent site ~report_reachable:true
| "android.util.Log", ("d" | "e" | "i" | "println" | "v" | "w" | "wtf") -> | "android.util.Log", ("d" | "e" | "i" | "println" | "v" | "w" | "wtf") ->
taint_all pname Logging site ~report_reachable:true taint_all pname Logging site ~report_reachable:true
| "com.facebook.infer.models.InferTaint", "inferSensitiveSink" -> | "com.facebook.infer.models.InferTaint", "inferSensitiveSink" ->
@ -160,6 +199,7 @@ module JavaSink = struct
compare t1 t2 = 0 compare t1 t2 = 0
let pp_kind fmt (kind : kind) = match kind with let pp_kind fmt (kind : kind) = match kind with
| Intent -> F.fprintf fmt "Intent"
| Logging -> F.fprintf fmt "Logging" | Logging -> F.fprintf fmt "Logging"
| Other -> F.fprintf fmt "Other" | Other -> F.fprintf fmt "Other"
@ -185,6 +225,8 @@ include
| SourceKind.Other, SinkKind.Other | SourceKind.Other, SinkKind.Other
| SourceKind.SharedPreferences, SinkKind.Logging -> | SourceKind.SharedPreferences, SinkKind.Logging ->
true true
| SourceKind.Intent, SinkKind.Intent ->
true
| _ -> | _ ->
false false

@ -0,0 +1,62 @@
/*
* Copyright (c) 2015 - 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.net.URISyntaxException;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import org.xmlpull.v1.XmlPullParserException;
public class Intents {
Activity activity;
public void callAllSinks(Intent i) {
activity.bindService(i, null, 0);
activity.sendBroadcast(i);
activity.sendBroadcastAsUser(i, null);
activity.sendOrderedBroadcast(i, null);
activity.sendStickyBroadcast(i);
activity.sendStickyBroadcastAsUser(i, null);
activity.sendStickyOrderedBroadcast(i, null, null, 0, null, null);
activity.sendStickyOrderedBroadcastAsUser(i, null, null, null, 0, null, null);
activity.startActivities(new Intent[] { i });
activity.startActivity(i);
activity.startActivityForResult(i, 0);
activity.startActivityIfNeeded(i, 0);
activity.startActivityFromChild(null, i, 0);
activity.startActivityFromFragment(null, i, 0);
activity.startService(i);
}
private native int rand();
public Intent returnAllSources() throws
IOException, URISyntaxException, XmlPullParserException {
switch (rand()) {
case 1:
return Intent.parseUri(null, 0);
case 2:
return Intent.parseIntent(null, null, null);
}
return null;
}
public void callAllSinksBad(String uri) throws
IOException, URISyntaxException, XmlPullParserException {
Intent intent = returnAllSources();
callAllSinks(intent);
}
}

@ -15,6 +15,7 @@ FILES = \
Basics.java \ Basics.java \
Exceptions.java \ Exceptions.java \
Fields.java \ Fields.java \
Intents.java \
Interprocedural.java \ Interprocedural.java \
LoggingPrivateData.java \ LoggingPrivateData.java \
Recursion.java \ Recursion.java \

Loading…
Cancel
Save