[quandary] separate sanitizers for different kinds of escaping

Summary: Previously we had a single sanitizer kind for escaping, but this isn't quite right. A function that escapes a URL doesn't necessarily make a string safe to execute in SQL, for example.

Reviewed By: the-st0rm

Differential Revision: D6656376

fbshipit-source-id: 572944e
master
Sam Blackshear 7 years ago committed by Facebook Github Bot
parent b3992cbab8
commit 7f62154318

@ -297,8 +297,6 @@ let quandary_taint_error = from_string "QUANDARY_TAINT_ERROR"
let registered_observer_being_deallocated = from_string "REGISTERED_OBSERVER_BEING_DEALLOCATED"
let remote_code_execution_risk = from_string "REMOTE_CODE_EXECUTION_RISK"
let resource_leak = from_string "RESOURCE_LEAK"
let retain_cycle = from_string ~enabled:true "RETAIN_CYCLE"
@ -315,8 +313,12 @@ let skip_pointer_dereference = from_string "SKIP_POINTER_DEREFERENCE"
let shell_injection = from_string "SHELL_INJECTION"
let shell_injection_risk = from_string "SHELL_INJECTION_RISK"
let sql_injection = from_string "SQL_INJECTION"
let sql_injection_risk = from_string "SQL_INJECTION_RISK"
let stack_variable_address_escape = from_string ~enabled:false "STACK_VARIABLE_ADDRESS_ESCAPE"
let static_initialization_order_fiasco = from_string "STATIC_INITIALIZATION_ORDER_FIASCO"

@ -214,8 +214,6 @@ val quandary_taint_error : t
val registered_observer_being_deallocated : t
val remote_code_execution_risk : t
val resource_leak : t
val retain_cycle : t
@ -232,8 +230,12 @@ val skip_pointer_dereference : t
val shell_injection : t
val shell_injection_risk : t
val sql_injection : t
val sql_injection_risk : t
val stack_variable_address_escape : t
val static_initialization_order_fiasco : t

