[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 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 resource_leak = from_string "RESOURCE_LEAK"
let retain_cycle = from_string ~enabled:true "RETAIN_CYCLE" 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 = from_string "SHELL_INJECTION"
let shell_injection_risk = from_string "SHELL_INJECTION_RISK"
let sql_injection = from_string "SQL_INJECTION" 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 stack_variable_address_escape = from_string ~enabled:false "STACK_VARIABLE_ADDRESS_ESCAPE"
let static_initialization_order_fiasco = from_string "STATIC_INITIALIZATION_ORDER_FIASCO" 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 registered_observer_being_deallocated : t
val remote_code_execution_risk : t
val resource_leak : t val resource_leak : t
val retain_cycle : t val retain_cycle : t
@ -232,8 +230,12 @@ val skip_pointer_dereference : t
val shell_injection : t val shell_injection : t
val shell_injection_risk : t
val sql_injection : t val sql_injection : t
val sql_injection_risk : t
val stack_variable_address_escape : t val stack_variable_address_escape : t
val static_initialization_order_fiasco : t val static_initialization_order_fiasco : t

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

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

@ -12,8 +12,8 @@
#include <string> #include <string>
extern void __infer_sql_sink(std::string); extern void __infer_sql_sink(std::string);
extern std::string __infer_all_sanitizer(std::string); extern std::string __infer_shell_sanitizer(std::string);
extern std::string __infer_string_sanitizer(std::string); extern std::string __infer_sql_sanitizer(std::string);
extern void curl_easy_setopt(void*, int, ...); extern void curl_easy_setopt(void*, int, ...);
@ -60,17 +60,18 @@ class Service1 : facebook::fb303::cpp2::FacebookServiceSvIf {
__infer_sql_sink(formal); __infer_sql_sink(formal);
} }
void sanitized_sql_bad(std::string formal) { void sanitized_sql_with_shell_bad(std::string formal) {
// this should report USER_CONTROLLED_SQL_RISK // this should report REMOTE_CODE_EXECUTION_RISK
__infer_sql_sink(__infer_string_sanitizer(formal)); __infer_sql_sink(__infer_shell_sanitizer(formal));
} }
void service1_endpoint_sql_sanitized_ok(std::string formal) { void service1_endpoint_sql_sanitized_bad(std::string formal) {
__infer_sql_sink(__infer_all_sanitizer(formal)); // this should report USER_CONTROLLED_SQL_RISK
__infer_sql_sink(__infer_sql_sanitizer(formal));
} }
void service1_endpoint_shell_sanitized_ok(std::string 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) { 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_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_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/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_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_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] 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, 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, 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_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_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, REMOTE_CODE_EXECUTION_RISK, [Return from endpoints::Service1_service1_endpoint_bad,Call to system] 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_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_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_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_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_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::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::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, REMOTE_CODE_EXECUTION_RISK, [Return from endpoints::Service3_service3_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, 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, 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] 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_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/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::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/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::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] 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 std::string __infer_taint_source();
extern void __infer_taint_sink(std::string);
extern void __infer_sql_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_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 { namespace sanitizers {
void escape_string_to_sql_ok() { void escape_sql_to_sql_ok() {
auto source = __infer_taint_source(); auto source = __infer_taint_source();
auto sanitized = __infer_string_sanitizer(source); auto sanitized = __infer_sql_sanitizer(source);
__infer_sql_sink(sanitized); __infer_sql_sink(sanitized);
} }
void escape_string_to_shell_ok() { void escape_shell_to_shell_ok() {
auto source = __infer_taint_source(); auto source = __infer_taint_source();
auto sanitized = __infer_string_sanitizer(source); auto sanitized = __infer_shell_sanitizer(source);
system(sanitized.c_str()); system(sanitized.c_str());
} }
void escape_string_to_all_bad() { void escape_url_to_url_ok() {
auto source = __infer_taint_source(); auto source = __infer_taint_source();
auto sanitized = __infer_string_sanitizer(source); auto sanitized = __infer_url_sanitizer(source);
__infer_taint_sink(sanitized); // wrong kind of sanitizer; report __infer_url_sink(sanitized);
} }
void foo(std::string sanitized) { __infer_url_sink(sanitized); }
void all_to_all_ok() { void all_to_all_ok() {
auto source = __infer_taint_source(); auto source = __infer_taint_source();
auto sanitized = __infer_all_sanitizer(source); auto sanitized = __infer_all_sanitizer(source);
__infer_taint_sink(sanitized); __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() { void dead_sanitizer_bad() {
auto source = __infer_taint_source(); auto source = __infer_taint_source();
auto sanitized = __infer_all_sanitizer(source); auto sanitized = __infer_all_sanitizer(source);
@ -61,7 +92,7 @@ void kill_sanitizer_bad() {
void double_sanitize_ok() { void double_sanitize_ok() {
auto source = __infer_taint_source(); auto source = __infer_taint_source();
auto x = __infer_all_sanitizer(source); auto x = __infer_all_sanitizer(source);
auto y = __infer_string_sanitizer(x); auto y = __infer_sql_sanitizer(x);
__infer_taint_sink(y); __infer_taint_sink(y);
} }
@ -97,7 +128,7 @@ void different_sanitizer_branches_ok(bool b) {
if (b) { if (b) {
x = __infer_all_sanitizer(source); x = __infer_all_sanitizer(source);
} else { } else {
x = __infer_string_sanitizer(source); x = __infer_sql_sanitizer(source);
} }
__infer_sql_sink(x); __infer_sql_sink(x);
} }

Loading…
Cancel
Save