Skip to content

Commit 9fa5e9e

Browse files
authored
Expand appsec integrations to Laminas Framework (#3716)
1 parent 09d8943 commit 9fa5e9e

55 files changed

Lines changed: 2329 additions & 5 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

appsec/src/extension/tags.c

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,8 @@ static THREAD_LOCAL_ON_ZTS bool _user_event_triggered;
146146
static THREAD_LOCAL_ON_ZTS bool _appsec_json_frags_inited;
147147
static THREAD_LOCAL_ON_ZTS zend_llist _appsec_json_frags;
148148
static THREAD_LOCAL_ON_ZTS zend_string *nullable _event_user_id;
149+
static THREAD_LOCAL_ON_ZTS zend_string *nullable
150+
_auth_user_event_automated_last_user_id;
149151

150152
static void _init_relevant_headers(void);
151153
static zend_string *_concat_json_fragments(void);
@@ -356,8 +358,9 @@ void dd_tags_rinit(void)
356358
_zend_string_release_indirect, 0);
357359
}
358360

359-
// Just in case...
361+
// Just in case (e.g. rinit without a prior rshutdown in edge paths)...
360362
_event_user_id = NULL;
363+
_auth_user_event_automated_last_user_id = NULL;
361364
}
362365

363366
void dd_tags_add_appsec_json_frag(zend_string *nonnull zstr)
@@ -368,6 +371,9 @@ void dd_tags_add_appsec_json_frag(zend_string *nonnull zstr)
368371

369372
void dd_tags_set_event_user_id(zend_string *nonnull zstr)
370373
{
374+
if (_event_user_id) {
375+
zend_string_release(_event_user_id);
376+
}
371377
_event_user_id = zend_string_copy(zstr);
372378
}
373379

@@ -379,6 +385,11 @@ void dd_tags_rshutdown(void)
379385
zend_string_release(_event_user_id);
380386
_event_user_id = NULL;
381387
}
388+
389+
if (_auth_user_event_automated_last_user_id) {
390+
zend_string_release(_auth_user_event_automated_last_user_id);
391+
_auth_user_event_automated_last_user_id = NULL;
392+
}
382393
}
383394

384395
void dd_tags_add_tags(
@@ -1533,6 +1544,11 @@ PHP_FUNCTION(datadog_appsec_internal_track_authenticated_user_event_automated)
15331544
return;
15341545
}
15351546

1547+
if (_auth_user_event_automated_last_user_id &&
1548+
zend_string_equals(user_id, _auth_user_event_automated_last_user_id)) {
1549+
return;
1550+
}
1551+
15361552
user_collection_mode mode = dd_get_user_collection_mode();
15371553
if (mode == user_mode_disabled ||
15381554
!get_DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING_ENABLED()) {
@@ -1573,6 +1589,11 @@ PHP_FUNCTION(datadog_appsec_internal_track_authenticated_user_event_automated)
15731589
// <DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING>
15741590
_add_new_zstr_to_meta(meta_ht, _dd_user_collection_mode,
15751591
dd_get_user_collection_mode_zstr(), true, false);
1592+
1593+
if (_auth_user_event_automated_last_user_id) {
1594+
zend_string_release(_auth_user_event_automated_last_user_id);
1595+
}
1596+
_auth_user_event_automated_last_user_id = zend_string_copy(user_id);
15761597
}
15771598

