diff --git a/infer/bin/inferlib.py b/infer/bin/inferlib.py index 2bf42f2f5..3465000d5 100644 --- a/infer/bin/inferlib.py +++ b/infer/bin/inferlib.py @@ -286,8 +286,9 @@ def should_report(analyzer, row): 'ASSERTION_FAILURE', 'CONTEXT_LEAK', 'BAD_POINTER_COMPARISON', - 'STRONG_DELEGATE_WARNING' - #'CHECKERS_PRINTF_ARGS' + 'TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION', + 'STRONG_DELEGATE_WARNING', + # 'CHECKERS_PRINTF_ARGS' # TODO (#8030397): revert this once all the checkers are moved to Infer ] diff --git a/infer/models/java/src/com/facebook/infer/models/InferBuiltins.java b/infer/models/java/src/com/facebook/infer/models/InferBuiltins.java index f6df8ac47..e1f743405 100644 --- a/infer/models/java/src/com/facebook/infer/models/InferBuiltins.java +++ b/infer/models/java/src/com/facebook/infer/models/InferBuiltins.java @@ -28,4 +28,8 @@ public class InferBuiltins { public native static String __split_get_nth(String s, String sep, int n); + public native static void __set_taint_attribute(Object o); + public native static void __set_untaint_attribute(Object o); + public native static boolean __state_untainted(Object o); + } diff --git a/infer/models/java/src/java/lang/String.java b/infer/models/java/src/java/lang/String.java index 6b5705211..9600fa733 100644 --- a/infer/models/java/src/java/lang/String.java +++ b/infer/models/java/src/java/lang/String.java @@ -10,6 +10,7 @@ package java.lang; import com.facebook.infer.models.InferUndefined; +import com.facebook.infer.models.InferBuiltins; public final class String { @@ -55,7 +56,22 @@ public final class String { public boolean equals(Object anObject) { + InferBuiltins.assume(!InferBuiltins.__state_untainted(anObject)); return this == anObject; } + public int compareTo(String aString) { + InferBuiltins.assume(!InferBuiltins.__state_untainted(aString)); + return InferUndefined.nonneg_int(); + } + + public boolean endsWith(String aString) { + InferBuiltins.assume(!InferBuiltins.__state_untainted(aString)); + return InferUndefined.boolean_undefined(); + } + + public boolean startsWith(String aString) { + InferBuiltins.assume(!InferBuiltins.__state_untainted(aString)); + return InferUndefined.boolean_undefined(); + } } diff --git a/infer/models/java/src/java/net/URL.java b/infer/models/java/src/java/net/URL.java index a5efd916d..90b711aee 100644 --- a/infer/models/java/src/java/net/URL.java +++ b/infer/models/java/src/java/net/URL.java @@ -11,6 +11,7 @@ package java.net; import javax.net.ssl.HttpsURLConnection; import java.util.Hashtable; +import com.facebook.infer.models.InferBuiltins; public final class URL implements java.io.Serializable { @@ -65,4 +66,29 @@ public final class URL implements java.io.Serializable { return openConnection(null); } + String tainted_string() { + String res = new String(); + InferBuiltins.__set_taint_attribute(res); + return res; + } + + public String getHost() { + return tainted_string(); + } + + public String getAuthority() { + return tainted_string(); + } + + public String getProtocol() { + return tainted_string(); + } + + public String toExternalForm() { + return tainted_string(); + } + + public String toString() { + return tainted_string(); + } } diff --git a/infer/src/backend/config.ml b/infer/src/backend/config.ml index 79b431d1e..1ef25d252 100644 --- a/infer/src/backend/config.ml +++ b/infer/src/backend/config.ml @@ -292,7 +292,7 @@ let save_time_in_summaries = ref false let smt_output = ref false (** flag: if true performs taint analysis *) -let taint_analysis = ref false +let taint_analysis = ref true (** set to true to printing tracing information for the analysis *) let trace_anal = ref false diff --git a/infer/src/backend/errdesc.ml b/infer/src/backend/errdesc.ml index 51e4d94cf..5f9b457f3 100644 --- a/infer/src/backend/errdesc.ml +++ b/infer/src/backend/errdesc.ml @@ -969,13 +969,17 @@ let explain_return_expression_required loc typ = pp_to_string pp () in Localise.desc_return_expression_required typ_str loc -(** Explain a tainted value error *) +(** Explain retain cycle value error *) let explain_retain_cycle prop cycle loc = Localise.desc_retain_cycle prop cycle loc (** Explain a tainted value error *) let explain_tainted_value_reaching_sensitive_function e loc = - Localise.desc_tainted_value_reaching_sensitive_function (Sil.exp_to_string e) loc + let var_desc = + match e with + | Sil.Lvar pv -> Sil.pvar_to_string pv + | _ -> " of some parameter " in + Localise.desc_tainted_value_reaching_sensitive_function var_desc loc (** explain a return statement missing *) let explain_return_statement_missing loc = diff --git a/infer/src/backend/exceptions.ml b/infer/src/backend/exceptions.ml index 2fec19012..d9cd3caa3 100644 --- a/infer/src/backend/exceptions.ml +++ b/infer/src/backend/exceptions.ml @@ -210,7 +210,8 @@ let recognize_exception exn = let desc = Localise.verbatim_desc s in (Localise.from_string "Sys_error", desc, None, Exn_system, Low, None, Nocat) | Tainted_value_reaching_sensitive_function (desc, mloc) -> - (Localise.tainted_value_reaching_sensitive_function, desc, Some mloc, Exn_developer, Medium, None, Nocat) + (Localise.tainted_value_reaching_sensitive_function, desc, Some mloc, + Exn_user, Medium, Some Kerror, Nocat) | Unix.Unix_error (_, s1, s2) -> let desc = Localise.verbatim_desc (s1 ^ s2) in (Localise.from_string "Unix_error", desc, None, Exn_system, Low, None, Nocat) diff --git a/infer/src/backend/tabulation.ml b/infer/src/backend/tabulation.ml index a28dd9872..8f2320473 100644 --- a/infer/src/backend/tabulation.ml +++ b/infer/src/backend/tabulation.ml @@ -761,39 +761,47 @@ let inconsistent_actualpre_missing actual_pre split_opt = Prover.check_inconsistency prop'' | None -> false -(* get the taint/untaint info from the pure part*) +(* Collect the taint/untain info on the pi part *) let rec get_taint_untaint pi = + let get_att_exp p e (t,u) = + match Prop.get_taint_attribute p e with + | Some(Sil.Ataint) -> + L.d_str " ---->Found TAINTED exp: "; Sil.d_exp e; L.d_ln (); + (e::t, u) + | Some(Sil.Auntaint) -> + L.d_str " ---->Found UNTAINTED exp: "; Sil.d_exp e; L.d_ln (); + (t, e::u) + | _ -> (t,u) in match pi with | [] -> ([],[]) | Sil.Aneq (e1, e2):: pi' -> - let p = Prop.replace_pi pi Prop.prop_emp in - (match Prop.get_taint_attribute p e1, Prop.get_taint_attribute p e2 with - | Some(Sil.Ataint), _ -> let (t', u') = get_taint_untaint pi' in (e1:: t', u') - | Some(Sil.Auntaint), _ -> let (t', u') = get_taint_untaint pi' in (t', e1:: u') - | _, Some(Sil.Ataint) -> let (t', u') = get_taint_untaint pi' in (e2:: t', u') - | _ , Some(Sil.Auntaint) -> let (t', u') = get_taint_untaint pi' in (t', e2:: u') - | _, _ -> get_taint_untaint pi') + let (t, u) = get_taint_untaint pi' in + let p = Prop.replace_pi [Sil.Aneq (e1, e2)] Prop.prop_emp in + let (t',u') = get_att_exp p e1 (t,u) in + get_att_exp p e2 (t',u') | _ :: pi' -> get_taint_untaint pi' -(* perform the taint analysis check *) -let do_taint_check caller_pname actual_pre missing_pi missing_sigma sub1 sub2 = - let rec intersection_taint_untaint taint untaint = (* note: return the first element in the intersection*) +(* perform the taint analysis check by comparing in a function call the + actual calling state and the missing pi computed by abduction *) +let do_taint_check caller_pname calling_prop missing_pi sub prop = + (* Note: returns only the first element in the intersection*) + let rec intersection_taint_untaint taint untaint = match taint with | [] -> None | e:: taint' -> if (IList.exists (fun e' -> Sil.exp_equal e e') untaint) then (Some e) else intersection_taint_untaint taint' untaint in - let augmented_actual_pre = Prop.replace_pi ((Prop.get_pi actual_pre) @ missing_pi) actual_pre in - let augmented_actual_pre = Prop.replace_sigma ((Prop.get_sigma actual_pre) @ missing_sigma) augmented_actual_pre in - let sub2_augmented_actual_pre = Prop.prop_sub sub2 augmented_actual_pre in - let taint2, untaint2 = get_taint_untaint (Prop.get_pi sub2_augmented_actual_pre) in - L.d_str "^^^^AUGMENTED ACTUAL PRE2: "; Prop.d_prop sub2_augmented_actual_pre; L.d_ln(); - L.d_str "^^^^TAINT2: "; Sil.d_exp_list taint2; L.d_ln (); - L.d_str "^^^^UNTAINT2: "; Sil.d_exp_list untaint2; L.d_ln (); - match intersection_taint_untaint taint2 untaint2 with - | None -> L.d_str "^^^^^^NO TAINT ERROR" + let combined_calling_prop = + Prop.replace_pi ((Prop.get_pi calling_prop) @ missing_pi) calling_prop in + let sub_combined_calling_prop = Prop.prop_sub sub combined_calling_prop in + let taint_set, untaint_set = get_taint_untaint (Prop.get_pi sub_combined_calling_prop) in + L.d_str "Actual pre combined with missing pi: "; Prop.d_prop sub_combined_calling_prop; L.d_ln(); + L.d_str "Taint set: "; Sil.d_exp_list taint_set; L.d_ln (); + L.d_str "Untaint set: "; Sil.d_exp_list untaint_set; L.d_ln (); + match intersection_taint_untaint taint_set untaint_set with + | None -> L.d_str "NO taint error detected"; L.d_ln(); | Some e -> begin - L.d_str "^^^^^ERROR in TAINT ANALYSIS: "; - let e' = match Errdesc.find_pvar_with_exp sub2_augmented_actual_pre e with + L.d_str "Taint error detected!"; L.d_ln(); + let e' = match Errdesc.find_pvar_with_exp prop e with | Some (pv, _) -> Sil.Lvar pv | None -> e in let err_desc = Errdesc.explain_tainted_value_reaching_sensitive_function e' (State.get_loc ()) in @@ -895,8 +903,8 @@ let exe_spec vr_incons_res = inconsistent_results } in begin IList.iter log_check_exn checks; - if (!Config.taint_analysis && !Config.developer_mode) then - do_taint_check caller_pname actual_pre missing_pi missing_sigma sub1 sub2; + if !Config.taint_analysis then + do_taint_check caller_pname actual_pre missing_pi sub2 prop; let subbed_pre = (Prop.prop_sub sub1 actual_pre) in match check_dereferences callee_pname subbed_pre sub2 spec_pre formal_params with | Some (Deref_undef _, _) when !Config.angelic_execution -> diff --git a/infer/tests/ant_report.json b/infer/tests/ant_report.json index 477d51b66..cdf89719b 100644 --- a/infer/tests/ant_report.json +++ b/infer/tests/ant_report.json @@ -579,6 +579,106 @@ "procedure": "void ResourceLeaks.scannerNotClosed()", "file": "codetoanalyze/java/infer/ResourceLeaks.java" }, + { + "type": "TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION", + "procedure": "String TaintExample.taintGetHostEquals(String)", + "file": "codetoanalyze/java/infer/TaintExample.java" + }, + { + "type": "TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION", + "procedure": "String TaintExample.taintGetHostCompareTo(String)", + "file": "codetoanalyze/java/infer/TaintExample.java" + }, + { + "type": "TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION", + "procedure": "String TaintExample.taintGetHostEndsWith(String)", + "file": "codetoanalyze/java/infer/TaintExample.java" + }, + { + "type": "TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION", + "procedure": "String TaintExample.taintGetHostStartsWith(String)", + "file": "codetoanalyze/java/infer/TaintExample.java" + }, + { + "type": "TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION", + "procedure": "String TaintExample.taintGetAuthoriyEquals(String)", + "file": "codetoanalyze/java/infer/TaintExample.java" + }, + { + "type": "TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION", + "procedure": "String TaintExample.taintGetAuthorityCompareTo(String)", + "file": "codetoanalyze/java/infer/TaintExample.java" + }, + { + "type": "TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION", + "procedure": "String TaintExample.taintGetAuthorityEndsWith(String)", + "file": "codetoanalyze/java/infer/TaintExample.java" + }, + { + "type": "TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION", + "procedure": "String TaintExample.taintGetAuthorityStartsWith(String)", + "file": "codetoanalyze/java/infer/TaintExample.java" + }, + { + "type": "TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION", + "procedure": "String TaintExample.taintGetProtocolEquals(String)", + "file": "codetoanalyze/java/infer/TaintExample.java" + }, + { + "type": "TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION", + "procedure": "String TaintExample.taintGetProtocolCompareTo(String)", + "file": "codetoanalyze/java/infer/TaintExample.java" + }, + { + "type": "TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION", + "procedure": "String TaintExample.taintGetProtocolEndsWith(String)", + "file": "codetoanalyze/java/infer/TaintExample.java" + }, + { + "type": "TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION", + "procedure": "String TaintExample.taintGetProtocolStartsWith(String)", + "file": "codetoanalyze/java/infer/TaintExample.java" + }, + { + "type": "TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION", + "procedure": "String TaintExample.taintToExternalFormEquals(String)", + "file": "codetoanalyze/java/infer/TaintExample.java" + }, + { + "type": "TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION", + "procedure": "String TaintExample.taintToExternalFormCompareTo(String)", + "file": "codetoanalyze/java/infer/TaintExample.java" + }, + { + "type": "TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION", + "procedure": "String TaintExample.taintToExternalFormEndsWith(String)", + "file": "codetoanalyze/java/infer/TaintExample.java" + }, + { + "type": "TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION", + "procedure": "String TaintExample.taintToExternalFormStartsWith(String)", + "file": "codetoanalyze/java/infer/TaintExample.java" + }, + { + "type": "TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION", + "procedure": "String TaintExample.taintToStringEquals(String)", + "file": "codetoanalyze/java/infer/TaintExample.java" + }, + { + "type": "TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION", + "procedure": "String TaintExample.taintToStringCompareTo(String)", + "file": "codetoanalyze/java/infer/TaintExample.java" + }, + { + "type": "TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION", + "procedure": "String TaintExample.taintToStringEndsWith(String)", + "file": "codetoanalyze/java/infer/TaintExample.java" + }, + { + "type": "TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION", + "procedure": "String TaintExample.taintToStringStartsWith(String)", + "file": "codetoanalyze/java/infer/TaintExample.java" + }, { "type": "RESOURCE_LEAK", "procedure": "void WriterLeaks.writerNotClosedAfterWrite()", diff --git a/infer/tests/buck_report.json b/infer/tests/buck_report.json index fcc2ca7b3..87346b46d 100644 --- a/infer/tests/buck_report.json +++ b/infer/tests/buck_report.json @@ -574,6 +574,106 @@ "procedure": "void ResourceLeaks.scannerNotClosed()", "file": "infer/tests/codetoanalyze/java/infer/ResourceLeaks.java" }, + { + "type": "TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION", + "procedure": "String TaintExample.taintGetHostEquals(String)", + "file": "infer/tests/codetoanalyze/java/infer/TaintExample.java" + }, + { + "type": "TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION", + "procedure": "String TaintExample.taintGetHostCompareTo(String)", + "file": "infer/tests/codetoanalyze/java/infer/TaintExample.java" + }, + { + "type": "TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION", + "procedure": "String TaintExample.taintGetHostEndsWith(String)", + "file": "infer/tests/codetoanalyze/java/infer/TaintExample.java" + }, + { + "type": "TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION", + "procedure": "String TaintExample.taintGetHostStartsWith(String)", + "file": "infer/tests/codetoanalyze/java/infer/TaintExample.java" + }, + { + "type": "TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION", + "procedure": "String TaintExample.taintGetAuthoriyEquals(String)", + "file": "infer/tests/codetoanalyze/java/infer/TaintExample.java" + }, + { + "type": "TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION", + "procedure": "String TaintExample.taintGetAuthorityCompareTo(String)", + "file": "infer/tests/codetoanalyze/java/infer/TaintExample.java" + }, + { + "type": "TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION", + "procedure": "String TaintExample.taintGetAuthorityEndsWith(String)", + "file": "infer/tests/codetoanalyze/java/infer/TaintExample.java" + }, + { + "type": "TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION", + "procedure": "String TaintExample.taintGetAuthorityStartsWith(String)", + "file": "infer/tests/codetoanalyze/java/infer/TaintExample.java" + }, + { + "type": "TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION", + "procedure": "String TaintExample.taintGetProtocolEquals(String)", + "file": "infer/tests/codetoanalyze/java/infer/TaintExample.java" + }, + { + "type": "TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION", + "procedure": "String TaintExample.taintGetProtocolCompareTo(String)", + "file": "infer/tests/codetoanalyze/java/infer/TaintExample.java" + }, + { + "type": "TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION", + "procedure": "String TaintExample.taintGetProtocolEndsWith(String)", + "file": "infer/tests/codetoanalyze/java/infer/TaintExample.java" + }, + { + "type": "TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION", + "procedure": "String TaintExample.taintGetProtocolStartsWith(String)", + "file": "infer/tests/codetoanalyze/java/infer/TaintExample.java" + }, + { + "type": "TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION", + "procedure": "String TaintExample.taintToExternalFormEquals(String)", + "file": "infer/tests/codetoanalyze/java/infer/TaintExample.java" + }, + { + "type": "TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION", + "procedure": "String TaintExample.taintToExternalFormCompareTo(String)", + "file": "infer/tests/codetoanalyze/java/infer/TaintExample.java" + }, + { + "type": "TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION", + "procedure": "String TaintExample.taintToExternalFormEndsWith(String)", + "file": "infer/tests/codetoanalyze/java/infer/TaintExample.java" + }, + { + "type": "TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION", + "procedure": "String TaintExample.taintToExternalFormStartsWith(String)", + "file": "infer/tests/codetoanalyze/java/infer/TaintExample.java" + }, + { + "type": "TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION", + "procedure": "String TaintExample.taintToStringEquals(String)", + "file": "infer/tests/codetoanalyze/java/infer/TaintExample.java" + }, + { + "type": "TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION", + "procedure": "String TaintExample.taintToStringCompareTo(String)", + "file": "infer/tests/codetoanalyze/java/infer/TaintExample.java" + }, + { + "type": "TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION", + "procedure": "String TaintExample.taintToStringEndsWith(String)", + "file": "infer/tests/codetoanalyze/java/infer/TaintExample.java" + }, + { + "type": "TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION", + "procedure": "String TaintExample.taintToStringStartsWith(String)", + "file": "infer/tests/codetoanalyze/java/infer/TaintExample.java" + }, { "type": "RESOURCE_LEAK", "procedure": "void WriterLeaks.writerNotClosedAfterWrite()", diff --git a/infer/tests/codetoanalyze/java/infer/TaintExample.java b/infer/tests/codetoanalyze/java/infer/TaintExample.java new file mode 100644 index 000000000..c6d71a900 --- /dev/null +++ b/infer/tests/codetoanalyze/java/infer/TaintExample.java @@ -0,0 +1,256 @@ +/* +* Copyright (c) 2013 - present Facebook, Inc. +* All rights reserved. +* +* This source code is licensed under the BSD style license found in the +* LICENSE file in the root directory of this source tree. An additional grant +* of patent rights can be found in the PATENTS file in the same directory. +*/ + +package codetoanalyze.java.infer; + + +import java.net.MalformedURLException; +import java.net.URL; + +public class TaintExample { + + String test_equals(String s) { + + String my_string ="a string"; + String res; + + if (my_string.equals(s)) { + res = "OK"; + } else { + res = "NOT OK"; + } + return res; + } + + String test_compareTo(String s) { + + String my_string ="a string"; + String res; + + if (my_string.compareTo(s) == 1) { + res = "OK"; + } else { + res = "NOT OK"; + } + return res; + } + + String test_endsWith(String s) { + + String my_string ="a string"; + String res; + + if (my_string.endsWith(s)) { + res = "OK"; + } else { + res = "NOT OK"; + } + return res; + } + + String test_startsWith(String s) { + + String my_string ="a string"; + String res; + + if (my_string.startsWith(s)) { + res = "OK"; + } else { + res = "NOT OK"; + } + return res; + } + + + public String taintGetHostEquals (String s) throws MalformedURLException { + + String res; + URL u = new URL(s); + String s1 = u.getHost(); + res = test_equals(s1); + return res; + } + + public String taintGetHostCompareTo (String s) throws MalformedURLException { + + String res; + URL u = new URL(s); + String s1 = u.getHost(); + res = test_compareTo(s1); + return res; + + } + + public String taintGetHostEndsWith (String s) throws MalformedURLException { + + String res; + URL u = new URL(s); + String s1 = u.getHost(); + res = test_endsWith(s1); + return res; + } + + public String taintGetHostStartsWith (String s) throws MalformedURLException { + + String res; + URL u = new URL(s); + String s1 = u.getHost(); + res = test_startsWith(s1); + return res; + } + + public String taintGetAuthoriyEquals (String s) throws MalformedURLException { + + String res; + URL u = new URL(s); + String s1 = u.getAuthority(); + res = test_equals(s1); + return res; + } + + public String taintGetAuthorityCompareTo (String s) throws MalformedURLException { + + String res; + URL u = new URL(s); + String s1 = u.getAuthority(); + res = test_compareTo(s1); + return res; + + } + + public String taintGetAuthorityEndsWith (String s) throws MalformedURLException { + + String res; + URL u = new URL(s); + String s1 = u.getAuthority(); + res = test_endsWith(s1); + return res; + } + + public String taintGetAuthorityStartsWith (String s) throws MalformedURLException { + + String res; + URL u = new URL(s); + String s1 = u.getAuthority(); + res = test_startsWith(s1); + return res; + } + + public String taintGetProtocolEquals (String s) throws MalformedURLException { + + String res; + URL u = new URL(s); + String s1 = u.getProtocol(); + res = test_equals(s1); + return res; + } + + public String taintGetProtocolCompareTo (String s) throws MalformedURLException { + + String res; + URL u = new URL(s); + String s1 = u.getProtocol(); + res = test_compareTo(s1); + return res; + + } + + public String taintGetProtocolEndsWith (String s) throws MalformedURLException { + + String res; + URL u = new URL(s); + String s1 = u.getProtocol(); + res = test_endsWith(s1); + return res; + } + + public String taintGetProtocolStartsWith (String s) throws MalformedURLException { + + String res; + URL u = new URL(s); + String s1 = u.getProtocol(); + res = test_startsWith(s1); + return res; + } + + public String taintToExternalFormEquals (String s) throws MalformedURLException { + + String res; + URL u = new URL(s); + String s1 = u.toExternalForm(); + res = test_equals(s1); + return res; + } + + public String taintToExternalFormCompareTo (String s) throws MalformedURLException { + + String res; + URL u = new URL(s); + String s1 = u.toExternalForm(); + res = test_compareTo(s1); + return res; + + } + + public String taintToExternalFormEndsWith (String s) throws MalformedURLException { + + String res; + URL u = new URL(s); + String s1 = u.toExternalForm(); + res = test_endsWith(s1); + return res; + } + + public String taintToExternalFormStartsWith (String s) throws MalformedURLException { + + String res; + URL u = new URL(s); + String s1 = u.toExternalForm(); + res = test_startsWith(s1); + return res; + } + + public String taintToStringEquals (String s) throws MalformedURLException { + + String res; + URL u = new URL(s); + String s1 = u.toString(); + res = test_equals(s1); + return res; + } + + public String taintToStringCompareTo (String s) throws MalformedURLException { + + String res; + URL u = new URL(s); + String s1 = u.toString(); + res = test_compareTo(s1); + return res; + + } + + public String taintToStringEndsWith (String s) throws MalformedURLException { + + String res; + URL u = new URL(s); + String s1 = u.toString(); + res = test_endsWith(s1); + return res; + } + + public String taintToStringStartsWith (String s) throws MalformedURLException { + + String res; + URL u = new URL(s); + String s1 = u.toString(); + res = test_startsWith(s1); + return res; + } + +} diff --git a/infer/tests/endtoend/java/infer/TaintTest.java b/infer/tests/endtoend/java/infer/TaintTest.java new file mode 100644 index 000000000..34743a4bd --- /dev/null +++ b/infer/tests/endtoend/java/infer/TaintTest.java @@ -0,0 +1,76 @@ +/* +* Copyright (c) 2013 - present Facebook, Inc. +* All rights reserved. +* +* This source code is licensed under the BSD style license found in the +* LICENSE file in the root directory of this source tree. An additional grant +* of patent rights can be found in the PATENTS file in the same directory. +*/ + +package endtoend.java.infer; + +import static org.hamcrest.MatcherAssert.assertThat; +import static utils.matchers.ResultContainsExactly.containsExactly; + +import org.junit.BeforeClass; +import org.junit.Test; + +import java.io.IOException; + +import utils.InferException; +import utils.InferResults; + +public class TaintTest { + + public static final String TaintFile = + "infer/tests/codetoanalyze/java/infer/TaintExample.java"; + + public static final String TAINTED_VALUE = "TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION"; + + private static InferResults inferResults; + + @BeforeClass + public static void loadResults() throws InterruptedException, IOException { + inferResults = InferResults.loadInferResults(TaintTest.class, TaintFile); + } + + @Test + public void whenInferRunsOnTaintFileErrorFound() + throws InterruptedException, IOException, InferException { + String[] methods = { + "taintGetHostEquals", + "taintGetHostCompareTo", + "taintGetHostEndsWith", + "taintGetHostStartsWith", + "taintGetAuthoriyEquals", + "taintGetAuthorityCompareTo", + "taintGetAuthorityEndsWith", + "taintGetAuthorityStartsWith", + "taintGetProtocolEquals", + "taintGetProtocolCompareTo", + "taintGetProtocolEndsWith", + "taintGetProtocolStartsWith", + "taintToExternalFormEquals", + "taintToExternalFormCompareTo", + "taintToExternalFormEndsWith", + "taintToExternalFormStartsWith", + "taintToStringEquals", + "taintToStringCompareTo", + "taintToStringEndsWith", + "taintToStringStartsWith" + }; + + assertThat( + "Results should contain tainted value reaching sensitive function.", + inferResults, + containsExactly( + TAINTED_VALUE, + TaintFile, + methods + ) + ); + + + } + +}