[quandary] allow sinks to be specified in inferconfig

Reviewed By: jberdine

Differential Revision: D4464461

fbshipit-source-id: 1b0359d
master
Sam Blackshear 8 years ago committed by Facebook Github Bot
parent 5bddb1e548
commit f372b6cb2f

@ -1009,6 +1009,9 @@ and progress_bar =
and quandary_sources =
CLOpt.mk_json ~long:"quandary-sources" "Specify custom sources for Quandary"
and quandary_sinks =
CLOpt.mk_json ~long:"quandary-sinks" "Specify custom sinks for Quandary"
and quiet =
CLOpt.mk_bool ~long:"quiet" ~short:"q" ~default:(current_exe <> CLOpt.Print)
~exes:CLOpt.[Print]
@ -1479,6 +1482,7 @@ and procs_csv = !procs_csv
and procs_xml = !procs_xml
and quandary = !quandary
and quandary_sources = !quandary_sources
and quandary_sinks = !quandary_sinks
and quiet = !quiet
and reactive_mode = !reactive
and reactive_capture = !reactive_capture

@ -243,6 +243,7 @@ val procs_xml : string option
val project_root : string
val quandary : bool
val quandary_sources : Yojson.Basic.json
val quandary_sinks : Yojson.Basic.json
val quiet : bool
val reactive_mode : bool
val reactive_capture : bool

@ -139,6 +139,14 @@ module SinkKind = struct
| Other (** for testing or uncategorized sinks *)
[@@deriving compare]
let of_string = function
| "Intent" -> Intent
| "JavaScript" -> JavaScript
| "Logging" -> Logging
| _ -> Other
let external_sinks = QuandaryConfig.Sink.of_json Config.quandary_sinks
let get pname actuals tenv =
(* taint all the inputs of [pname]. for non-static procedures, taints the "this" parameter only
if [taint_this] is true. *)
@ -223,8 +231,23 @@ module SinkKind = struct
| "android.webkit.WebViewClient",
("onLoadResource" | "shouldInterceptRequest" | "shouldOverrideUrlLoading") ->
Some (taint_all JavaScript ~report_reachable:true)
| _ ->
None in
| class_name, method_name ->
(* check the list of externally specified sinks *)
let procedure = class_name ^ "." ^ method_name in
IList.find_map_opt
(fun (sink_spec : QuandaryConfig.Sink.t) ->
if String.equal sink_spec.procedure procedure
then
let kind = of_string sink_spec.kind in
try
let n = int_of_string sink_spec.index in
Some (taint_nth n kind ~report_reachable:true)
with Failure _ ->
(* couldn't parse the index, just taint everything *)
Some (taint_all kind ~report_reachable:true)
else
None)
external_sinks in
begin
match
PatternMatch.supertype_find_map_opt

@ -11,7 +11,7 @@ open! IStd
module F = Format
(** utilities for importing JSON specifications of sources/sinks into Quandary*)
(** utilities for importing JSON specifications of sources/sinks into Quandary *)
module Source = struct
type t = { procedure : string; kind : string; }
@ -30,3 +30,22 @@ module Source = struct
let pp fmt { procedure; kind; } =
F.fprintf fmt "Procedure: %s Kind: %s" procedure kind
end
module Sink = struct
type t = { procedure : string; kind : string; index : string}
let of_json = function
| `List sinks ->
let parse_sink json =
let open Yojson.Basic.Util in
let procedure = json |> member "procedure" |> to_string in
let kind = json |> member "kind" |> to_string in
let index = json |> member "index" |> to_string in
{ procedure; kind; index; } in
IList.map parse_sink sinks
| _ ->
[]
let pp fmt { procedure; kind; index; } =
F.fprintf fmt "Procedure: %s Kind: %s Index %s" procedure kind index
end

@ -18,3 +18,11 @@ module Source : sig
val pp : Format.formatter -> t -> unit
end
module Sink : sig
type t = { procedure : string; kind : string; index : string; }
val of_json : [> `List of Yojson.Basic.json list ] -> t list
val pp : Format.formatter -> t -> unit
end

