diff --git a/appsec/tests/extension/push_params_block_02.phpt b/appsec/tests/extension/push_params_block_02.phpt
new file mode 100644
index 0000000000..a11c052a8f
--- /dev/null
+++ b/appsec/tests/extension/push_params_block_02.phpt
@@ -0,0 +1,43 @@
+--TEST--
+Push address gets blocked even when within a hook
+--INI--
+extension=ddtrace.so
+datadog.appsec.enabled=1
+--FILE--
+ '404', 'type' => 'html']]], ['{"found":"attack"}','{"another":"attack"}']])),
+]);
+rinit();
+
+class SomeIntegration {
+ public function init()
+ {
+ DDTrace\install_hook("ltrim", self::hooked_function(), null);
+ }
+
+ private static function hooked_function()
+ {
+ return static function (DDTrace\HookData $hook) {
+ push_address("server.request.path_params", ["some" => "params", "more" => "parameters"]);
+ var_dump("This should be executed");
+ };
+ }
+}
+
+$integration = new SomeIntegration();
+$integration->init();
+var_dump(ltrim(" Calling wrapped function"));
+var_dump("THIS SHOULD NOT GET IN THE OUTPUT");
+?>
+--EXPECTHEADERS--
+Status: 404 Not Found
+Content-type: text/html;charset=UTF-8
+--EXPECTF--
+
You've been blockedSorry, you cannot access this page. Please contact the customer service team.
\ No newline at end of file
diff --git a/appsec/tests/extension/push_params_block_03.phpt b/appsec/tests/extension/push_params_block_03.phpt
new file mode 100644
index 0000000000..eba1d26d4a
--- /dev/null
+++ b/appsec/tests/extension/push_params_block_03.phpt
@@ -0,0 +1,43 @@
+--TEST--
+Push address gets blocked even when within a hook
+--INI--
+extension=ddtrace.so
+datadog.appsec.enabled=1
+--FILE--
+ '404', 'type' => 'html']]], ['{"found":"attack"}','{"another":"attack"}']])),
+]);
+rinit();
+
+class SomeIntegration {
+ public function init()
+ {
+ DDTrace\install_hook("ltrim", self::hooked_function(), null);
+ }
+
+ private static function hooked_function()
+ {
+ return static function (DDTrace\HookData $hook) {
+ push_address("server.request.path_params", ["some" => "params", "more" => "parameters"]);
+ var_dump("This should be executed");
+ };
+ }
+}
+
+$integration = new SomeIntegration();
+$integration->init();
+echo "Something here to force partially booking";
+var_dump(ltrim(" Calling wrapped function"));
+var_dump("THIS SHOULD NOT GET IN THE OUTPUT");
+?>
+--EXPECTHEADERS--
+Content-type: text/html; charset=UTF-8
+--EXPECTF--
+Something here to force partially booking
\ No newline at end of file
diff --git a/zend_abstract_interface/sandbox/php7/sandbox.c b/zend_abstract_interface/sandbox/php7/sandbox.c
index dadc09afa5..e6efd13e16 100644
--- a/zend_abstract_interface/sandbox/php7/sandbox.c
+++ b/zend_abstract_interface/sandbox/php7/sandbox.c
@@ -6,6 +6,7 @@ extern inline void zai_sandbox_open(zai_sandbox *sandbox);
extern inline void zai_sandbox_close(zai_sandbox *sandbox);
extern inline void zai_sandbox_bailout(zai_sandbox *sandbox);
extern inline bool zai_sandbox_timed_out(void);
+extern inline bool zai_is_request_blocked(void);
extern inline void zai_sandbox_error_state_backup(zai_error_state *es);
extern inline void zai_sandbox_error_state_restore(zai_error_state *es);
diff --git a/zend_abstract_interface/sandbox/php8/sandbox.c b/zend_abstract_interface/sandbox/php8/sandbox.c
index 92fc0589ea..ddd93bb2b1 100644
--- a/zend_abstract_interface/sandbox/php8/sandbox.c
+++ b/zend_abstract_interface/sandbox/php8/sandbox.c
@@ -7,6 +7,7 @@ extern inline void zai_sandbox_open(zai_sandbox *sandbox);
extern inline void zai_sandbox_close(zai_sandbox *sandbox);
extern inline void zai_sandbox_bailout(zai_sandbox *sandbox);
extern inline bool zai_sandbox_timed_out(void);
+extern inline bool zai_is_request_blocked(void);
extern inline void zai_sandbox_error_state_backup(zai_error_state *es);
diff --git a/zend_abstract_interface/sandbox/sandbox.h b/zend_abstract_interface/sandbox/sandbox.h
index c441b5bc16..4ce65f4b9c 100644
--- a/zend_abstract_interface/sandbox/sandbox.h
+++ b/zend_abstract_interface/sandbox/sandbox.h
@@ -76,7 +76,9 @@
*
* This function should be invoked when a bailout has been caught.
*
- * It will restore engine state and continue in all but the case of a timeout
+ * It will restore engine state and continue in all cases except:
+ * - Timeout
+ * - Request is blocked by the extension
*/
/* ######### Timeout ##########
@@ -218,8 +220,25 @@ inline bool zai_sandbox_timed_out(void) {
return false;
}
+inline bool zai_is_request_blocked(void)
+{
+ if (!PG(last_error_message)) {
+ return false;
+ }
+
+ if (strcmp("Datadog blocked the request and presented a static error page", ZSTR_VAL(PG(last_error_message))) == 0) {
+ return true;
+ }
+
+ if (strcmp("Datadog blocked the request, but the response has already been partially committed", ZSTR_VAL(PG(last_error_message))) == 0) {
+ return true;
+ }
+
+ return false;
+}
+
inline void zai_sandbox_bailout(zai_sandbox *sandbox) {
- if (!zai_sandbox_timed_out()) {
+ if (!zai_sandbox_timed_out() && !zai_is_request_blocked()) {
zai_sandbox_engine_state_restore(&sandbox->engine_state);
return;
@@ -356,8 +375,25 @@ inline bool zai_sandbox_timed_out(void) {
return false;
}
+inline bool zai_is_request_blocked(void)
+{
+ if (!PG(last_error_message)) {
+ return false;
+ }
+
+ if (strcmp("Datadog blocked the request and presented a static error page", ZSTR_VAL(PG(last_error_message))) == 0) {
+ return true;
+ }
+
+ if (strcmp("Datadog blocked the request, but the response has already been partially committed", ZSTR_VAL(PG(last_error_message))) == 0) {
+ return true;
+ }
+
+ return false;
+}
+
inline void zai_sandbox_bailout(zai_sandbox *sandbox) {
- if (!zai_sandbox_timed_out()) {
+ if (!zai_sandbox_timed_out() && !zai_is_request_blocked()) {
zai_sandbox_engine_state_restore(&sandbox->engine_state);
return;