Skip to content

Commit

Permalink
Add asm event to propagated tags
Browse files Browse the repository at this point in the history
  • Loading branch information
estringana committed Nov 8, 2024
1 parent 8b6bafc commit f62483e
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 4 deletions.
28 changes: 28 additions & 0 deletions appsec/src/extension/ddtrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ static zend_string *_ddtrace_root_span_fname;
static zend_string *_meta_propname;
static zend_string *_metrics_propname;
static zend_string *_meta_struct_propname;
static zend_string *_propagated_tags_propname;
static THREAD_LOCAL_ON_ZTS bool _suppress_ddtrace_rshutdown;
static uint8_t *_ddtrace_runtime_id = NULL;

Expand All @@ -40,6 +41,8 @@ static void (*nullable _ddtrace_close_all_spans_and_flush)(void);
static void (*nullable _ddtrace_set_priority_sampling_on_span_zobj)(
zend_object *nonnull zobj, zend_long priority,
enum dd_sampling_mechanism mechanism);
static void (*nullable _ddtrace_add_propagated_tag_on_span_zobj)(
zend_string *nonnull key, zval *nonnull value);

static bool (*nullable _ddtrace_user_req_add_listeners)(
ddtrace_user_req_listeners *listeners);
Expand Down Expand Up @@ -88,6 +91,14 @@ static void dd_trace_load_symbols(void)
dlerror()); // NOLINT(concurrency-mt-unsafe)
}

_ddtrace_add_propagated_tag_on_span_zobj =
dlsym(handle, "ddtrace_add_propagated_tag_on_span_zobj");
if (_ddtrace_add_propagated_tag_on_span_zobj == NULL) {
mlog(dd_log_error,
"Failed to load ddtrace_add_propagated_tag_on_span_zobj: %s",
dlerror()); // NOLINT(concurrency-mt-unsafe)
}