15781599
PHP_FUNCTION(datadog_appsec_track_authenticated_user_event)
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
--TEST--
2+
track_authenticated_user_event_automated dedupes helper request_exec for the same user id
3+
--INI--
4+
extension=ddtrace.so
5+
datadog.appsec.enabled=1
6+
--ENV--
7+
DD_APPSEC_ENABLED=1
8+
DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=ident
9+
--FILE--
10+
<?php
11+
12+
use function datadog\appsec\internal\track_authenticated_user_event_automated;
13+
use function datadog\appsec\testing\rinit;
14+
15+
include __DIR__ . '/inc/ddtrace_version.php';
16+
include __DIR__ . '/inc/mock_helper.php';
17+
18+
ddtrace_version_at_least('0.79.0');
19+
20+
$helper = Helper::createInitedRun([
21+
response_list(response_request_init([[['ok', []]]])),
22+
response_list(response_request_exec([[['ok', []]]])),
23+
], ['continuous' => true]);
24+
25+
rinit();
26+
$helper->get_commands(); // drain client_init + request_init (and any startup traffic)
27+
28+
track_authenticated_user_event_automated('test', 'sameUser');
29+
track_authenticated_user_event_automated('test', 'sameUser');
30+
31+
$commands = $helper->get_commands();
32+
$n = 0;
33+
foreach ($commands as $c) {
34+
if (is_array($c) && isset($c[0]) && $c[0] === 'request_exec') {
35+
$n++;
36+
}
37+
}
38+
echo "request_exec messages: {$n}\n";
39+
40+
$helper->finished_with_commands();
41+
?>
42+
--EXPECT--
43+
request_exec messages: 1
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
--TEST--
2+
Repeated track_authenticated_user_event_automated with same user id dedupes (single usr.id / no extra verdict work)
3+
--INI--
4+
extension=ddtrace.so
5+
--ENV--
6+
DD_APPSEC_ENABLED=1
7+
DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=ident
8+
--FILE--
9+
<?php
10+
11+
use function datadog\appsec\testing\root_span_get_meta;
12+
use function datadog\appsec\internal\track_authenticated_user_event_automated;
13+
14+
include __DIR__ . '/inc/ddtrace_version.php';
15+
16+
ddtrace_version_at_least('0.79.0');
17+
18+
track_authenticated_user_event_automated(
19+
'test',
20+
'sameUser'
21+
);
22+
track_authenticated_user_event_automated(
23+
'test',
24+
'sameUser'
25+
);
26+
27+
echo "root_span_get_meta():\n";
28+
print_r(root_span_get_meta());
29+
?>
30+
--EXPECTF--
31+
root_span_get_meta():
32+
Array
33+
(
34+
[runtime-id] => %s
35+
[usr.id] => sameUser
36+
[_dd.appsec.usr.id] => sameUser
37+
[_dd.appsec.user.collection_mode] => identification
38+
)
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
--TEST--
2+
track_authenticated_user_event_automated issues one request_exec per distinct user id
3+
--INI--
4+
extension=ddtrace.so
5+
datadog.appsec.enabled=1
6+
--ENV--
7+
DD_APPSEC_ENABLED=1
8+
DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=ident
9+
--FILE--
10+
<?php
11+
12+
use function datadog\appsec\internal\track_authenticated_user_event_automated;
13+
use function datadog\appsec\testing\rinit;
14+
15+
include __DIR__ . '/inc/ddtrace_version.php';
16+
include __DIR__ . '/inc/mock_helper.php';
17+
18+
ddtrace_version_at_least('0.79.0');
19+
20+
$helper = Helper::createInitedRun([
21+
response_list(response_request_init([[['ok', []]]])),
22+
response_list(response_request_exec([[['ok', []]]])),
23+
response_list(response_request_exec([[['ok', []]]])),
24+
], ['continuous' => true]);
25+
26+
rinit();
27+
$helper->get_commands();
28+
29+
track_authenticated_user_event_automated('test', 'userA');
30+
track_authenticated_user_event_automated('test', 'userB');
31+
32+
$commands = $helper->get_commands();
33+
$n = 0;
34+
foreach ($commands as $c) {
35+
if (is_array($c) && isset($c[0]) && $c[0] === 'request_exec') {
36+
$n++;
37+
}
38+
}
39+
echo "request_exec messages: {$n}\n";
40+
41+
$helper->finished_with_commands();
42+
?>
43+
--EXPECT--
44+
request_exec messages: 2

0 commit comments

Comments
 (0)