Description
When before_send modifies values on an event, the changes can leak back into the scope.
user and fingerprint are placed into the event by reference (PLACE_VALUE) rather than being cloned, so any modification corrupts the scope directly.
tags, extra, and contexts use PLACE_CLONED_VALUE, but sentry__value_clone() only performs a shallow clone so modifying a nested object still mutates the scope's original.
When does the problem happen
Steps To Reproduce
#include <stdio.h>
#include <sentry.h>
sentry_value_t before_send(sentry_value_t event, void *hint, void *user_data)
{
sentry_value_t user = sentry_value_get_by_key(event, "user");
char* original = sentry_value_to_json(user);
sentry_value_set_by_key(user, "email", sentry_value_new_string("redacted"));
char* redacted = sentry_value_to_json(user);
fprintf(stderr, "%s ==> %s\n", original, redacted);
sentry_free(original);
sentry_free(redacted);
return event;
}
int main(int argc, char *argv[])
{
sentry_options_t *options = sentry_options_new();
sentry_options_set_dsn(options, SENTRY_DSN);
sentry_options_set_before_send(options, before_send, nullptr);
sentry_init(options);
sentry_set_user(sentry_value_new_user(NULL, "somebody", "somebody@example.com", NULL));
sentry_capture_event(sentry_value_new_event()); // {"username":"somebody","email":"somebody@example.com"} ==> {"username":"somebody","email":"redacted"}
sentry_capture_event(sentry_value_new_event()); // {"username":"somebody","email":"redacted"} ==> {"username":"somebody","email":"redacted"}
sentry_close();
}
Log output
Expected output:
{"username":"somebody","email":"somebody@example.com"} ==> {"username":"somebody","email":"redacted"}
{"username":"somebody","email":"somebody@example.com"} ==> {"username":"somebody","email":"redacted"}
Actual output:
{"username":"somebody","email":"somebody@example.com"} ==> {"username":"somebody","email":"redacted"}
{"username":"somebody","email":"redacted"} ==> {"username":"somebody","email":"redacted"}
The second before_send receives "redacted" as the original email because the first before_send mutated the scope's user object in place.
Description
When
before_sendmodifies values on an event, the changes can leak back into the scope.userandfingerprintare placed into the event by reference (PLACE_VALUE) rather than being cloned, so any modification corrupts the scope directly.tags,extra, andcontextsusePLACE_CLONED_VALUE, butsentry__value_clone()only performs a shallow clone so modifying a nested object still mutates the scope's original.When does the problem happen
Steps To Reproduce
Log output
Expected output:
Actual output:
The second
before_sendreceives "redacted" as the original email because the firstbefore_sendmutated the scope's user object in place.