Skip to content

Commit

Permalink
feat(agent): use composer for vuln mgmt package info (#962)
Browse files Browse the repository at this point in the history
If possible, use Composer's runtime API to collect information about PHP
packages used by the application for New Relic Vulnerability Management.
This feature is disabled by default and can be enabled by setting
`newrelic.vulnerability_management.composer_detection.enabled` to `true`.

---------

Co-authored-by: Hitesh Ahuja <[email protected]>
Co-authored-by: bduranleau-nr <[email protected]>
Co-authored-by: Hitesh Ahuja <[email protected]>
Co-authored-by: Amber Sistla <[email protected]>
Co-authored-by: Michael Fulbright <[email protected]>
  • Loading branch information
6 people authored Sep 26, 2024
1 parent f4a33d2 commit 498b8f3
Show file tree
Hide file tree
Showing 126 changed files with 2,972 additions and 235 deletions.
1 change: 1 addition & 0 deletions agent/Makefile.frag
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ TEST_BINARIES = \
tests/test_php_minit \
tests/test_php_stack \
tests/test_php_stacked_segment \
tests/test_php_txn \
tests/test_php_wrapper \
tests/test_predis \
tests/test_redis \
Expand Down
3 changes: 2 additions & 1 deletion agent/config.m4
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,8 @@ if test "$PHP_NEWRELIC" = "yes"; then
fw_zend2.c fw_zend.c"
LIBRARIES="lib_aws_sdk_php.c lib_monolog.c lib_doctrine2.c lib_guzzle3.c \
lib_guzzle4.c lib_guzzle6.c lib_guzzle_common.c \
lib_mongodb.c lib_phpunit.c lib_predis.c lib_zend_http.c"
lib_mongodb.c lib_phpunit.c lib_predis.c lib_zend_http.c \
lib_composer.c"
PHP_NEW_EXTENSION(newrelic, $FRAMEWORKS $LIBRARIES $NEWRELIC_AGENT, $ext_shared,, \\$(NEWRELIC_CFLAGS))

PHP_SUBST(NEWRELIC_CFLAGS)
Expand Down
10 changes: 10 additions & 0 deletions agent/fw_drupal.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
#include "util_memory.h"
#include "util_strings.h"

#define PHP_PACKAGE_NAME "drupal/drupal"

/*
* Set the Web Transaction (WT) name to "(cached page)"
*
Expand Down Expand Up @@ -879,4 +881,12 @@ void nr_drupal_enable(TSRMLS_D) {
nr_php_user_function_add_declared_callback(
NR_PSTR("drupal_http_request"), nr_drupal_replace_http_request TSRMLS_CC);
#endif

if (NRINI(vulnerability_management_package_detection_enabled)) {
nr_txn_add_php_package(NRPRG(txn), PHP_PACKAGE_NAME,
PHP_PACKAGE_VERSION_UNKNOWN);
}

nr_txn_suggest_package_supportability_metric(NRPRG(txn), PHP_PACKAGE_NAME,
PHP_PACKAGE_VERSION_UNKNOWN);
}
5 changes: 3 additions & 2 deletions agent/fw_drupal8.c
Original file line number Diff line number Diff line change
Expand Up @@ -689,8 +689,6 @@ void nr_drupal_version() {
if (NRINI(vulnerability_management_package_detection_enabled)) {
nr_txn_add_php_package(NRPRG(txn), PHP_PACKAGE_NAME, version);
}
nr_fw_support_add_package_supportability_metric(NRPRG(txn), PHP_PACKAGE_NAME,
version);
}

nr_php_zval_free(&zval_version);
Expand Down Expand Up @@ -762,4 +760,7 @@ void nr_drupal8_enable(TSRMLS_D) {
nr_txn_add_php_package(NRPRG(txn), PHP_PACKAGE_NAME,
PHP_PACKAGE_VERSION_UNKNOWN);
}

nr_txn_suggest_package_supportability_metric(NRPRG(txn), PHP_PACKAGE_NAME,
PHP_PACKAGE_VERSION_UNKNOWN);
}
1 change: 1 addition & 0 deletions agent/fw_hooks.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ extern void nr_phpunit_enable(TSRMLS_D);
extern void nr_predis_enable(TSRMLS_D);
extern void nr_zend_http_enable(TSRMLS_D);
extern void nr_monolog_enable(TSRMLS_D);
extern void nr_composer_handle_autoload(const char* filename);

/* Vulnerability Management Packages */
extern void nr_drupal_version(void);
Expand Down
7 changes: 6 additions & 1 deletion agent/fw_laminas3.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#include "util_logging.h"
#include "util_memory.h"

#define PHP_PACKAGE_NAME "laminas/laminas-mvc"

/*
* Laminas is a rebranding of Zend, but the logic remains the same,
* it is simply a name change and corresponds directly to Zend 3.x.
Expand Down Expand Up @@ -163,7 +165,10 @@ void nr_laminas3_enable(TSRMLS_D) {
nr_laminas3_name_the_wt TSRMLS_CC);

if (NRINI(vulnerability_management_package_detection_enabled)) {
nr_txn_add_php_package(NRPRG(txn), "laminas/laminas-mvc",
nr_txn_add_php_package(NRPRG(txn), PHP_PACKAGE_NAME,
PHP_PACKAGE_VERSION_UNKNOWN);
}

nr_txn_suggest_package_supportability_metric(NRPRG(txn), PHP_PACKAGE_NAME,
PHP_PACKAGE_VERSION_UNKNOWN);
}
5 changes: 3 additions & 2 deletions agent/fw_laravel.c
Original file line number Diff line number Diff line change
Expand Up @@ -963,8 +963,9 @@ NR_PHP_WRAPPER(nr_laravel_application_construct) {
// Add php package to transaction
nr_txn_add_php_package(NRPRG(txn), PHP_PACKAGE_NAME, version);
}
nr_fw_support_add_package_supportability_metric(NRPRG(txn), PHP_PACKAGE_NAME,
version);

nr_txn_suggest_package_supportability_metric(NRPRG(txn), PHP_PACKAGE_NAME,
version);

if (version) {
nrl_debug(NRL_FRAMEWORK, "Laravel version is " NRP_FMT, NRP_PHP(version));
Expand Down
8 changes: 7 additions & 1 deletion agent/fw_lumen.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@
#include "php_wrapper.h"
#include "php_hash.h"
#include "fw_hooks.h"
#include "fw_support.h"
#include "util_logging.h"
#include "util_memory.h"
#include "util_strings.h"

#define PHP_PACKAGE_NAME "laravel/lumen-framework"

/*
* Sets the web transaction name. If strip_base == true,
* leading class path components will be stripped.
Expand Down Expand Up @@ -232,7 +235,10 @@ void nr_lumen_enable(TSRMLS_D) {
#endif

if (NRINI(vulnerability_management_package_detection_enabled)) {
nr_txn_add_php_package(NRPRG(txn), "laravel/lumen-framework",
nr_txn_add_php_package(NRPRG(txn), PHP_PACKAGE_NAME,
PHP_PACKAGE_VERSION_UNKNOWN);
}

nr_txn_suggest_package_supportability_metric(NRPRG(txn), PHP_PACKAGE_NAME,
PHP_PACKAGE_VERSION_UNKNOWN);
}
4 changes: 2 additions & 2 deletions agent/fw_slim.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,8 @@ NR_PHP_WRAPPER(nr_slim_application_construct) {
nr_txn_add_php_package(NRPRG(txn), PHP_PACKAGE_NAME, version);
}

nr_fw_support_add_package_supportability_metric(NRPRG(txn), PHP_PACKAGE_NAME,
version);
nr_txn_suggest_package_supportability_metric(NRPRG(txn), PHP_PACKAGE_NAME,
version);

nr_free(version);
nr_php_scope_release(&this_var);
Expand Down
26 changes: 21 additions & 5 deletions agent/fw_support.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,23 +58,39 @@ void nr_fw_support_add_logging_supportability_metric(nrtxn_t* txn,
void nr_fw_support_add_package_supportability_metric(
nrtxn_t* txn,
const char* package_name,
const char* package_version) {
if (NULL == txn || NULL == package_name || NULL == package_version) {
const char* package_version,
nr_php_package_t* p) {
if (NULL == txn || NULL == package_name) {
return;
}

char* metname = NULL;
char major_version[MAJOR_VERSION_LENGTH] = {0};
const char* version = package_version;

// override provided package_version only if:
// - php_package is provided
// - its version is not NULL
// - its version is not PHP_PACKAGE_VERSION_UNKNOWN
if (NULL != p && NULL != p->package_version
&& 0 != nr_strcmp(p->package_version, PHP_PACKAGE_VERSION_UNKNOWN)) {
version = p->package_version;
}

// only generate metric if version is known
if (NULL == version || 0 == nr_strcmp(version, PHP_PACKAGE_VERSION_UNKNOWN)) {
return;
}

/* The below for loop checks if the major version of the package is more than
* one digit and keeps looping until a '.' is encountered or one of the
* conditions is met.
*/
for (int i = 0; package_version[i] && i < MAJOR_VERSION_LENGTH - 1; i++) {
if ('.' == package_version[i]) {
for (int i = 0; version[i] && i < MAJOR_VERSION_LENGTH - 1; i++) {
if ('.' == version[i]) {
break;
}
major_version[i] = package_version[i];
major_version[i] = version[i];
}

if (NR_FW_UNSET == NRINI(force_framework)) {
Expand Down
5 changes: 4 additions & 1 deletion agent/fw_support.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#define FW_SUPPORT_HDR

#include "php_user_instrument.h"
#include "nr_php_packages.h"

extern void nr_php_framework_add_supportability_metric(
const char* framework_name,
Expand Down Expand Up @@ -44,11 +45,13 @@ extern void nr_fw_support_add_logging_supportability_metric(
* Params : 1. Transaction object
* 2. Package name
* 3. Package version
* 4. PHP package reported for vulnerability management
*
*/
extern void nr_fw_support_add_package_supportability_metric(
nrtxn_t* txn,
const char* package_name,
const char* package_version);
const char* package_version,
nr_php_package_t* p);

#endif /* FW_SUPPORT_HDR */
7 changes: 6 additions & 1 deletion agent/fw_symfony4.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#include "fw_support.h"
#include "fw_symfony_common.h"

#define PHP_PACKAGE_NAME "symfony/http-kernel"

NR_PHP_WRAPPER(nr_symfony4_exception) {
int priority = nr_php_error_get_priority(E_ERROR);
zval* event = NULL;
Expand Down Expand Up @@ -277,7 +279,10 @@ void nr_symfony4_enable(TSRMLS_D) {
#endif

if (NRINI(vulnerability_management_package_detection_enabled)) {
nr_txn_add_php_package(NRPRG(txn), "symfony/http-kernel",
nr_txn_add_php_package(NRPRG(txn), PHP_PACKAGE_NAME,
PHP_PACKAGE_VERSION_UNKNOWN);
}

nr_txn_suggest_package_supportability_metric(NRPRG(txn), PHP_PACKAGE_NAME,
PHP_PACKAGE_VERSION_UNKNOWN);
}
8 changes: 4 additions & 4 deletions agent/fw_wordpress.c
Original file line number Diff line number Diff line change
Expand Up @@ -804,17 +804,17 @@ void nr_wordpress_version() {
"})();";

zval retval;
int result
= zend_eval_string(func_string, &retval, "Get Wordpress Version");
int result = zend_eval_string(func_string, &retval, "Get Wordpress Version");
// Add php package to transaction
if (SUCCESS == result) {
if (nr_php_is_zval_valid_string(&retval)) {
char* version = Z_STRVAL(retval);
if (NRINI(vulnerability_management_package_detection_enabled)) {
nr_txn_add_php_package(NRPRG(txn), PHP_PACKAGE_NAME, version);
}
nr_fw_support_add_package_supportability_metric(NRPRG(txn), PHP_PACKAGE_NAME,
version);

nr_txn_suggest_package_supportability_metric(NRPRG(txn), PHP_PACKAGE_NAME,
version);
}
zval_dtor(&retval);
}
Expand Down
9 changes: 9 additions & 0 deletions agent/fw_yii.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "util_memory.h"
#include "util_strings.h"

#define PHP_PACKAGE_NAME "yiisoft/yii2"
/*
* Yii1: Set the web transaction name from the controllerId + actionId combo.
*
Expand Down Expand Up @@ -221,4 +222,12 @@ void nr_yii2_enable(TSRMLS_D) {
nr_php_wrap_user_function(NR_PSTR("yii\\base\\ErrorHandler::logException"),
nr_yii2_error_handler_wrapper TSRMLS_CC);
#endif

if (NRINI(vulnerability_management_package_detection_enabled)) {
nr_txn_add_php_package(NRPRG(txn), PHP_PACKAGE_NAME,
PHP_PACKAGE_VERSION_UNKNOWN);
}

nr_txn_suggest_package_supportability_metric(NRPRG(txn), PHP_PACKAGE_NAME,
PHP_PACKAGE_VERSION_UNKNOWN);
}
6 changes: 4 additions & 2 deletions agent/lib_aws_sdk_php.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,10 @@ void nr_lib_aws_sdk_php_handle_version() {
/* Add php package to transaction */
nr_txn_add_php_package(NRPRG(txn), PHP_PACKAGE_NAME, version);
}
nr_fw_support_add_package_supportability_metric(NRPRG(txn), PHP_PACKAGE_NAME,
version);

nr_txn_suggest_package_supportability_metric(NRPRG(txn), PHP_PACKAGE_NAME,
version);

nr_php_zval_free(&zval_version);
}

Expand Down
Loading

0 comments on commit 498b8f3

Please sign in to comment.