[quandary] Different source kinds for endpoints

Reviewed By: ngorogiannis

Differential Revision: D13465357

fbshipit-source-id: 0e5f00a93
master
Mehdi Bouaziz 6 years ago committed by Facebook Github Bot
parent f6c2bd3f61
commit 9f333bb433

@ -16,7 +16,12 @@ let all_formals_untainted pdesc =
module type Kind = sig
include TraceElem.Kind
val get : Typ.Procname.t -> HilExp.t list -> Tenv.t -> (t * int option) list
val get :
caller_pname:Typ.Procname.t
-> Typ.Procname.t
-> HilExp.t list
-> Tenv.t
-> (t * int option) list
val get_tainted_formals : Procdesc.t -> Tenv.t -> (Mangled.t * Typ.t * t option) list
end
@ -26,7 +31,7 @@ module type S = sig
type spec = {source: t; index: int option}
val get : CallSite.t -> HilExp.t list -> Tenv.t -> spec list
val get : caller_pname:Typ.Procname.t -> CallSite.t -> HilExp.t list -> Tenv.t -> spec list
val get_tainted_formals : Procdesc.t -> Tenv.t -> (Mangled.t * Typ.t * t option) list
end
@ -44,8 +49,8 @@ module Make (Kind : Kind) = struct
let make ?indexes:_ kind site = {site; kind}
let get site actuals tenv =
Kind.get (CallSite.pname site) actuals tenv
let get ~caller_pname site actuals tenv =
Kind.get ~caller_pname (CallSite.pname site) actuals tenv
|> List.rev_map ~f:(fun (kind, index) ->
let source = make kind site in
{source; index} )
@ -85,7 +90,7 @@ module Dummy = struct
let pp _ () = ()
let get _ _ _ = []
let get ~caller_pname:_ _ _ _ = []
let get_tainted_formals pdesc _ =
List.map ~f:(fun (name, typ) -> (name, typ, None)) (Procdesc.get_formals pdesc)