@ -184,10 +184,10 @@ module SinkKind = struct
| BufferAccess (** read/write an array *)
| CreateFile (** create/open a file *)
| HeapAllocation (** heap memory allocation *)
| Network (** network access *)
| ShellExec (** shell exec function *)
| SQL (** SQL query *)
| StackAllocation (** stack memory allocation *)
| URL (** URL creation *)
| Other (** for testing or uncategorized sinks *)
[@@deriving compare]
@ -200,14 +200,14 @@ module SinkKind = struct
CreateFile
| "HeapAllocation" ->
HeapAllocation
| "Network" ->
Network
| "ShellExec" ->
ShellExec
| "SQL" ->
SQL
| "StackAllocation" ->
StackAllocation
| "URL" ->
URL
| _ ->
Other
@ -308,11 +308,10 @@ module SinkKind = struct
match HilExp.eval exp with
| Some Const.Cint i ->
(* check if the data kind might be CURLOPT_URL *)
if controls_request (IntLit.to_int i) then taint_after_nth 1 Network actuals
else None
if controls_request (IntLit.to_int i) then taint_after_nth 1 URL actuals else None
| _ ->
(* can't statically resolve data kind; taint it just in case *)
taint_after_nth 1 Network actuals )
taint_after_nth 1 URL actuals )
| None ->
None )
| "execl" | "execlp" | "execle" | "execv" | "execve" | "execvp" | "system" ->
@ -349,14 +348,14 @@ module SinkKind = struct
"CreateFile"
| HeapAllocation ->
"HeapAllocation"
| Network ->
"Network"
| ShellExec ->
"ShellExec"
| SQL ->
"SQL"
| StackAllocation ->
"StackAllocation"
| URL ->
"URL"
| Other ->
"Other" )
end
@ -365,13 +364,24 @@ module CppSink = Sink.Make (SinkKind)
module CppSanitizer = struct
type t =
| Escape (** escaped string to sanitize SQL injection or ShellExec sinks *)
| EscapeShell (** escape string to sanitize shell commands *)
| EscapeSQL (** escape string to sanitize SQL queries *)
| EscapeURL (** escape string to sanitize URLs (e.g., prevent injecting GET/POST params) *)
| All (** sanitizes all forms of taint *)
[@@deriving compare]
let equal = [%compare.equal : t]
let of_string = function "Escape" -> Escape | _ -> All
let of_string = function
| "EscapeShell" ->
EscapeShell
| "EscapeSQL" ->
EscapeSQL
| "EscapeURL" ->
EscapeURL
| _ ->
All
let external_sanitizers =
List.map
@ -389,7 +399,15 @@ module CppSanitizer = struct
external_sanitizers
let pp fmt = function Escape -> F.fprintf fmt "Escape" | All -> F.fprintf fmt "All"
let pp fmt = function
| EscapeShell ->
F.fprintf fmt "EscapeShell"
| EscapeSQL ->
F.fprintf fmt "EscapeSQL"
| EscapeURL ->
F.fprintf fmt "EscapeURL"
| All ->
F.fprintf fmt "All"
end
include Trace.Make (struct
@ -397,9 +415,10 @@ include Trace.Make (struct
module Sink = CppSink
module Sanitizer = CppSanitizer
(* return true if code injection is possible because the source is a string/is not sanitized *)
let is_injection_possible ?typ sanitizers =
let is_escaped = List.mem sanitizers Sanitizer.Escape ~equal:Sanitizer.equal in
(* return true if code injection is possible because the source is a string/is not sanitized with
[escape_sanitizer] *)
let is_injection_possible ?typ escape_sanitizer sanitizers =
let is_escaped = List.mem sanitizers escape_sanitizer ~equal:Sanitizer.equal in
not is_escaped
&&
match typ with
@ -416,33 +435,46 @@ include Trace.Make (struct
(* the All sanitizer clears any form of taint; don't report *)
None
| UserControlledEndpoint (_, typ), CreateFile ->
Option.some_if (is_injection_possible ~typ sanitizers) IssueType.untrusted_file
Option.some_if
(is_injection_possible ~typ Sanitizer.EscapeShell sanitizers)
IssueType.untrusted_file
| (Endpoint (_, typ) | CommandLineFlag (_, typ)), CreateFile ->
Option.some_if (is_injection_possible ~typ sanitizers) IssueType.untrusted_file_risk
| UserControlledEndpoint (_, typ), Network ->
Option.some_if (is_injection_possible ~typ sanitizers) IssueType.untrusted_url
| (Endpoint (_, typ) | CommandLineFlag (_, typ)), Network ->
Option.some_if (is_injection_possible ~typ sanitizers) IssueType.untrusted_url_risk
| (EnvironmentVariable | ReadFile), Network ->
Option.some_if
(is_injection_possible ~typ Sanitizer.EscapeShell sanitizers)
IssueType.untrusted_file_risk
| UserControlledEndpoint (_, typ), URL ->
Option.some_if
(is_injection_possible ~typ Sanitizer.EscapeURL sanitizers)
IssueType.untrusted_url
| (Endpoint (_, typ) | CommandLineFlag (_, typ)), URL ->
Option.some_if
(is_injection_possible ~typ Sanitizer.EscapeURL sanitizers)
IssueType.untrusted_url_risk
| (EnvironmentVariable | ReadFile), URL ->
None
| (UserControlledEndpoint (_, typ) | CommandLineFlag (_, typ)), SQL ->
if is_injection_possible ~typ sanitizers then Some IssueType.sql_injection
if is_injection_possible ~typ Sanitizer.EscapeSQL sanitizers then
Some IssueType.sql_injection
else
(* no injection risk, but still user-controlled *)
Some IssueType.user_controlled_sql_risk
| Endpoint (_, typ), SQL ->
if is_injection_possible ~typ sanitizers then
(* code injection if the caller of the endpoint doesn't sanitize on its end *)
Some IssueType.remote_code_execution_risk
if is_injection_possible ~typ Sanitizer.EscapeSQL sanitizers then
(* SQL injection if the caller of the endpoint doesn't sanitize on its end *)
Some IssueType.sql_injection_risk
else
(* no injection risk, but still user-controlled *)
Some IssueType.user_controlled_sql_risk
| (UserControlledEndpoint (_, typ) | CommandLineFlag (_, typ)), ShellExec ->
(* we know the user controls the endpoint, so it's code injection without a sanitizer *)
Option.some_if (is_injection_possible ~typ sanitizers) IssueType.shell_injection
Option.some_if
(is_injection_possible ~typ Sanitizer.EscapeShell sanitizers)
IssueType.shell_injection
| Endpoint (_, typ), ShellExec ->
(* code injection if the caller of the endpoint doesn't sanitize on its end *)
Option.some_if (is_injection_possible ~typ sanitizers) IssueType.remote_code_execution_risk
Option.some_if
(is_injection_possible ~typ Sanitizer.EscapeShell sanitizers)
IssueType.shell_injection_risk
| UserControlledEndpoint _, BufferAccess ->
(* untrusted data from an endpoint flowing into a buffer *)
Some IssueType.quandary_taint_error
@ -454,10 +486,19 @@ include Trace.Make (struct
Some IssueType.quandary_taint_error
| (EnvironmentVariable | ReadFile | Other), ShellExec ->
(* untrusted flag, environment var, or file data flowing to shell *)
Option.some_if (is_injection_possible sanitizers) IssueType.shell_injection
Option.some_if
(is_injection_possible Sanitizer.EscapeShell sanitizers)
IssueType.shell_injection
| (EnvironmentVariable | ReadFile | Other), SQL ->
(* untrusted flag, environment var, or file data flowing to SQL *)
Option.some_if (is_injection_possible sanitizers) IssueType.sql_injection
Option.some_if
(is_injection_possible Sanitizer.EscapeSQL sanitizers)
IssueType.sql_injection
| Other, URL ->
(* untrusted flag, environment var, or file data flowing to URL *)
Option.some_if
(is_injection_possible Sanitizer.EscapeURL sanitizers)
IssueType.untrusted_url_risk
| ( (CommandLineFlag _ | UserControlledEndpoint _ | EnvironmentVariable | ReadFile | Other)
, HeapAllocation ) ->
(* untrusted data of any kind flowing to heap allocation. this can cause crashes or DOS. *)

@ -42,6 +42,11 @@
"kind": "SQL",
"index": "all"
},
{
"procedure": "__infer_url_sink",
"kind": "URL",
"index": "all"
},
{
"procedure": "basics::Obj::method_sink",
"kind": "Other",
@ -69,8 +74,16 @@
"kind": "All"
},
{
"procedure": "__infer_string_sanitizer",
"kind": "Escape"
"procedure": "__infer_shell_sanitizer",
"kind": "EscapeShell"
},
{
"procedure": "__infer_sql_sanitizer",
"kind": "EscapeSQL"
},
{
"procedure": "__infer_url_sanitizer",
"kind": "EscapeURL"
},
{
"procedure": "basics::Obj::sanitizer1"

@ -12,8 +12,8 @@
#include <string>
extern void __infer_sql_sink(std::string);
extern std::string __infer_all_sanitizer(std::string);
extern std::string __infer_string_sanitizer(std::string);
extern std::string __infer_shell_sanitizer(std::string);
extern std::string __infer_sql_sanitizer(std::string);
extern void curl_easy_setopt(void*, int, ...);
@ -60,17 +60,18 @@ class Service1 : facebook::fb303::cpp2::FacebookServiceSvIf {
__infer_sql_sink(formal);
}
void sanitized_sql_bad(std::string formal) {
// this should report USER_CONTROLLED_SQL_RISK
__infer_sql_sink(__infer_string_sanitizer(formal));
void sanitized_sql_with_shell_bad(std::string formal) {
// this should report REMOTE_CODE_EXECUTION_RISK
__infer_sql_sink(__infer_shell_sanitizer(formal));
}
void service1_endpoint_sql_sanitized_ok(std::string formal) {
__infer_sql_sink(__infer_all_sanitizer(formal));
void service1_endpoint_sql_sanitized_bad(std::string formal) {
// this should report USER_CONTROLLED_SQL_RISK
__infer_sql_sink(__infer_sql_sanitizer(formal));
}
void service1_endpoint_shell_sanitized_ok(std::string formal) {
system(__infer_string_sanitizer(formal).c_str());
system(__infer_shell_sanitizer(formal).c_str());
}
void service1_endpoint_struct_string_field_bad(request formal) {

@ -36,7 +36,7 @@ codetoanalyze/cpp/quandary/basics.cpp, basics::via_field_bad1, 3, QUANDARY_TAINT
codetoanalyze/cpp/quandary/basics.cpp, basics::via_field_bad2, 2, QUANDARY_TAINT_ERROR, [Return from basics::template_source<std::basic_string<char>_>,Call to basics::template_sink<std::basic_string<char>_>]
codetoanalyze/cpp/quandary/basics.cpp, basics::via_passthrough_bad1, 4, QUANDARY_TAINT_ERROR, [Return from basics::Obj_string_source,Call to basics::Obj_string_sink]
codetoanalyze/cpp/quandary/basics.cpp, basics::via_passthrough_bad2, 3, QUANDARY_TAINT_ERROR, [Return from basics::Obj_string_source,Call to basics::Obj_string_sink]
codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1_FP_service1_endpoint_struct_int_field_ok, 1, REMOTE_CODE_EXECUTION_RISK, [Return from endpoints::Service1_FP_service1_endpoint_struct_int_field_ok,Call to system]
codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1_FP_service1_endpoint_struct_int_field_ok, 1, SHELL_INJECTION_RISK, [Return from endpoints::Service1_FP_service1_endpoint_struct_int_field_ok,Call to system]
codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1_endpoint_to_curl_url_bad, 1, UNTRUSTED_URL_RISK, [Return from endpoints::Service1_endpoint_to_curl_url_bad,Call to curl_easy_setopt]
codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1_endpoint_to_curl_url_exp_bad, 1, UNTRUSTED_URL_RISK, [Return from endpoints::Service1_endpoint_to_curl_url_exp_bad,Call to curl_easy_setopt]
codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1_endpoint_to_curl_url_unknown_exp_bad, 1, UNTRUSTED_URL_RISK, [Return from endpoints::Service1_endpoint_to_curl_url_unknown_exp_bad,Call to curl_easy_setopt]
@ -52,14 +52,15 @@ codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1_open_or_create_c_s
codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1_open_or_create_c_style_file_bad, 4, UNTRUSTED_FILE_RISK, [Return from endpoints::Service1_open_or_create_c_style_file_bad,Call to fopen]
codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1_open_or_create_c_style_file_bad, 5, UNTRUSTED_FILE_RISK, [Return from endpoints::Service1_open_or_create_c_style_file_bad,Call to freopen]
codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1_open_or_create_c_style_file_bad, 6, UNTRUSTED_FILE_RISK, [Return from endpoints::Service1_open_or_create_c_style_file_bad,Call to rename]
codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1_sanitized_sql_bad, 2, USER_CONTROLLED_SQL_RISK, [Return from endpoints::Service1_sanitized_sql_bad,Call to __infer_sql_sink]
codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1_service1_endpoint_bad, 2, REMOTE_CODE_EXECUTION_RISK, [Return from endpoints::Service1_service1_endpoint_bad,Call to system]
codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1_service1_endpoint_struct_string_field_bad, 1, REMOTE_CODE_EXECUTION_RISK, [Return from endpoints::Service1_service1_endpoint_struct_string_field_bad,Call to system]
codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1_unsanitized_sql_bad, 2, REMOTE_CODE_EXECUTION_RISK, [Return from endpoints::Service1_unsanitized_sql_bad,Call to __infer_sql_sink]
codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1_sanitized_sql_with_shell_bad, 2, SQL_INJECTION_RISK, [Return from endpoints::Service1_sanitized_sql_with_shell_bad,Call to __infer_sql_sink]
codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1_service1_endpoint_bad, 2, SHELL_INJECTION_RISK, [Return from endpoints::Service1_service1_endpoint_bad,Call to system]
codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1_service1_endpoint_sql_sanitized_bad, 2, USER_CONTROLLED_SQL_RISK, [Return from endpoints::Service1_service1_endpoint_sql_sanitized_bad,Call to __infer_sql_sink]
codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1_service1_endpoint_struct_string_field_bad, 1, SHELL_INJECTION_RISK, [Return from endpoints::Service1_service1_endpoint_struct_string_field_bad,Call to system]
codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1_unsanitized_sql_bad, 2, SQL_INJECTION_RISK, [Return from endpoints::Service1_unsanitized_sql_bad,Call to __infer_sql_sink]
codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1_user_controlled_endpoint_to_shell_bad, 2, SHELL_INJECTION, [Return from endpoints::Service1_user_controlled_endpoint_to_shell_bad,Call to system]
codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1_user_controlled_endpoint_to_sql_bad, 2, SQL_INJECTION, [Return from endpoints::Service1_user_controlled_endpoint_to_sql_bad,Call to __infer_sql_sink]
codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service2_service2_endpoint_bad, 2, REMOTE_CODE_EXECUTION_RISK, [Return from endpoints::Service2_service2_endpoint_bad,Call to system]
codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service3_service3_endpoint_bad, 2, REMOTE_CODE_EXECUTION_RISK, [Return from endpoints::Service3_service3_endpoint_bad,Call to system]
codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service2_service2_endpoint_bad, 2, SHELL_INJECTION_RISK, [Return from endpoints::Service2_service2_endpoint_bad,Call to system]
codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service3_service3_endpoint_bad, 2, SHELL_INJECTION_RISK, [Return from endpoints::Service3_service3_endpoint_bad,Call to system]
codetoanalyze/cpp/quandary/execs.cpp, execs::callExecBad, 6, SHELL_INJECTION, [Return from getenv,Call to execl]
codetoanalyze/cpp/quandary/execs.cpp, execs::callExecBad, 8, SHELL_INJECTION, [Return from getenv,Call to execl]
codetoanalyze/cpp/quandary/execs.cpp, execs::callExecBad, 11, SHELL_INJECTION, [Return from getenv,Call to execl]
@ -97,7 +98,10 @@ codetoanalyze/cpp/quandary/pointers.cpp, pointers::assign_source_by_reference_ba
codetoanalyze/cpp/quandary/pointers.cpp, pointers::assign_source_by_reference_bad2, 2, QUANDARY_TAINT_ERROR, [Return from __infer_taint_source with tainted data @val$0*,Return from pointers::assign_source_by_reference,Call to __infer_taint_sink]
codetoanalyze/cpp/quandary/pointers.cpp, pointers::assign_source_by_reference_bad3, 3, QUANDARY_TAINT_ERROR, [Return from __infer_taint_source with tainted data @val$0*,Return from pointers::assign_source_by_reference with tainted data @val$0*,Return from pointers::call_assign_source_by_reference,Call to __infer_taint_sink]
codetoanalyze/cpp/quandary/sanitizers.cpp, sanitizers::dead_sanitizer_bad, 3, QUANDARY_TAINT_ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink]
codetoanalyze/cpp/quandary/sanitizers.cpp, sanitizers::escape_string_to_all_bad, 3, QUANDARY_TAINT_ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink]
codetoanalyze/cpp/quandary/sanitizers.cpp, sanitizers::escape_shell_to_url_bad, 3, UNTRUSTED_URL_RISK, [Return from __infer_taint_source,Call to __infer_url_sink]
codetoanalyze/cpp/quandary/sanitizers.cpp, sanitizers::escape_sql_to_shell_bad, 3, SHELL_INJECTION, [Return from __infer_taint_source,Call to system]
codetoanalyze/cpp/quandary/sanitizers.cpp, sanitizers::escape_sql_to_url_bad, 3, UNTRUSTED_URL_RISK, [Return from __infer_taint_source,Call to __infer_url_sink]
codetoanalyze/cpp/quandary/sanitizers.cpp, sanitizers::escape_url_to_sql_bad, 3, SQL_INJECTION, [Return from __infer_taint_source,Call to __infer_sql_sink]
codetoanalyze/cpp/quandary/sanitizers.cpp, sanitizers::kill_sanitizer_bad, 4, QUANDARY_TAINT_ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink]
codetoanalyze/cpp/quandary/strings.cpp, strings::append1_bad, 2, QUANDARY_TAINT_ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink]
codetoanalyze/cpp/quandary/strings.cpp, strings::append2_bad, 3, QUANDARY_TAINT_ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink]

@ -12,38 +12,69 @@
extern std::string __infer_taint_source();
extern void __infer_taint_sink(std::string);
extern void __infer_sql_sink(std::string);
extern void __infer_taint_sink(std::string);
extern void __infer_url_sink(std::string);
extern std::string __infer_all_sanitizer(std::string);
extern std::string __infer_string_sanitizer(std::string);
extern std::string __infer_shell_sanitizer(std::string);
extern std::string __infer_sql_sanitizer(std::string);
extern std::string __infer_url_sanitizer(std::string);
namespace sanitizers {
void escape_string_to_sql_ok() {
void escape_sql_to_sql_ok() {
auto source = __infer_taint_source();
auto sanitized = __infer_string_sanitizer(source);
auto sanitized = __infer_sql_sanitizer(source);
__infer_sql_sink(sanitized);
}
void escape_string_to_shell_ok() {
void escape_shell_to_shell_ok() {
auto source = __infer_taint_source();
auto sanitized = __infer_string_sanitizer(source);
auto sanitized = __infer_shell_sanitizer(source);
system(sanitized.c_str());
}
void escape_string_to_all_bad() {
void escape_url_to_url_ok() {
auto source = __infer_taint_source();
auto sanitized = __infer_string_sanitizer(source);
__infer_taint_sink(sanitized); // wrong kind of sanitizer; report
auto sanitized = __infer_url_sanitizer(source);
__infer_url_sink(sanitized);
}
void foo(std::string sanitized) { __infer_url_sink(sanitized); }
void all_to_all_ok() {
auto source = __infer_taint_source();
auto sanitized = __infer_all_sanitizer(source);
__infer_taint_sink(sanitized);
}
// test a few permutations of "wrong sanitizer for this sink"
void escape_sql_to_shell_bad() {
auto source = __infer_taint_source();
auto sanitized = __infer_sql_sanitizer(source);
system(sanitized.c_str());
}
void escape_sql_to_url_bad() {
auto source = __infer_taint_source();
auto sanitized = __infer_sql_sanitizer(source);
__infer_url_sink(sanitized);
}
void escape_shell_to_url_bad() {
auto source = __infer_taint_source();
auto sanitized = __infer_shell_sanitizer(source);
__infer_url_sink(sanitized);
}
void escape_url_to_sql_bad() {
auto source = __infer_taint_source();
auto sanitized = __infer_url_sanitizer(source);
__infer_sql_sink(sanitized);
}
void dead_sanitizer_bad() {
auto source = __infer_taint_source();
auto sanitized = __infer_all_sanitizer(source);
@ -61,7 +92,7 @@ void kill_sanitizer_bad() {
void double_sanitize_ok() {
auto source = __infer_taint_source();
auto x = __infer_all_sanitizer(source);
auto y = __infer_string_sanitizer(x);
auto y = __infer_sql_sanitizer(x);
__infer_taint_sink(y);
}
@ -97,7 +128,7 @@ void different_sanitizer_branches_ok(bool b) {
if (b) {
x = __infer_all_sanitizer(source);
} else {
x = __infer_string_sanitizer(source);
x = __infer_sql_sanitizer(source);
}
__infer_sql_sink(x);
}

Loading…
Cancel
Save