[quandary] check for subclassing in externally specified sources/sinks

Reviewed By: jeremydubreil

Differential Revision: D7221876

fbshipit-source-id: 682900e
master
Sam Blackshear 7 years ago committed by Facebook Github Bot
parent 12be484431
commit d720eb52ba

@ -63,6 +63,15 @@ module SourceKind = struct
let get pname actuals tenv =
let return = None in
let get_external_source class_name method_name =
(* check the list of externally specified sources *)
let procedure = class_name ^ "." ^ method_name in
List.find_map
~f:(fun (procedure_regex, kind) ->
if Str.string_match procedure_regex procedure 0 then Some (of_string kind, return)
else None )
external_sources
in
match pname with
| Typ.Procname.Java pname -> (
match (Typ.Procname.Java.get_class_name pname, Typ.Procname.Java.get_method pname) with
@ -102,24 +111,11 @@ module SourceKind = struct
Some (UserControlledString, return)
| "android.widget.EditText", "getText" ->
Some (UserControlledString, return)
| _ ->
None
| class_name, method_name ->
get_external_source class_name method_name
in
let kind_opt =
PatternMatch.supertype_find_map_opt tenv taint_matching_supertype
(Typ.Name.Java.from_string class_name)
in
match kind_opt with
| Some _ ->
kind_opt
| None ->
(* check the list of externally specified sources *)
let procedure = class_name ^ "." ^ method_name in
List.find_map
~f:(fun (procedure_regex, kind) ->
if Str.string_match procedure_regex procedure 0 then Some (of_string kind, return)
else None )
external_sources )
(Typ.Name.Java.from_string class_name) )
| Typ.Procname.C _ when Typ.Procname.equal pname BuiltinDecl.__global_access -> (
match (* accessed global will be passed to us as the only parameter *)
actuals with
@ -335,6 +331,22 @@ module SinkKind = struct
if first_index < List.length actuals then Some (kind, IntSet.singleton first_index)
else None
in
let get_external_sink class_name method_name =
(* check the list of externally specified sinks *)
let procedure = class_name ^ "." ^ method_name in
List.find_map
~f:(fun (procedure_regex, kind, index) ->
if Str.string_match procedure_regex procedure 0 then
let kind = of_string kind in
try
let n = int_of_string index in
taint_nth n kind
with Failure _ ->
(* couldn't parse the index, just taint everything *)
taint_all kind
else None )
external_sinks
in
match
(Typ.Procname.Java.get_class_name java_pname, Typ.Procname.Java.get_method java_pname)
with
@ -407,20 +419,7 @@ module SinkKind = struct
| "java.lang.Runtime", "exec" ->
taint_nth 0 ShellExec
| class_name, method_name ->
(* check the list of externally specified sinks *)
let procedure = class_name ^ "." ^ method_name in
List.find_map
~f:(fun (procedure_regex, kind, index) ->
if Str.string_match procedure_regex procedure 0 then
let kind = of_string kind in
try
let n = int_of_string index in
taint_nth n kind
with Failure _ ->
(* couldn't parse the index, just taint everything *)
taint_all kind
else None )
external_sinks
get_external_sink class_name method_name
in
PatternMatch.supertype_find_map_opt tenv taint_matching_supertype
(Typ.Name.Java.from_string class_name) )

@ -4,6 +4,10 @@
{
"procedure": "codetoanalyze.java.quandary.ExternalSpecs.privateData*",
"kind": "PrivateData"
},
{
"procedure": "codetoanalyze.java.quandary.InterfaceSpec.source",
"kind": "PrivateData"
}
],
"quandary-sinks": [
@ -19,6 +23,10 @@
{
"procedure": "codetoanalyze.java.quandary.ExternalSpecs.sinkThatPropagates",
"kind": "Logging"
},
{
"procedure": "codetoanalyze.java.quandary.InterfaceSpec.sink",
"kind": "Logging"
}
],
"quandary-sanitizers": [

@ -125,3 +125,28 @@ public class ExternalSpecs {
}
}
interface InterfaceSpec {
// marked as source in .inferconfig
public Object source();
// marked as sink in .inferconfig
public void sink(Object o);
}
class InterfaceSpecImpl implements InterfaceSpec {
@Override
public Object source() {
return null;
}
@Override
public void sink(Object o) {}
public void externalSpecBad() {
sink(source());
}
}

@ -50,6 +50,7 @@ codetoanalyze/java/quandary/ExternalSpecs.java, void ExternalSpecs.callExternalS
codetoanalyze/java/quandary/ExternalSpecs.java, void ExternalSpecs.callSinkThatPropagatesBad(), 2, QUANDARY_TAINT_ERROR, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to Object ExternalSpecs.sinkThatPropagates(Object) with tainted index 0]
codetoanalyze/java/quandary/ExternalSpecs.java, void ExternalSpecs.callSinkThatPropagatesBad(), 3, QUANDARY_TAINT_ERROR, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void ExternalSpecs.loggingSink1(Object,Object) with tainted index 1]
codetoanalyze/java/quandary/ExternalSpecs.java, void ExternalSpecs.logExternalSourceBad(), 1, LOGGING_PRIVATE_DATA, ERROR, [Return from Object ExternalSpecs.privateDataSource(),Call to int Log.e(String,String) with tainted index 1]
codetoanalyze/java/quandary/ExternalSpecs.java, void InterfaceSpecImpl.externalSpecBad(), 1, LOGGING_PRIVATE_DATA, ERROR, [Return from Object InterfaceSpecImpl.source(),Call to void InterfaceSpecImpl.sink(Object) with tainted index 1]
codetoanalyze/java/quandary/Fields.java, void Fields.instanceFieldBad(), 2, QUANDARY_TAINT_ERROR, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0]
codetoanalyze/java/quandary/Fields.java, void Fields.staticFieldBad(), 2, QUANDARY_TAINT_ERROR, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0]
codetoanalyze/java/quandary/Fields.java, void Fields.viaFieldBad1(Fields$Obj), 2, QUANDARY_TAINT_ERROR, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0]

Loading…
Cancel
Save