[quandary] simplify source/sink matching

Reviewed By: chenguangshen

Differential Revision: D7691508

fbshipit-source-id: 418faf3
master
Sam Blackshear 7 years ago committed by Facebook Github Bot
parent 033928f716
commit cbc793be16

@ -73,51 +73,51 @@ module SourceKind = struct
external_sources external_sources
in in
match pname with match pname with
| Typ.Procname.Java pname -> ( | Typ.Procname.Java pname ->
match (Typ.Procname.Java.get_class_name pname, Typ.Procname.Java.get_method pname) with let method_name = Typ.Procname.Java.get_method pname in
| "android.content.Intent", "<init>" when actual_has_type 2 "android.net.Uri" actuals tenv -> let taint_matching_supertype typename =
(* taint the [this] parameter passed to the constructor *) match (Typ.Name.name typename, method_name) with
Some (IntentFromURI, Some 0) | "android.app.Activity", "getIntent" ->
| ( "android.content.Intent" Some (Intent, return)
, ( "parseUri" | "android.content.Intent", "<init>"
| "setData" when actual_has_type 2 "android.net.Uri" actuals tenv ->
| "setDataAndNormalize" (* taint the [this] parameter passed to the constructor *)
| "setDataAndType" Some (IntentFromURI, Some 0)
| "setDataAndTypeAndNormalize" ) ) -> | ( "android.content.Intent"
Some (IntentFromURI, return) , ( "parseUri"
| ( "android.location.Location" | "setData"
, ("getAltitude" | "getBearing" | "getLatitude" | "getLongitude" | "getSpeed") ) -> | "setDataAndNormalize"
Some (PrivateData, return) | "setDataAndType"
| ( "android.telephony.TelephonyManager" | "setDataAndTypeAndNormalize" ) ) ->
, ( "getDeviceId" Some (IntentFromURI, return)
| "getLine1Number" | "android.content.Intent", "getStringExtra" ->
| "getSimSerialNumber" Some (Intent, return)
| "getSubscriberId" | "android.content.SharedPreferences", "getString" ->
| "getVoiceMailNumber" ) ) -> Some (PrivateData, return)
Some (PrivateData, return) | ( ("android.content.ClipboardManager" | "android.text.ClipboardManager")
| "com.facebook.infer.builtins.InferTaint", "inferSecretSource" -> , ("getPrimaryClip" | "getText") ) ->
Some (Other, return) Some (UserControlledString, return)
| class_name, method_name -> | ( "android.location.Location"
let taint_matching_supertype typename = , ("getAltitude" | "getBearing" | "getLatitude" | "getLongitude" | "getSpeed") ) ->
match (Typ.Name.name typename, method_name) with Some (PrivateData, return)
| "android.app.Activity", "getIntent" -> | ( "android.telephony.TelephonyManager"
Some (Intent, return) , ( "getDeviceId"
| "android.content.Intent", "getStringExtra" -> | "getLine1Number"
Some (Intent, return) | "getSimSerialNumber"
| "android.content.SharedPreferences", "getString" -> | "getSubscriberId"
Some (PrivateData, return) | "getVoiceMailNumber" ) ) ->
| ( ("android.content.ClipboardManager" | "android.text.ClipboardManager") Some (PrivateData, return)
, ("getPrimaryClip" | "getText") ) -> | "android.webkit.WebResourceRequest", "getUrl" ->
Some (UserControlledString, return) Some (UserControlledURI, return)
| "android.webkit.WebResourceRequest", "getUrl" -> | "android.widget.EditText", "getText" ->
Some (UserControlledURI, return) Some (UserControlledString, return)
| "android.widget.EditText", "getText" -> | "com.facebook.infer.builtins.InferTaint", "inferSecretSource" ->
Some (UserControlledString, return) Some (Other, return)
| class_name, method_name -> | class_name, method_name ->
get_external_source class_name method_name get_external_source class_name method_name
in in
PatternMatch.supertype_find_map_opt tenv taint_matching_supertype PatternMatch.supertype_find_map_opt tenv taint_matching_supertype
(Typ.Name.Java.from_string class_name) ) (Typ.Name.Java.from_string (Typ.Procname.Java.get_class_name pname))
| Typ.Procname.C _ when Typ.Procname.equal pname BuiltinDecl.__global_access -> ( | Typ.Procname.C _ when Typ.Procname.equal pname BuiltinDecl.__global_access -> (
match (* accessed global will be passed to us as the only parameter *) match (* accessed global will be passed to us as the only parameter *)
actuals with actuals with
@ -171,74 +171,68 @@ module SourceKind = struct
in in
let formals = Procdesc.get_formals pdesc in let formals = Procdesc.get_formals pdesc in
match Procdesc.get_proc_name pdesc with match Procdesc.get_proc_name pdesc with
| Typ.Procname.Java java_pname -> ( | Typ.Procname.Java java_pname
match -> (
(Typ.Procname.Java.get_class_name java_pname, Typ.Procname.Java.get_method java_pname) let method_name = Typ.Procname.Java.get_method java_pname in
with let taint_matching_supertype typename =
| "codetoanalyze.java.quandary.TaintedFormals", "taintedContextBad" -> match (Typ.Name.name typename, method_name) with
taint_formals_with_types ["java.lang.Integer"; "java.lang.String"] Other formals | "android.app.Activity", ("onActivityResult" | "onNewIntent") ->
| class_name, method_name -> Some (taint_formals_with_types ["android.content.Intent"] Intent formals)
let taint_matching_supertype typename = | ( "android.app.Service"
match (Typ.Name.name typename, method_name) with , ("onBind" | "onRebind" | "onStart" | "onStartCommand" | "onTaskRemoved" | "onUnbind")
| "android.app.Activity", ("onActivityResult" | "onNewIntent") -> ) ->
Some (taint_formals_with_types ["android.content.Intent"] Intent formals) Some (taint_formals_with_types ["android.content.Intent"] Intent formals)
| ( "android.app.Service" | "android.content.BroadcastReceiver", "onReceive" ->
, ( "onBind" Some (taint_formals_with_types ["android.content.Intent"] Intent formals)
| "onRebind" | ( "android.content.ContentProvider"
| "onStart" , ( "bulkInsert"
| "onStartCommand" | "call"
| "onTaskRemoved" | "delete"
| "onUnbind" ) ) -> | "insert"
Some (taint_formals_with_types ["android.content.Intent"] Intent formals) | "getType"
| "android.content.BroadcastReceiver", "onReceive" -> | "openAssetFile"
Some (taint_formals_with_types ["android.content.Intent"] Intent formals) | "openFile"
| ( "android.content.ContentProvider" | "openPipeHelper"
, ( "bulkInsert" | "openTypedAssetFile"
| "call" | "query"
| "delete" | "refresh"
| "insert" | "update" ) ) ->
| "getType" Some
| "openAssetFile" (taint_formals_with_types ["android.net.Uri"; "java.lang.String"] UserControlledURI
| "openFile" formals)
| "openPipeHelper" | ( "android.webkit.WebChromeClient"
| "openTypedAssetFile" , ("onJsAlert" | "onJsBeforeUnload" | "onJsConfirm" | "onJsPrompt") ) ->
| "query" Some (taint_formals_with_types ["java.lang.String"] UserControlledURI formals)
| "refresh" | ( "android.webkit.WebViewClient"
| "update" ) ) -> , ("onLoadResource" | "shouldInterceptRequest" | "shouldOverrideUrlLoading") ) ->
Some Some
(taint_formals_with_types ["android.net.Uri"; "java.lang.String"] (taint_formals_with_types ["android.webkit.WebResourceRequest"; "java.lang.String"]
UserControlledURI formals) UserControlledURI formals)
| ( "android.webkit.WebViewClient" | "codetoanalyze.java.quandary.TaintedFormals", "taintedContextBad" ->
, ("onLoadResource" | "shouldInterceptRequest" | "shouldOverrideUrlLoading") ) -> Some
Some (taint_formals_with_types ["java.lang.Integer"; "java.lang.String"] Other formals)
(taint_formals_with_types | _ ->
["android.webkit.WebResourceRequest"; "java.lang.String"] UserControlledURI match Tenv.lookup tenv typename with
formals) | Some typ ->
| ( "android.webkit.WebChromeClient" if
, ("onJsAlert" | "onJsBeforeUnload" | "onJsConfirm" | "onJsPrompt") ) -> Annotations.struct_typ_has_annot typ Annotations.ia_is_thrift_service
Some (taint_formals_with_types ["java.lang.String"] UserControlledURI formals) && PredSymb.equal_access (Procdesc.get_access pdesc) PredSymb.Public
then
(* assume every non-this formal of a Thrift service is tainted *)
(* TODO: may not want to taint numbers or Enum's *)
Some (taint_all_but_this ~make_source:(fun name desc -> Endpoint (name, desc)))
else None
| _ -> | _ ->
match Tenv.lookup tenv typename with None
| Some typ -> in
if match
Annotations.struct_typ_has_annot typ Annotations.ia_is_thrift_service PatternMatch.supertype_find_map_opt tenv taint_matching_supertype
&& PredSymb.equal_access (Procdesc.get_access pdesc) PredSymb.Public (Typ.Name.Java.from_string (Typ.Procname.Java.get_class_name java_pname))
then with
(* assume every non-this formal of a Thrift service is tainted *) | Some tainted_formals ->
(* TODO: may not want to taint numbers or Enum's *) tainted_formals
Some (taint_all_but_this ~make_source:(fun name desc -> Endpoint (name, desc))) | None ->
else None Source.all_formals_untainted pdesc )
| _ ->
None
in
match
PatternMatch.supertype_find_map_opt tenv taint_matching_supertype
(Typ.Name.Java.from_string class_name)
with
| Some tainted_formals ->
tainted_formals
| None ->
Source.all_formals_untainted pdesc )
| procname -> | procname ->
L.(die InternalError) L.(die InternalError)
"Non-Java procedure %a where only Java procedures are expected" Typ.Procname.pp procname "Non-Java procedure %a where only Java procedures are expected" Typ.Procname.pp procname
@ -314,8 +308,7 @@ module SinkKind = struct
let get pname actuals _ tenv = let get pname actuals _ tenv =
match pname with match pname with
| Typ.Procname.Java java_pname | Typ.Procname.Java java_pname ->
-> (
(* taint all the inputs of [pname]. for non-static procedures, taints the "this" parameter (* taint all the inputs of [pname]. for non-static procedures, taints the "this" parameter
only if [taint_this] is true. *) only if [taint_this] is true. *)
let taint_all ?(taint_this= false) kind = let taint_all ?(taint_this= false) kind =
@ -350,82 +343,79 @@ module SinkKind = struct
else None ) else None )
external_sinks external_sinks
in in
match let method_name = Typ.Procname.Java.get_method java_pname in
(Typ.Procname.Java.get_class_name java_pname, Typ.Procname.Java.get_method java_pname) let taint_matching_supertype typename =
with match (Typ.Name.name typename, method_name) with
| "android.text.Html", "fromHtml" -> | "android.app.Activity", ("startActivityFromChild" | "startActivityFromFragment") ->
taint_nth 0 HTML taint_nth 1 StartComponent
| "android.util.Log", ("e" | "println" | "w" | "wtf") -> | "android.app.Activity", "startIntentSenderForResult" ->
taint_all Logging taint_nth 2 StartComponent
| "java.io.File", "<init>" | "android.app.Activity", "startIntentSenderFromChild" ->
| "java.nio.file.FileSystem", "getPath" taint_nth 3 StartComponent
| "java.nio.file.Paths", "get" -> | ( "android.content.Context"
taint_all CreateFile , ( "bindService"
| "java.io.ObjectInputStream", "<init>" -> | "sendBroadcast"
taint_all Deserialization | "sendBroadcastAsUser"
| "com.facebook.infer.builtins.InferTaint", "inferSensitiveSink" -> | "sendOrderedBroadcast"
taint_nth 0 Other | "sendOrderedBroadcastAsUser"
| "java.lang.ProcessBuilder", "<init>" -> | "sendStickyBroadcast"
taint_all ShellExec | "sendStickyBroadcastAsUser"
| "java.lang.ProcessBuilder", "command" -> | "sendStickyOrderedBroadcast"
taint_all ShellExec | "sendStickyOrderedBroadcastAsUser"
| class_name, method_name -> | "startActivities"
let taint_matching_supertype typename = | "startActivity"
match (Typ.Name.name typename, method_name) with | "startActivityForResult"
| "android.app.Activity", ("startActivityFromChild" | "startActivityFromFragment") -> | "startActivityIfNeeded"
taint_nth 1 StartComponent | "startNextMatchingActivity"
| "android.app.Activity", "startIntentSenderForResult" -> | "startService"
taint_nth 2 StartComponent | "stopService" ) ) ->
| "android.app.Activity", "startIntentSenderFromChild" -> taint_nth 0 StartComponent
taint_nth 3 StartComponent | "android.content.Context", "startIntentSender" ->
| ( "android.content.Context" taint_nth 1 StartComponent
, ( "bindService" | ( "android.content.Intent"
| "sendBroadcast" , ( "parseUri"
| "sendBroadcastAsUser" | "getIntent"
| "sendOrderedBroadcast" | "getIntentOld"
| "sendOrderedBroadcastAsUser" | "setComponent"
| "sendStickyBroadcast" | "setData"
| "sendStickyBroadcastAsUser" | "setDataAndNormalize"
| "sendStickyOrderedBroadcast" | "setDataAndType"
| "sendStickyOrderedBroadcastAsUser" | "setDataAndTypeAndNormalize"
| "startActivities" | "setPackage" ) ) ->
| "startActivity" taint_nth 0 CreateIntent
| "startActivityForResult" | "android.content.Intent", "setClassName" ->
| "startActivityIfNeeded" taint_all CreateIntent
| "startNextMatchingActivity" | "android.text.Html", "fromHtml" ->
| "startService" taint_nth 0 HTML
| "stopService" ) ) -> | "android.util.Log", ("e" | "println" | "w" | "wtf") ->
taint_nth 0 StartComponent taint_all Logging
| "android.content.Context", "startIntentSender" -> | ( "android.webkit.WebView"
taint_nth 1 StartComponent , ( "evaluateJavascript"
| ( "android.content.Intent" | "loadData"
, ( "parseUri" | "loadDataWithBaseURL"
| "getIntent" | "loadUrl"
| "getIntentOld" | "postUrl"
| "setComponent" | "postWebMessage" ) ) ->
| "setData" taint_all JavaScript
| "setDataAndNormalize" | "com.facebook.infer.builtins.InferTaint", "inferSensitiveSink" ->
| "setDataAndType" taint_nth 0 Other
| "setDataAndTypeAndNormalize" | "java.io.File", "<init>"
| "setPackage" ) ) -> | "java.nio.file.FileSystem", "getPath"
taint_nth 0 CreateIntent | "java.nio.file.Paths", "get" ->
| "android.content.Intent", "setClassName" -> taint_all CreateFile
taint_all CreateIntent | "java.io.ObjectInputStream", "<init>" ->
| ( "android.webkit.WebView" taint_all Deserialization
, ( "evaluateJavascript" | "java.lang.ProcessBuilder", "<init>" ->
| "loadData" taint_all ShellExec
| "loadDataWithBaseURL" | "java.lang.ProcessBuilder", "command" ->
| "loadUrl" taint_all ShellExec
| "postUrl" | "java.lang.Runtime", "exec" ->
| "postWebMessage" ) ) -> taint_nth 0 ShellExec
taint_all JavaScript | class_name, method_name ->
| "java.lang.Runtime", "exec" -> get_external_sink class_name method_name
taint_nth 0 ShellExec in
| class_name, method_name -> PatternMatch.supertype_find_map_opt tenv taint_matching_supertype
get_external_sink class_name method_name (Typ.Name.Java.from_string (Typ.Procname.Java.get_class_name java_pname))
in
PatternMatch.supertype_find_map_opt tenv taint_matching_supertype
(Typ.Name.Java.from_string class_name) )
| pname when BuiltinDecl.is_declared pname -> | pname when BuiltinDecl.is_declared pname ->
None None
| pname -> | pname ->

Loading…
Cancel
Save