From c77a3b5adc0ace19da2c29788f756c9e9ca3251d Mon Sep 17 00:00:00 2001 From: Hitesh Ahuja <108540135+hahuja2@users.noreply.github.com> Date: Thu, 15 Feb 2024 15:25:27 -0800 Subject: [PATCH 1/2] fix(agent): ensure package version retrieval does not error out (#833) This PR does the following: - For Drupal the `Drupal::VERSION` class constant is retrieved using zend calls from C and does not require using `zend_eval_string`. The retrieval is robust against the this constant not being defined. - For Wordpress, the presence of the `wp_version` value in `$GLOBAL` is verified before trying to retrieve the value. --------- Co-authored-by: Michael Fulbright Co-authored-by: Michal Nowacki Co-authored-by: Michael Fulbright <89205663+mfulb@users.noreply.github.com> --- agent/fw_drupal8.c | 40 +++++++++++++++++++++++++++++----------- agent/fw_wordpress.c | 25 +++++++++++++++++++------ 2 files changed, 48 insertions(+), 17 deletions(-) diff --git a/agent/fw_drupal8.c b/agent/fw_drupal8.c index 52f550868..5456cf390 100644 --- a/agent/fw_drupal8.c +++ b/agent/fw_drupal8.c @@ -533,20 +533,38 @@ NR_PHP_WRAPPER(nr_drupal8_name_the_wt_via_symfony) { } NR_PHP_WRAPPER_END +/* + * Drupal stores the version of the framework in the class constant + * Drupal::VERSION. This code first verifies the 'Drupal' class exists (note + * having to pass the lower case name of the class). If present then an attempt + * is made to retrieve the 'VERSION' class constant. Both of these checks rely + * on existing "nr_" routines that have been designed to be robust and will not + * cause an issue in user's application if either check were to fail. + */ void nr_drupal_version() { - char* string = "Drupal::VERSION;"; - zval retval; - int result - = zend_eval_string(string, &retval, "Retrieve Drupal Version"); - + zval* zval_version = NULL; + zend_class_entry* class_entry = NULL; + + class_entry = nr_php_find_class("drupal"); + if (NULL == class_entry) { + nrl_verbosedebug(NRL_INSTRUMENT, "%s: 'Drupal' class not found", __func__); + return; + } + + zval_version = nr_php_get_class_constant(class_entry, "VERSION"); + if (NULL == zval_version) { + nrl_verbosedebug(NRL_INSTRUMENT, "%s: Drupal does not have VERSION", + __func__); + return; + } + // Add php package to transaction - if (result == SUCCESS) { - if (Z_TYPE(retval) == IS_STRING) { - char* version = Z_STRVAL(retval); - nr_txn_add_php_package(NRPRG(txn), "drupal/core", version); - } - zval_dtor(&retval); + if (nr_php_is_zval_valid_string(zval_version)) { + char* version = Z_STRVAL_P(zval_version); + nr_txn_add_php_package(NRPRG(txn), "drupal/core", version); } + + nr_php_zval_free(&zval_version); } void nr_drupal8_enable(TSRMLS_D) { diff --git a/agent/fw_wordpress.c b/agent/fw_wordpress.c index 675360a49..32ce1fdc1 100644 --- a/agent/fw_wordpress.c +++ b/agent/fw_wordpress.c @@ -658,14 +658,27 @@ NR_PHP_WRAPPER_END #endif /* PHP 7.4+ */ void nr_wordpress_version() { - char* string = "$GLOBALS['wp_version'];"; + char* func_string + = "" + "(function() {" + " try {" + " if (array_key_exists('wp_version', $GLOBALS)) {" + " return $GLOBALS['wp_version'];" + " }" + " else {" + " return ' ';" + " }" + " } catch (Exception $e) {" + " return ' ';" + " }" + "})();"; + zval retval; - int result = zend_eval_string(string, &retval, - "Retrieve Wordpress Version"); - + int result + = zend_eval_string(func_string, &retval, "Get Wordpress Version"); // Add php package to transaction - if (result == SUCCESS) { - if (Z_TYPE(retval) == IS_STRING) { + if (SUCCESS == result) { + if (nr_php_is_zval_valid_string(&retval)) { char* version = Z_STRVAL(retval); nr_txn_add_php_package(NRPRG(txn), "wordpress", version); } From bc860662872123d8a9b7dc14644c07c1434ef8d2 Mon Sep 17 00:00:00 2001 From: Hitesh Ahuja <108540135+hahuja2@users.noreply.github.com> Date: Thu, 15 Feb 2024 15:25:54 -0800 Subject: [PATCH 2/2] fix(agent): remove PHPUnit version detection (#835) This PR removes the version detection code for PHPUnit. --- agent/fw_hooks.h | 1 - agent/lib_phpunit.c | 16 ---------------- agent/php_execute.c | 1 - 3 files changed, 18 deletions(-) diff --git a/agent/fw_hooks.h b/agent/fw_hooks.h index ee7496741..f49bc591b 100644 --- a/agent/fw_hooks.h +++ b/agent/fw_hooks.h @@ -58,6 +58,5 @@ extern void nr_monolog_enable(TSRMLS_D); /* Vulnerability Management Packages */ extern void nr_drupal_version(void); extern void nr_wordpress_version(void); -extern void nr_phpunit_version(void); #endif /* FW_HOOKS_HDR */ diff --git a/agent/lib_phpunit.c b/agent/lib_phpunit.c index 66702c5e4..436666dc9 100644 --- a/agent/lib_phpunit.c +++ b/agent/lib_phpunit.c @@ -666,22 +666,6 @@ static int nr_phpunit_are_statuses_valid(TSRMLS_D) { return 1; } -void nr_phpunit_version() { - char* string = "PHPUnit\\Runner\\Version::id();"; - zval retval; - int result - = zend_eval_string(string, &retval, "Retrieve PHPUnit Version"); - - // Add php package to transaction - if (result == SUCCESS) { - if (Z_TYPE(retval) == IS_STRING) { - char* version = Z_STRVAL(retval); - nr_txn_add_php_package(NRPRG(txn), "phpunit/phpunit", version); - } - zval_dtor(&retval); - } -} - void nr_phpunit_enable(TSRMLS_D) { if (!NRINI(phpunit_events_enabled)) { return; diff --git a/agent/php_execute.c b/agent/php_execute.c index dc4901e23..81d2f3d8b 100644 --- a/agent/php_execute.c +++ b/agent/php_execute.c @@ -605,7 +605,6 @@ typedef struct _nr_vuln_mgmt_table_t { /* Note that all paths should be in lowercase. */ static const nr_vuln_mgmt_table_t vuln_mgmt_packages[] = { {"Drupal", "core/lib/drupal.php", nr_drupal_version}, - {"PHPUnit", "runner/version.php", nr_phpunit_version}, {"Wordpress", "wp-includes/version.php", nr_wordpress_version}, };