_ddtrace_user_req_add_listeners =
dlsym(handle, "ddtrace_user_req_add_listeners");
if (_ddtrace_user_req_add_listeners == NULL) {
Expand Down Expand Up @@ -120,6 +131,8 @@ void dd_trace_startup()
_metrics_propname = zend_string_init_interned(LSTRARG("metrics"), 1);
_meta_struct_propname =
zend_string_init_interned(LSTRARG("meta_struct"), 1);
_propagated_tags_propname =
zend_string_init_interned(LSTRARG("propagated_tags"), 1);

if (get_global_DD_APPSEC_TESTING()) {
_register_testing_objects();
Expand Down Expand Up @@ -304,6 +317,11 @@ zval *nullable dd_trace_span_get_meta_struct(zend_object *nonnull zobj)
return _get_span_modifiable_array_property(zobj, _meta_struct_propname);
}

zval *nullable dd_trace_span_get_propagated_tags(zend_object *nonnull zobj)
{
return _get_span_modifiable_array_property(zobj, _propagated_tags_propname);
}

// NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers)
zend_string *nullable dd_trace_get_formatted_runtime_id(bool persistent)
{
Expand Down Expand Up @@ -379,6 +397,16 @@ const char *nullable dd_trace_remote_config_get_path()
return path;
}

void dd_trace_span_add_propagated_tags(
zend_string *nonnull key, zval *nonnull value)
{
if (UNEXPECTED(_ddtrace_add_propagated_tag_on_span_zobj == NULL)) {
return;
}

_ddtrace_add_propagated_tag_on_span_zobj(key, value);
}

static PHP_FUNCTION(datadog_appsec_testing_ddtrace_rshutdown)
{
if (zend_parse_parameters_none() == FAILURE) {
Expand Down
1 change: 1 addition & 0 deletions appsec/src/extension/ddtrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ void dd_trace_close_all_spans_and_flush(void);
zval *nullable dd_trace_span_get_meta(zend_object *nonnull);
zval *nullable dd_trace_span_get_metrics(zend_object *nonnull);
zval *nullable dd_trace_span_get_meta_struct(zend_object *nonnull);
void dd_trace_span_add_propagated_tags(zend_string *nonnull key, zval *nonnull value);
zend_string *nullable dd_trace_get_formatted_runtime_id(bool persistent);

// Set sampling priority on root span
Expand Down
18 changes: 14 additions & 4 deletions appsec/src/extension/tags.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ static THREAD_LOCAL_ON_ZTS bool _appsec_json_frags_inited;
static THREAD_LOCAL_ON_ZTS zend_llist _appsec_json_frags;
static THREAD_LOCAL_ON_ZTS zend_string *nullable _event_user_id;
static THREAD_LOCAL_ON_ZTS bool _blocked;
static THREAD_LOCAL_ON_ZTS bool _asm_event;
static THREAD_LOCAL_ON_ZTS bool _asm_event_propagated;
static THREAD_LOCAL_ON_ZTS bool _force_keep;

static void _init_relevant_headers(void);
Expand Down Expand Up @@ -295,8 +295,8 @@ void dd_tags_rinit()
// Just in case...
_event_user_id = NULL;
_blocked = false;
_asm_event = false;
_force_keep = false;
_asm_event_propagated = false;
}

void dd_tags_add_appsec_json_frag(zend_string *nonnull zstr)
Expand All @@ -321,6 +321,9 @@ void dd_tags_rshutdown()

void dd_appsec_add_asm_event()
{
if (_asm_event_propagated) {
return;
}
zval *nullable meta = _root_span_get_meta();
if (meta && Z_TYPE_P(meta) == IS_ARRAY) {
zend_array *meta_ht = Z_ARRVAL_P(meta);
Expand All @@ -329,6 +332,11 @@ void dd_appsec_add_asm_event()
_add_new_zstr_to_meta(
meta_ht, _dd_tag_p_appsec_zstr, _1_zstr, true, false);
}

zval _1_zval;
ZVAL_STR(&_1_zval, _1_zstr);
dd_trace_span_add_propagated_tags(_dd_tag_p_appsec_zstr, &_1_zval);
_asm_event_propagated = true;
}

void dd_tags_add_tags(
Expand Down Expand Up @@ -890,13 +898,15 @@ static zval *nullable _root_span_get_meta()
{
zend_object *nullable span = dd_req_lifecycle_get_cur_span();
if (!span) {
mlog(dd_log_warning, "No root span being tracked by appsec");
// TODO Uncomment this
// mlog(dd_log_warning, "No root span being tracked by appsec");
return NULL;
}

zval *nullable meta = dd_trace_span_get_meta(span);
if (!meta) {
mlog(dd_log_warning, "Failed to retrieve root span meta");
// TODO Uncomment this
// mlog(dd_log_warning, "Failed to retrieve root span meta");
}
return meta;
}
Expand Down
66 changes: 66 additions & 0 deletions appsec/tests/extension/rinit_asm_events_propagate_tags.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
--TEST--
Asm events are added as meta tags and also as propagated tags
--INI--
extension=ddtrace.so
datadog.appsec.log_file=/tmp/php_appsec_test.log
datadog.appsec.log_level=debug
datadog.appsec.enabled=1
--ENV--
HTTP_X_DATADOG_TRACE_ID=42
HTTP_X_DATADOG_PARENT_ID=10
HTTP_X_DATADOG_ORIGIN=datadog
HTTP_X_DATADOG_TAGS=_dd.p.custom_tag=inherited,_dd.p.second_tag=bar
--FILE--
<?php
use function datadog\appsec\testing\{rinit,rshutdown,ddtrace_rshutdown,root_span_get_meta};
include __DIR__ . '/inc/ddtrace_version.php';

ddtrace_version_at_least('0.79.0');

include __DIR__ . '/inc/mock_helper.php';

$helper = Helper::createInitedRun([
response_list(response_request_init([[['record', []]], ['{"found":"attack"}','{"another":"attack"}']])),
response_list(
response_request_shutdown(
[[['record', []]], ['{"yet another":"attack"}'], false, ["rshutdown_tag" => "rshutdown_value"], ["rshutdown_metric" => 2.1]]
)
),
], ['continuous' => true]);

echo "rinit\n";
var_dump(rinit());
$helper->get_commands(); //ignore

$context = DDTrace\current_context();
echo "_dd.p.appsec on distributed propagated tags? ";
echo isset($context['distributed_tracing_propagated_tags']['_dd.p.appsec']) && $context['distributed_tracing_propagated_tags']['_dd.p.appsec'] == 1 ? "Yes": "No";
echo PHP_EOL;

echo "rshutdown\n";
var_dump(rshutdown());
$helper->get_commands(); //ignore

echo "ddtrace_rshutdown\n";
var_dump(ddtrace_rshutdown());
dd_trace_internal_fn('synchronous_flush');

$commands = $helper->get_commands();
$tags = $commands[0]['payload'][0][0]['meta'];

echo "_dd.p.appsec? ";
echo isset($tags['_dd.p.appsec']) && $tags['_dd.p.appsec'] === "1" ? "Yes": "No";
echo PHP_EOL;

$helper->finished_with_commands();

?>
--EXPECTF--
rinit
bool(true)
_dd.p.appsec on distributed propagated tags? Yes
rshutdown
bool(true)
ddtrace_rshutdown
bool(true)
_dd.p.appsec? Yes
1 change: 1 addition & 0 deletions ddtrace.sym
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ ddtrace_close_all_spans_and_flush
ddtrace_get_profiling_context
ddtrace_get_root_span
ddtrace_set_priority_sampling_on_span_zobj
ddtrace_add_propagated_tag_on_span_zobj
ddtrace_runtime_id
ddtrace_user_req_add_listeners
ddtrace_ip_extraction_find
Expand Down
15 changes: 15 additions & 0 deletions ext/tracer_tag_propagation/tracer_tag_propagation.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,3 +182,18 @@ zend_string *ddtrace_format_propagated_tags(zend_array *propagated, zend_array *
smart_str_0(&taglist);
return taglist.s;
}

DDTRACE_PUBLIC void ddtrace_add_propagated_tag_on_span_zobj(zend_string *key, zval *value) {
ddtrace_root_span_data *root_span = DDTRACE_G(active_stack)->root_span;
zend_array *root_meta = &DDTRACE_G(root_span_tags_preset);
zend_array *propagated_tags = &DDTRACE_G(propagated_root_span_tags);
if (root_span) {
root_meta = ddtrace_property_array(&root_span->property_meta);
propagated_tags = ddtrace_property_array(&root_span->property_propagated_tags);
}

zval tagstr;
ddtrace_convert_to_string(&tagstr, value);
zend_hash_update(root_meta, key, &tagstr);
zend_hash_add_empty_element(propagated_tags, key);
}
3 changes: 3 additions & 0 deletions ext/tracer_tag_propagation/tracer_tag_propagation.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@

#include <php.h>

#include "../ddtrace_export.h"

void ddtrace_clean_tracer_tags(zend_array *root_meta, zend_array *propagated_tags);
void ddtrace_add_tracer_tags_from_header(zend_string *headerstr, zend_array *root_meta, zend_array *propagated_tags);
void ddtrace_add_tracer_tags_from_array(zend_array *array, zend_array *root_meta, zend_array *propagated_tags);
DDTRACE_PUBLIC void ddtrace_add_propagated_tag_on_span_zobj(zend_string *key, zval *value);

void ddtrace_get_propagated_tags(zend_array *tags);
zend_string *ddtrace_format_root_propagated_tags(void);
Expand Down

0 comments on commit f62483e

Please sign in to comment.