From 64e52596abaf4bdd4c17f79c4e8acf25d1a452b4 Mon Sep 17 00:00:00 2001 From: jvoisin Date: Wed, 29 Aug 2018 08:55:49 +0000 Subject: Verify certs (#223) Ensure that certificates are verified in curl should close #47 --- src/config.m4 | 1 + src/php_snuffleupagus.h | 1 + src/snuffleupagus.c | 6 ++++ src/sp_config.c | 1 + src/sp_config.h | 8 ++++++ src/sp_config_keywords.c | 5 ++++ src/sp_config_keywords.h | 1 + src/sp_curl_verify_certificates.c | 33 ++++++++++++++++++++++ src/sp_curl_verify_certificates.h | 15 ++++++++++ .../config/disabled_function_curl_verify_certs.ini | 1 + src/tests/ensure_client_valid_certs.phpt | 18 ++++++++++++ src/tests/ensure_server_valid_certs.phpt | 18 ++++++++++++ 12 files changed, 108 insertions(+) create mode 100644 src/sp_curl_verify_certificates.c create mode 100644 src/sp_curl_verify_certificates.h create mode 100644 src/tests/config/disabled_function_curl_verify_certs.ini create mode 100644 src/tests/ensure_client_valid_certs.phpt create mode 100644 src/tests/ensure_server_valid_certs.phpt (limited to 'src') diff --git a/src/config.m4 b/src/config.m4 index 52b6d04..dc88661 100644 --- a/src/config.m4 +++ b/src/config.m4 @@ -7,6 +7,7 @@ sources="$sources sp_disabled_functions.c sp_execute.c sp_upload_validation.c" sources="$sources sp_cookie_encryption.c sp_network_utils.c tweetnacl.c" sources="$sources sp_config_keywords.c sp_var_parser.c sp_var_value.c sp_tree.c" sources="$sources sp_pcre_compat.c sp_crypt.c sp_session.c sp_sloppy.c sp_wrapper.c" +sources="$sources sp_curl_verify_certificates.c" PHP_ARG_ENABLE(snuffleupagus, whether to enable snuffleupagus support, [ --enable-snuffleupagus Enable snuffleupagus support]) diff --git a/src/php_snuffleupagus.h b/src/php_snuffleupagus.h index 41d9b77..9dc045c 100644 --- a/src/php_snuffleupagus.h +++ b/src/php_snuffleupagus.h @@ -32,6 +32,7 @@ #include "sp_config.h" #include "sp_config_utils.h" #include "sp_config_keywords.h" +#include "sp_curl_verify_certificates.h" #include "sp_cookie_encryption.h" #include "sp_disable_xxe.h" #include "sp_disabled_functions.h" diff --git a/src/snuffleupagus.c b/src/snuffleupagus.c index 1a92f11..9f92397 100644 --- a/src/snuffleupagus.c +++ b/src/snuffleupagus.c @@ -96,6 +96,7 @@ PHP_GINIT_FUNCTION(snuffleupagus) { SP_INIT(snuffleupagus_globals->config.config_session); SP_INIT(snuffleupagus_globals->config.config_eval); SP_INIT(snuffleupagus_globals->config.config_wrapper); + SP_INIT(snuffleupagus_globals->config.config_curl_verify_certificates); snuffleupagus_globals->config.config_disabled_functions_reg ->disabled_functions = NULL; @@ -143,6 +144,7 @@ PHP_MSHUTDOWN_FUNCTION(snuffleupagus) { pefree(SNUFFLEUPAGUS_G(config.config_random), 1); pefree(SNUFFLEUPAGUS_G(config.config_readonly_exec), 1); pefree(SNUFFLEUPAGUS_G(config.config_global_strict), 1); + pefree(SNUFFLEUPAGUS_G(config.config_curl_verify_certificates), 1); pefree(SNUFFLEUPAGUS_G(config.config_auto_cookie_secure), 1); pefree(SNUFFLEUPAGUS_G(config.config_snuffleupagus), 1); pefree(SNUFFLEUPAGUS_G(config.config_disable_xxe), 1); @@ -272,6 +274,10 @@ static PHP_INI_MH(OnUpdateConfiguration) { hook_session(); } + if (SNUFFLEUPAGUS_G(config).config_curl_verify_certificates->enable) { + hook_curl_verify_certificates(); + } + if (true == SNUFFLEUPAGUS_G(config).config_global_strict->enable) { if (!zend_get_extension(PHP_SNUFFLEUPAGUS_EXTNAME)) { zend_extension_entry.startup = NULL; diff --git a/src/sp_config.c b/src/sp_config.c index 2480362..bc703a6 100644 --- a/src/sp_config.c +++ b/src/sp_config.c @@ -24,6 +24,7 @@ sp_config_tokens const sp_func[] = { {.func = parse_session, .token = SP_TOKEN_SESSION_ENCRYPTION}, {.func = parse_sloppy_comparison, .token = SP_TOKEN_SLOPPY_COMPARISON}, {.func = parse_wrapper_whitelist, .token = SP_TOKEN_ALLOW_WRAPPERS}, + {.func = parse_curl_verify_certificates, .token = SP_TOKEN_CURL_VERIFY_CERTIFICATES}, {NULL, NULL}}; /* Top level keyword parsing */ diff --git a/src/sp_config.h b/src/sp_config.h index 9d58359..4d85cf2 100644 --- a/src/sp_config.h +++ b/src/sp_config.h @@ -53,6 +53,10 @@ typedef struct { bool enable; } sp_config_global_strict; +typedef struct { + bool enable; +} sp_config_curl_verify_certificates; + typedef struct { bool enable; } sp_config_random; @@ -162,6 +166,7 @@ typedef struct { typedef struct { sp_config_random *config_random; + sp_config_curl_verify_certificates *config_curl_verify_certificates; sp_config_sloppy *config_sloppy; sp_config_unserialize *config_unserialize; sp_config_readonly_exec *config_readonly_exec; @@ -264,6 +269,9 @@ typedef struct { // upload_validator #define SP_TOKEN_UPLOAD_SCRIPT ".script(" +// cURL certificate verify +# define SP_TOKEN_CURL_VERIFY_CERTIFICATES ".curl_verify_certificates" + #define SP_TOKEN_LIST ".list(" int sp_parse_config(const char *); diff --git a/src/sp_config_keywords.c b/src/sp_config_keywords.c index 93077c6..ee4d130 100644 --- a/src/sp_config_keywords.c +++ b/src/sp_config_keywords.c @@ -94,6 +94,11 @@ int parse_global_strict(char *line) { line, &(SNUFFLEUPAGUS_G(config).config_global_strict->enable), NULL); } +int parse_curl_verify_certificates(char *line) { + return parse_enable( + line, &(SNUFFLEUPAGUS_G(config).config_curl_verify_certificates->enable), NULL); +} + int parse_unserialize(char *line) { bool enable = false, disable = false; sp_config_unserialize *unserialize = diff --git a/src/sp_config_keywords.h b/src/sp_config_keywords.h index ab58456..f7a4ca4 100644 --- a/src/sp_config_keywords.h +++ b/src/sp_config_keywords.h @@ -17,5 +17,6 @@ int parse_eval_whitelist(char *line); int parse_session(char *line); int parse_sloppy_comparison(char *line); int parse_wrapper_whitelist(char *line); +int parse_curl_verify_certificates(char *line); #endif // __SP_CONFIG_KEYWORDS_H diff --git a/src/sp_curl_verify_certificates.c b/src/sp_curl_verify_certificates.c new file mode 100644 index 0000000..057ee29 --- /dev/null +++ b/src/sp_curl_verify_certificates.c @@ -0,0 +1,33 @@ +#include "php_snuffleupagus.h" +#include "sp_config.h" + +ZEND_DECLARE_MODULE_GLOBALS(snuffleupagus) + +PHP_FUNCTION(sp_curl_setopt) { + void (*orig_handler)(INTERNAL_FUNCTION_PARAMETERS); + zend_string *protocol_name = NULL; + zval *zid, *zvalue; + zend_long options; + + ZEND_PARSE_PARAMETERS_START(3, 3) + Z_PARAM_RESOURCE(zid) + Z_PARAM_LONG(options) + Z_PARAM_ZVAL(zvalue) + ZEND_PARSE_PARAMETERS_END(); + + if (options & CURLOPT_SSL_VERIFYPEER && zval_get_long(zvalue) != 1) { + sp_log_err("verify_vertificates", "Please don't deactivate server certificate validation"); + } else if (options & CURLOPT_SSL_VERIFYHOST && zval_get_long(zvalue) != 2) { + sp_log_err("verify_vertificates", "Please don't deactivate client certificate validation"); + } + + orig_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +int hook_curl_verify_certificates() { + TSRMLS_FETCH(); + + HOOK_FUNCTION("curl_setopt", sp_internal_functions_hook, PHP_FN(sp_curl_setopt)); + + return SUCCESS; +} diff --git a/src/sp_curl_verify_certificates.h b/src/sp_curl_verify_certificates.h new file mode 100644 index 0000000..f4f680e --- /dev/null +++ b/src/sp_curl_verify_certificates.h @@ -0,0 +1,15 @@ +#ifndef SP_CURL_VERIFY_CERTIFICATES_H +#define SP_CURL_VERIFY_CERTIFICATES_H +#include "php_snuffleupagus.h" + +#ifndef CURLOPT_SSL_VERIFYPEER +#define CURLOPT_SSL_VERIFYPEER 64 +#endif + +#ifndef CURLOPT_SSL_VERIFYHOST +#define CURLOPT_SSL_VERIFYHOST 81 +#endif + +int hook_curl_verify_certificates(); + +#endif diff --git a/src/tests/config/disabled_function_curl_verify_certs.ini b/src/tests/config/disabled_function_curl_verify_certs.ini new file mode 100644 index 0000000..64d54a7 --- /dev/null +++ b/src/tests/config/disabled_function_curl_verify_certs.ini @@ -0,0 +1 @@ +sp.curl_verify_certificates.enable(); diff --git a/src/tests/ensure_client_valid_certs.phpt b/src/tests/ensure_client_valid_certs.phpt new file mode 100644 index 0000000..64c523c --- /dev/null +++ b/src/tests/ensure_client_valid_certs.phpt @@ -0,0 +1,18 @@ +--TEST-- +Disable functions - Ensure that client certificates validation can't be disabled +--SKIPIF-- + +--INI-- +sp.configuration_file={PWD}/config/disabled_function_curl_verify_certs.ini +--FILE-- + +--EXPECTF-- +Fatal error: [snuffleupagus][verify_vertificates] Please don't deactivate client certificate validation in %s/tests/ensure_client_valid_certs.php on line %d diff --git a/src/tests/ensure_server_valid_certs.phpt b/src/tests/ensure_server_valid_certs.phpt new file mode 100644 index 0000000..7eaf1a4 --- /dev/null +++ b/src/tests/ensure_server_valid_certs.phpt @@ -0,0 +1,18 @@ +--TEST-- +Disable functions - Ensure that server certificates validation can't be disabled +--SKIPIF-- + +--INI-- +sp.configuration_file={PWD}/config/disabled_function_curl_verify_certs.ini +--FILE-- + +--EXPECTF-- +Fatal error: [snuffleupagus][verify_vertificates] Please don't deactivate client certificate validation in %s/tests/ensure_server_valid_certs.php on line 3 -- cgit v1.3