@ -4,5 +4,17 @@
"procedure": "codetoanalyze.java.quandary.ExternalSpecs.privateDataSource",
"kind": "PrivateData"
}
],
"quandary-sinks": [
{
"procedure": "codetoanalyze.java.quandary.ExternalSpecs.loggingSink1",
"kind": "Logging",
"index": "1"
},
{
"procedure": "codetoanalyze.java.quandary.ExternalSpecs.loggingSink2",
"kind": "Logging",
"index": "all"
}
]
}

@ -34,4 +34,37 @@ public class ExternalSpecs {
activity.startActivity((Intent) privateDataSource());
}
// we specify that index 1 is an external sink with type Logging in .inferconfig
public static void loggingSink1(Object notASink, Object sink) {}
public static void callExternalSinkBad() {
loggingSink1(null, privateDataSource());
}
// passing to non-tainted param
public static void callExternalSinkOk1() {
loggingSink1(privateDataSource(), null);
}
// passing intent source to logging sink is fine
public static void callExternalSinkOk2(Activity activity) {
loggingSink1(null, activity.getIntent());
}
// we specify that all the indices are tainted with type Logging in .inferconfig
public static void loggingSink2(Object sink1, Object sink2) {}
public static void callExternalSink2Bad1() {
loggingSink2(privateDataSource(), null);
}
public static void callExternalSink2Bad2() {
loggingSink2(null, privateDataSource());
}
// passing intent sources to logging sink is fine
public static void callExternalSink2Ok(Activity activity) {
loggingSink2(activity.getIntent(), activity.getIntent());
}
}

@ -43,6 +43,9 @@ codetoanalyze/java/quandary/Exceptions.java, void Exceptions.sinkInCatchBad2(),
codetoanalyze/java/quandary/Exceptions.java, void Exceptions.sinkInFinallyBad1(), 5, QUANDARY_TAINT_ERROR, [return from Object InferTaint.inferSecretSource(),call to void InferTaint.inferSensitiveSink(Object)]
codetoanalyze/java/quandary/Exceptions.java, void Exceptions.sinkInFinallyBad2(), 6, QUANDARY_TAINT_ERROR, [return from Object InferTaint.inferSecretSource(),call to void InferTaint.inferSensitiveSink(Object)]
codetoanalyze/java/quandary/Exceptions.java, void Exceptions.sinkInFinallyBad3(), 7, QUANDARY_TAINT_ERROR, [return from Object InferTaint.inferSecretSource(),call to void InferTaint.inferSensitiveSink(Object)]
codetoanalyze/java/quandary/ExternalSpecs.java, void ExternalSpecs.callExternalSink2Bad1(), 1, QUANDARY_TAINT_ERROR, [return from Object ExternalSpecs.privateDataSource(),call to void ExternalSpecs.loggingSink2(Object,Object)]
codetoanalyze/java/quandary/ExternalSpecs.java, void ExternalSpecs.callExternalSink2Bad2(), 1, QUANDARY_TAINT_ERROR, [return from Object ExternalSpecs.privateDataSource(),call to void ExternalSpecs.loggingSink2(Object,Object)]
codetoanalyze/java/quandary/ExternalSpecs.java, void ExternalSpecs.callExternalSinkBad(), 1, QUANDARY_TAINT_ERROR, [return from Object ExternalSpecs.privateDataSource(),call to void ExternalSpecs.loggingSink1(Object,Object)]
codetoanalyze/java/quandary/ExternalSpecs.java, void ExternalSpecs.logExternalSourceBad(), 1, QUANDARY_TAINT_ERROR, [return from Object ExternalSpecs.privateDataSource(),call to int Log.e(String,String)]
codetoanalyze/java/quandary/Fields.java, void Fields.instanceFieldBad(), 2, QUANDARY_TAINT_ERROR, [return from Object InferTaint.inferSecretSource(),call to void InferTaint.inferSensitiveSink(Object)]
codetoanalyze/java/quandary/Fields.java, void Fields.staticFieldBad(), 2, QUANDARY_TAINT_ERROR, [return from Object InferTaint.inferSecretSource(),call to void InferTaint.inferSensitiveSink(Object)]

Loading…
Cancel
Save