|
|
@ -14,17 +14,19 @@ module L = Logging
|
|
|
|
|
|
|
|
|
|
|
|
module SourceKind = struct
|
|
|
|
module SourceKind = struct
|
|
|
|
type t =
|
|
|
|
type t =
|
|
|
|
| PrivateData (** private user or device-specific data *)
|
|
|
|
| Intent (** external Intent or a value read from one *)
|
|
|
|
| Intent
|
|
|
|
|
|
|
|
| Other (** for testing or uncategorized sources *)
|
|
|
|
| Other (** for testing or uncategorized sources *)
|
|
|
|
|
|
|
|
| PrivateData (** private user or device-specific data *)
|
|
|
|
|
|
|
|
| WebviewUrl (** external URL passed to a WebView *)
|
|
|
|
| Unknown
|
|
|
|
| Unknown
|
|
|
|
[@@deriving compare]
|
|
|
|
[@@deriving compare]
|
|
|
|
|
|
|
|
|
|
|
|
let unknown = Unknown
|
|
|
|
let unknown = Unknown
|
|
|
|
|
|
|
|
|
|
|
|
let of_string = function
|
|
|
|
let of_string = function
|
|
|
|
| "PrivateData" -> PrivateData
|
|
|
|
|
|
|
|
| "Intent" -> Intent
|
|
|
|
| "Intent" -> Intent
|
|
|
|
|
|
|
|
| "PrivateData" -> PrivateData
|
|
|
|
|
|
|
|
| "WebviewUrl" -> WebviewUrl
|
|
|
|
| _ -> Other
|
|
|
|
| _ -> Other
|
|
|
|
|
|
|
|
|
|
|
|
let external_sources = QuandaryConfig.Source.of_json Config.quandary_sources
|
|
|
|
let external_sources = QuandaryConfig.Source.of_json Config.quandary_sources
|
|
|
@ -113,11 +115,11 @@ module SourceKind = struct
|
|
|
|
Some
|
|
|
|
Some
|
|
|
|
(taint_formals_with_types
|
|
|
|
(taint_formals_with_types
|
|
|
|
["android.webkit.WebResourceRequest"; "java.lang.String"]
|
|
|
|
["android.webkit.WebResourceRequest"; "java.lang.String"]
|
|
|
|
Intent
|
|
|
|
WebviewUrl
|
|
|
|
formals)
|
|
|
|
formals)
|
|
|
|
| "android.webkit.WebChromeClient",
|
|
|
|
| "android.webkit.WebChromeClient",
|
|
|
|
("onJsAlert" | "onJsBeforeUnload" | "onJsConfirm" | "onJsPrompt") ->
|
|
|
|
("onJsAlert" | "onJsBeforeUnload" | "onJsConfirm" | "onJsPrompt") ->
|
|
|
|
Some (taint_formals_with_types ["java.lang.String"] Intent formals)
|
|
|
|
Some (taint_formals_with_types ["java.lang.String"] WebviewUrl formals)
|
|
|
|
| _ ->
|
|
|
|
| _ ->
|
|
|
|
None in
|
|
|
|
None in
|
|
|
|
begin
|
|
|
|
begin
|
|
|
@ -135,27 +137,31 @@ module SourceKind = struct
|
|
|
|
"Non-Java procedure %a where only Java procedures are expected"
|
|
|
|
"Non-Java procedure %a where only Java procedures are expected"
|
|
|
|
Typ.Procname.pp procname
|
|
|
|
Typ.Procname.pp procname
|
|
|
|
|
|
|
|
|
|
|
|
let pp fmt = function
|
|
|
|
let pp fmt kind =
|
|
|
|
| Intent -> F.fprintf fmt "Intent"
|
|
|
|
F.fprintf fmt
|
|
|
|
| PrivateData -> F.fprintf fmt "PrivateData"
|
|
|
|
(match kind with
|
|
|
|
| Other -> F.fprintf fmt "Other"
|
|
|
|
| Intent -> "Intent"
|
|
|
|
| Unknown -> F.fprintf fmt "Unknown"
|
|
|
|
| WebviewUrl -> "WebviewUrl"
|
|
|
|
|
|
|
|
| PrivateData -> "PrivateData"
|
|
|
|
|
|
|
|
| Other -> "Other"
|
|
|
|
|
|
|
|
| Unknown -> "Unknown")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
module JavaSource = Source.Make(SourceKind)
|
|
|
|
module JavaSource = Source.Make(SourceKind)
|
|
|
|
|
|
|
|
|
|
|
|
module SinkKind = struct
|
|
|
|
module SinkKind = struct
|
|
|
|
type t =
|
|
|
|
type t =
|
|
|
|
| Intent (** sink that trusts an Intent *)
|
|
|
|
| CreateIntent (** sink that creates an Intent *)
|
|
|
|
| JavaScript (** sink that passes its arguments to untrusted JS code *)
|
|
|
|
| JavaScript (** sink that passes its arguments to untrusted JS code *)
|
|
|
|
| Logging (** sink that logs one or more of its arguments *)
|
|
|
|
| Logging (** sink that logs one or more of its arguments *)
|
|
|
|
|
|
|
|
| StartComponent (** sink that launches an Activity, Service, etc. *)
|
|
|
|
| Other (** for testing or uncategorized sinks *)
|
|
|
|
| Other (** for testing or uncategorized sinks *)
|
|
|
|
[@@deriving compare]
|
|
|
|
[@@deriving compare]
|
|
|
|
|
|
|
|
|
|
|
|
let of_string = function
|
|
|
|
let of_string = function
|
|
|
|
| "Intent" -> Intent
|
|
|
|
|
|
|
|
| "JavaScript" -> JavaScript
|
|
|
|
| "JavaScript" -> JavaScript
|
|
|
|
| "Logging" -> Logging
|
|
|
|
| "Logging" -> Logging
|
|
|
|
|
|
|
|
| "StartComponent" -> StartComponent
|
|
|
|
| _ -> Other
|
|
|
|
| _ -> Other
|
|
|
|
|
|
|
|
|
|
|
|
let external_sinks = QuandaryConfig.Sink.of_json Config.quandary_sinks
|
|
|
|
let external_sinks = QuandaryConfig.Sink.of_json Config.quandary_sinks
|
|
|
@ -188,11 +194,11 @@ module SinkKind = struct
|
|
|
|
match Typ.Name.name typename, method_name with
|
|
|
|
match Typ.Name.name typename, method_name with
|
|
|
|
| "android.app.Activity",
|
|
|
|
| "android.app.Activity",
|
|
|
|
("startActivityFromChild" | "startActivityFromFragment") ->
|
|
|
|
("startActivityFromChild" | "startActivityFromFragment") ->
|
|
|
|
Some (taint_nth 1 Intent ~report_reachable:true)
|
|
|
|
Some (taint_nth 1 StartComponent ~report_reachable:true)
|
|
|
|
| "android.app.Activity", "startIntentSenderForResult" ->
|
|
|
|
| "android.app.Activity", "startIntentSenderForResult" ->
|
|
|
|
Some (taint_nth 2 Intent ~report_reachable:true)
|
|
|
|
Some (taint_nth 2 StartComponent ~report_reachable:true)
|
|
|
|
| "android.app.Activity", "startIntentSenderFromChild" ->
|
|
|
|
| "android.app.Activity", "startIntentSenderFromChild" ->
|
|
|
|
Some (taint_nth 3 Intent ~report_reachable:true)
|
|
|
|
Some (taint_nth 3 StartComponent ~report_reachable:true)
|
|
|
|
| "android.content.Context",
|
|
|
|
| "android.content.Context",
|
|
|
|
("bindService" |
|
|
|
|
("bindService" |
|
|
|
|
"sendBroadcast" |
|
|
|
|
"sendBroadcast" |
|
|
|
@ -210,9 +216,9 @@ module SinkKind = struct
|
|
|
|
"startNextMatchingActivity" |
|
|
|
|
"startNextMatchingActivity" |
|
|
|
|
"startService" |
|
|
|
|
"startService" |
|
|
|
|
"stopService") ->
|
|
|
|
"stopService") ->
|
|
|
|
Some (taint_nth 0 Intent ~report_reachable:true)
|
|
|
|
Some (taint_nth 0 StartComponent ~report_reachable:true)
|
|
|
|
| "android.content.Context", "startIntentSender" ->
|
|
|
|
| "android.content.Context", "startIntentSender" ->
|
|
|
|
Some (taint_nth 1 Intent ~report_reachable:true)
|
|
|
|
Some (taint_nth 1 StartComponent ~report_reachable:true)
|
|
|
|
| "android.content.Intent",
|
|
|
|
| "android.content.Intent",
|
|
|
|
("parseUri" |
|
|
|
|
("parseUri" |
|
|
|
|
"getIntent" |
|
|
|
|
"getIntent" |
|
|
|
@ -223,9 +229,9 @@ module SinkKind = struct
|
|
|
|
"setDataAndType" |
|
|
|
|
"setDataAndType" |
|
|
|
|
"setDataAndTypeAndNormalize" |
|
|
|
|
"setDataAndTypeAndNormalize" |
|
|
|
|
"setPackage") ->
|
|
|
|
"setPackage") ->
|
|
|
|
Some (taint_nth 0 Intent ~report_reachable:true)
|
|
|
|
Some (taint_nth 0 CreateIntent ~report_reachable:true)
|
|
|
|
| "android.content.Intent", "setClassName" ->
|
|
|
|
| "android.content.Intent", "setClassName" ->
|
|
|
|
Some (taint_all Intent ~report_reachable:true)
|
|
|
|
Some (taint_all CreateIntent ~report_reachable:true)
|
|
|
|
| "android.webkit.WebView",
|
|
|
|
| "android.webkit.WebView",
|
|
|
|
("evaluateJavascript" |
|
|
|
|
("evaluateJavascript" |
|
|
|
|
"loadData" |
|
|
|
|
"loadData" |
|
|
|
@ -264,11 +270,14 @@ module SinkKind = struct
|
|
|
|
| pname when BuiltinDecl.is_declared pname -> []
|
|
|
|
| pname when BuiltinDecl.is_declared pname -> []
|
|
|
|
| pname -> failwithf "Non-Java procname %a in Java analysis@." Typ.Procname.pp pname
|
|
|
|
| pname -> failwithf "Non-Java procname %a in Java analysis@." Typ.Procname.pp pname
|
|
|
|
|
|
|
|
|
|
|
|
let pp fmt = function
|
|
|
|
let pp fmt kind =
|
|
|
|
| Intent -> F.fprintf fmt "Intent"
|
|
|
|
F.fprintf fmt
|
|
|
|
| JavaScript -> F.fprintf fmt "JavaScript"
|
|
|
|
(match kind with
|
|
|
|
| Logging -> F.fprintf fmt "Logging"
|
|
|
|
| CreateIntent -> "CreateIntent"
|
|
|
|
| Other -> F.fprintf fmt "Other"
|
|
|
|
| JavaScript -> "JavaScript"
|
|
|
|
|
|
|
|
| Logging -> "Logging"
|
|
|
|
|
|
|
|
| StartComponent -> "StartComponent"
|
|
|
|
|
|
|
|
| Other -> "Other")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
module JavaSink = Sink.Make(SinkKind)
|
|
|
|
module JavaSink = Sink.Make(SinkKind)
|
|
|
@ -280,10 +289,14 @@ include
|
|
|
|
|
|
|
|
|
|
|
|
let should_report source sink =
|
|
|
|
let should_report source sink =
|
|
|
|
match Source.kind source, Sink.kind sink with
|
|
|
|
match Source.kind source, Sink.kind sink with
|
|
|
|
| PrivateData, Logging
|
|
|
|
| PrivateData, Logging (* logging private data issue *)
|
|
|
|
| Intent, Intent
|
|
|
|
| Intent, StartComponent (* intent reuse issue *)
|
|
|
|
| (Intent | PrivateData), JavaScript
|
|
|
|
| Intent, CreateIntent (* intent configured with external values issue *)
|
|
|
|
| Other, _ | _, Other ->
|
|
|
|
| Intent, JavaScript (* external data flows into JS: remote code execution risk *)
|
|
|
|
|
|
|
|
| WebviewUrl, (CreateIntent | StartComponent)
|
|
|
|
|
|
|
|
(* create intent/launch component from external URL *)
|
|
|
|
|
|
|
|
| PrivateData, JavaScript (* leaking private data into JS *)
|
|
|
|
|
|
|
|
| Other, _ | _, Other -> (* for testing purposes, Other matches everything *)
|
|
|
|
true
|
|
|
|
true
|
|
|
|
| _ ->
|
|
|
|
| _ ->
|
|
|
|
false
|
|
|
|
false
|
|
|
|