@ -13,7 +13,12 @@ val all_formals_untainted : Procdesc.t -> (Mangled.t * Typ.t * 'a option) list
module type Kind = sig
include TraceElem.Kind
val get : Typ.Procname.t -> HilExp.t list -> Tenv.t -> (t * int option) list
val get :
caller_pname:Typ.Procname.t
-> Typ.Procname.t
-> HilExp.t list
-> Tenv.t
-> (t * int option) list
(** return Some (kind) if the procedure with the given actuals is a taint source, None otherwise *)
val get_tainted_formals : Procdesc.t -> Tenv.t -> (Mangled.t * Typ.t * t option) list
@ -28,7 +33,7 @@ module type S = sig
{ source: t (** type of the returned source *)
; index: int option (** index of the returned source if Some; return value if None *) }
val get : CallSite.t -> HilExp.t list -> Tenv.t -> spec list
val get : caller_pname:Typ.Procname.t -> CallSite.t -> HilExp.t list -> Tenv.t -> spec list
(** return Some (taint spec) if the call site with the given actuals is a taint source, None otherwise *)
val get_tainted_formals : Procdesc.t -> Tenv.t -> (Mangled.t * Typ.t * t option) list

@ -64,7 +64,7 @@ module SourceKind = struct
else [] )
let get pname actuals tenv =
let get ~caller_pname:_ pname actuals tenv =
let return = None in
match pname with
| Typ.Procname.ObjC_Cpp cpp_name -> (

@ -14,7 +14,7 @@ module SourceKind = struct
| DrawableResource of Pvar.t (** Drawable resource ID read from a global *)
| Endpoint of (Mangled.t * Typ.desc) (** source originating from formal of an endpoint *)
| Intent (** external Intent or a value read from one *)
| IntentForInsecureIntentHandling
| IntentForInsecureIntentHandling of {exposed: bool}
| IntentFromURI (** Intent created from a URI *)
| Other (** for testing or uncategorized sources *)
| PrivateData (** private user or device-specific data *)
@ -22,6 +22,20 @@ module SourceKind = struct
| UserControlledURI (** resource locator originating from the browser bar *)
[@@deriving compare]
let is_exposed ~caller_pname =
match caller_pname with
| Typ.Procname.Java java_pname ->
let class_name = Typ.Procname.Java.get_class_name java_pname in
QuandaryConfig.is_endpoint class_name
| _ ->
false
let intent_for_insecure_intent_handling ~caller_pname =
let exposed = is_exposed ~caller_pname in
IntentForInsecureIntentHandling {exposed}
let matches ~caller ~callee = Int.equal 0 (compare caller callee)
let of_string = function
@ -60,7 +74,7 @@ module SourceKind = struct
false
let get pname actuals tenv =
let get ~caller_pname pname actuals tenv =
let return = None in
let get_external_source class_name method_name =
(* check the list of externally specified sources *)
@ -79,9 +93,9 @@ module SourceKind = struct
let taint_matching_supertype typename =
match (Typ.Name.name typename, method_name) with
| "android.app.Activity", "getIntent" ->
Some [(Intent, return); (IntentForInsecureIntentHandling, return)]
Some [(Intent, return); (intent_for_insecure_intent_handling ~caller_pname, return)]
| "android.support.v4.app.FragmentActivity", "getIntent" ->
Some [(IntentForInsecureIntentHandling, return)]
Some [(intent_for_insecure_intent_handling ~caller_pname, return)]
| "android.content.Intent", "<init>"
when actual_has_type 2 "android.net.Uri" actuals tenv ->
(* taint the [this] parameter passed to the constructor *)
@ -94,7 +108,7 @@ module SourceKind = struct
| "setDataAndTypeAndNormalize" ) ) ->
Some [(IntentFromURI, return)]
| "android.content.Intent", "getData" ->
Some [(IntentForInsecureIntentHandling, return)]
Some [(intent_for_insecure_intent_handling ~caller_pname, return)]
| "android.content.Intent", "getStringExtra" ->
Some [(Intent, return)]
| "android.content.SharedPreferences", "getString" ->
@ -251,7 +265,7 @@ module SourceKind = struct
F.pp_print_string fmt (Pvar.to_string pvar)
| Endpoint (formal_name, _) ->
F.fprintf fmt "Endpoint(%s)" (Mangled.to_string formal_name)
| Intent | IntentForInsecureIntentHandling ->
| Intent | IntentForInsecureIntentHandling _ ->
F.pp_print_string fmt "Intent"
| IntentFromURI ->
F.pp_print_string fmt "IntentFromURI"
@ -592,7 +606,7 @@ include Trace.Make (struct
| DrawableResource _, OpenDrawableResource ->
(* not a security issue, but useful for debugging flows from resource IDs to inflation *)
Some IssueType.quandary_taint_error
| IntentForInsecureIntentHandling, StartComponentForInsecureIntentHandling ->
| IntentForInsecureIntentHandling _, StartComponentForInsecureIntentHandling ->
Some IssueType.insecure_intent_handling
| IntentFromURI, StartComponent ->
(* create an intent/start a component using a (possibly user-controlled) URI. may or may not
@ -607,7 +621,7 @@ include Trace.Make (struct
| Other, _ | _, Other ->
(* for testing purposes, Other matches everything *)
Some IssueType.quandary_taint_error
| (DrawableResource _ | IntentForInsecureIntentHandling | IntentFromURI | PrivateData), _
| (DrawableResource _ | IntentForInsecureIntentHandling _ | IntentFromURI | PrivateData), _
| _, (Logging | OpenDrawableResource | StartComponent | StartComponentForInsecureIntentHandling)
->
None

@ -478,7 +478,8 @@ module Make (TaintSpecification : TaintSpec.S) = struct
if Var.is_global var then
let dummy_call_site = CallSite.make BuiltinDecl.__global_access loc in
let sources =
TraceDomain.Source.get dummy_call_site
let caller_pname = Procdesc.get_proc_name proc_data.ProcData.pdesc in
TraceDomain.Source.get ~caller_pname dummy_call_site
[HilExp.AccessExpression access_expr]
proc_data.tenv
in
@ -645,7 +646,10 @@ module Make (TaintSpecification : TaintSpec.S) = struct
add_sink sink actuals astate proc_data call_site )
in
let astate_with_direct_sources =
let sources = TraceDomain.Source.get call_site actuals proc_data.tenv in
let sources =
let caller_pname = Procdesc.get_proc_name proc_data.ProcData.pdesc in
TraceDomain.Source.get ~caller_pname call_site actuals proc_data.tenv
in
List.fold sources ~init:astate_with_sink
~f:(fun astate {TraceDomain.Source.source; index} ->
match index with

@ -18,7 +18,7 @@ module MockTrace = Trace.Make (struct
module Source = Source.Make (struct
include MockTraceElem
let get pname _ _ =
let get ~caller_pname:_ pname _ _ =
if String.is_prefix ~prefix:"SOURCE" (Typ.Procname.to_string pname) then
[(CallSite.make pname Location.dummy, None)]
else []

@ -53,7 +53,7 @@ module MockSource = struct
include Source.Make (struct
include MockTraceElem
let get _ _ = assert false
let get ~caller_pname:_ _ _ = assert false
let get_tainted_formals _ = assert false
end)

Loading…
Cancel
Save