Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement SSRF #3014

Merged
merged 13 commits into from
Jan 29, 2025
25 changes: 10 additions & 15 deletions appsec/src/extension/ddappsec.c
Original file line number Diff line number Diff line change
Expand Up @@ -474,23 +474,22 @@ static PHP_FUNCTION(datadog_appsec_testing_request_exec)
RETURN_TRUE;
}

static PHP_FUNCTION(datadog_appsec_push_address)
static PHP_FUNCTION(datadog_appsec_push_addresses)
{
struct timespec start;
struct timespec end;
clock_gettime(CLOCK_MONOTONIC_RAW, &start);
long elapsed = 0;
UNUSED(return_value);
if (!DDAPPSEC_G(active)) {
mlog(dd_log_debug, "Trying to access to push_address "
mlog(dd_log_debug, "Trying to access to push_addresses "
"function while appsec is disabled");
return;
}

zend_string *key = NULL;
zval *value = NULL;
HashTable *addresses = NULL;
bool rasp = false;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "Sz|b", &key, &value, &rasp) ==
if (zend_parse_parameters(ZEND_NUM_ARGS(), "h|b", &addresses, &rasp) ==
FAILURE) {
RETURN_FALSE;
}
Expand All @@ -500,20 +499,16 @@ static PHP_FUNCTION(datadog_appsec_push_address)
}

zval parameters_zv;
zend_array *parameters_arr = zend_new_array(1);
ZVAL_ARR(&parameters_zv, parameters_arr);
zend_hash_add(Z_ARRVAL(parameters_zv), key, value);
Z_TRY_ADDREF_P(value);
ZVAL_ARR(&parameters_zv, addresses);

dd_conn *conn = dd_helper_mgr_cur_conn();
if (conn == NULL) {
zval_ptr_dtor(&parameters_zv);
mlog_g(dd_log_debug, "No connection; skipping push_address");
mlog_g(dd_log_debug, "No connection; skipping push_addresses");
return;
}

dd_result res = dd_request_exec(conn, &parameters_zv, rasp);
zval_ptr_dtor(&parameters_zv);
estringana marked this conversation as resolved.
Show resolved Hide resolved

if (rasp) {
clock_gettime(CLOCK_MONOTONIC_RAW, &end);
Expand Down Expand Up @@ -549,16 +544,16 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(request_exec_arginfo, 0, 1, _IS_BOOL, 0)
ZEND_ARG_INFO(0, "data")
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(push_address_arginfo, 0, 0, IS_VOID, 1)
ZEND_ARG_INFO(0, key)
ZEND_ARG_INFO(0, value)
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(
push_addresses_arginfo, 0, 0, IS_VOID, 1)
ZEND_ARG_INFO(0, addresses)
ZEND_ARG_INFO(0, rasp)
ZEND_END_ARG_INFO()

// clang-format off
static const zend_function_entry functions[] = {
ZEND_RAW_FENTRY(DD_APPSEC_NS "is_enabled", PHP_FN(datadog_appsec_is_enabled), void_ret_bool_arginfo, 0, NULL, NULL)
ZEND_RAW_FENTRY(DD_APPSEC_NS "push_address", PHP_FN(datadog_appsec_push_address), push_address_arginfo, 0, NULL, NULL)
ZEND_RAW_FENTRY(DD_APPSEC_NS "push_addresses", PHP_FN(datadog_appsec_push_addresses), push_addresses_arginfo, 0, NULL, NULL)
PHP_FE_END
};
static const zend_function_entry testing_functions[] = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class engine_listener : public listener_base {
[[nodiscard]] std::unordered_set<product> get_supported_products() override
{
return {known_products::ASM, known_products::ASM_DD,
known_products::ASM_DATA, known_products::ASM_RASP_LFI};
known_products::ASM_DATA};
}

protected:
Expand Down
6 changes: 0 additions & 6 deletions appsec/src/helper/remote_config/product.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@ struct known_products {
static inline constexpr product ASM_DATA{std::string_view{"ASM_DATA"}};
static inline constexpr product ASM_FEATURES{
std::string_view{"ASM_FEATURES"}};
static inline constexpr product ASM_RASP_LFI{
std::string_view{"ASM_RASP_LFI"}};
static inline constexpr product UNKNOWN{std::string_view{"UNKOWN"}};

static product for_name(std::string_view name)
Expand All @@ -47,10 +45,6 @@ struct known_products {
if (name == ASM_FEATURES.name()) {
return ASM_FEATURES;
}
if (name == ASM_RASP_LFI.name()) {
return ASM_RASP_LFI;
}

return UNKNOWN;
}
};
Expand Down
4 changes: 2 additions & 2 deletions appsec/tests/extension/actions_handling_01.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ datadog.appsec.enabled=1
--FILE--
<?php
use function datadog\appsec\testing\{rinit,rshutdown};
use function datadog\appsec\push_address;
use function datadog\appsec\push_addresses;

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

Expand All @@ -17,7 +17,7 @@ $helper = Helper::createInitedRun([
]);

var_dump(rinit());
push_address("server.request.path_params", ["some" => "params", "more" => "parameters"]);
push_addresses(["server.request.path_params" => ["some" => "params", "more" => "parameters"]]);
var_dump(rshutdown());

var_dump($helper->get_command("request_exec"));
Expand Down
6 changes: 3 additions & 3 deletions appsec/tests/extension/push_params_block.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ datadog.appsec.enabled=1
--FILE--
<?php
use function datadog\appsec\testing\{rinit,rshutdown};
use function datadog\appsec\push_address;
use function datadog\appsec\push_addresses;

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

Expand All @@ -16,7 +16,7 @@ $helper = Helper::createInitedRun([
]);

rinit();
push_address("server.request.path_params", ["some" => "params", "more" => "parameters"]);
push_addresses(["server.request.path_params" => ["some" => "params", "more" => "parameters"]]);

var_dump("THIS SHOULD NOT GET IN THE OUTPUT");

Expand All @@ -26,4 +26,4 @@ Status: 404 Not Found
Content-type: application/json
--EXPECTF--
{"errors": [{"title": "You've been blocked", "detail": "Sorry, you cannot access this page. Please contact the customer service team. Security provided by Datadog."}]}
Warning: datadog\appsec\push_address(): Datadog blocked the request and presented a static error page in %s on line %d
Warning: datadog\appsec\push_addresses(): Datadog blocked the request and presented a static error page in %s on line %d
4 changes: 2 additions & 2 deletions appsec/tests/extension/push_params_block_02.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ datadog.appsec.enabled=1
--FILE--
<?php
use function datadog\appsec\testing\{rinit,rshutdown};
use function datadog\appsec\push_address;
use function datadog\appsec\push_addresses;

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

Expand All @@ -25,7 +25,7 @@ class SomeIntegration {
private static function hooked_function()
{
return static function (DDTrace\HookData $hook) {
push_address("server.request.path_params", ["some" => "params", "more" => "parameters"]);
push_addresses(["server.request.path_params", ["some" => "params", "more" => "parameters"]]);
var_dump("This should be executed");
};
}
Expand Down
4 changes: 2 additions & 2 deletions appsec/tests/extension/push_params_block_03.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ datadog.appsec.enabled=1
--FILE--
<?php
use function datadog\appsec\testing\{rinit,rshutdown};
use function datadog\appsec\push_address;
use function datadog\appsec\push_addresses;

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

Expand All @@ -25,7 +25,7 @@ class SomeIntegration {
private static function hooked_function()
{
return static function (DDTrace\HookData $hook) {
push_address("server.request.path_params", ["some" => "params", "more" => "parameters"]);
push_addresses(["server.request.path_params", ["some" => "params", "more" => "parameters"]]);
var_dump("This should be executed");
};
}
Expand Down
4 changes: 2 additions & 2 deletions appsec/tests/extension/push_params_ok_01.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ datadog.appsec.enabled=1
--FILE--
<?php
use function datadog\appsec\testing\{rinit,rshutdown};
use function datadog\appsec\push_address;
use function datadog\appsec\push_addresses;

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

Expand All @@ -17,7 +17,7 @@ $helper = Helper::createInitedRun([
]);

var_dump(rinit());
push_address("server.request.path_params", ["some" => "params", "more" => "parameters"]);
push_addresses(["server.request.path_params" => ["some" => "params", "more" => "parameters"]]);
var_dump(rshutdown());

var_dump($helper->get_command("request_exec"));
Expand Down
4 changes: 2 additions & 2 deletions appsec/tests/extension/push_params_ok_02.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ datadog.appsec.enabled=1
--FILE--
<?php
use function datadog\appsec\testing\{rinit,rshutdown};
use function datadog\appsec\push_address;
use function datadog\appsec\push_addresses;

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

Expand All @@ -17,7 +17,7 @@ $helper = Helper::createInitedRun([
]);

var_dump(rinit());
push_address("server.request.path_params", "some string");
push_addresses(["server.request.path_params" => "some string"]);
var_dump(rshutdown());

var_dump($helper->get_command("request_exec"));
Expand Down
4 changes: 2 additions & 2 deletions appsec/tests/extension/push_params_ok_03.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ datadog.appsec.enabled=1
--FILE--
<?php
use function datadog\appsec\testing\{rinit,rshutdown};
use function datadog\appsec\push_address;
use function datadog\appsec\push_addresses;

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

Expand All @@ -17,7 +17,7 @@ $helper = Helper::createInitedRun([
]);

var_dump(rinit());
push_address("server.request.path_params", 1234);
push_addresses(["server.request.path_params" => 1234]);
var_dump(rshutdown());

var_dump($helper->get_command("request_exec"));
Expand Down
4 changes: 2 additions & 2 deletions appsec/tests/extension/push_params_ok_04.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ datadog.appsec.rasp_enabled=1
--FILE--
<?php
use function datadog\appsec\testing\{rinit,rshutdown, root_span_get_metrics};
use function datadog\appsec\push_address;
use function datadog\appsec\push_addresses;

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

Expand All @@ -19,7 +19,7 @@ $helper = Helper::createInitedRun([

var_dump(rinit());
$is_rasp = true;
push_address("server.request.path_params", 1234, $is_rasp);
push_addresses(["server.request.path_params" => 1234], $is_rasp);
var_dump(rshutdown());
print_r(root_span_get_metrics());

Expand Down
4 changes: 2 additions & 2 deletions appsec/tests/extension/push_params_ok_05.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ DD_APPSEC_RASP_ENABLED=false
--FILE--
<?php
use function datadog\appsec\testing\{rinit,rshutdown,root_span_get_metrics};
use function datadog\appsec\push_address;
use function datadog\appsec\push_addresses;

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

Expand All @@ -19,7 +19,7 @@ $helper = Helper::createInitedRun([

var_dump(rinit());
$is_rasp = true;
push_address("server.request.path_params", 1234, $is_rasp);
push_addresses(["server.request.path_params" => 1234], $is_rasp);
var_dump(rshutdown());
print_r(root_span_get_metrics());

Expand Down
4 changes: 2 additions & 2 deletions appsec/tests/extension/push_params_ok_06.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ datadog.appsec.enabled=1
--FILE--
<?php
use function datadog\appsec\testing\{rinit,rshutdown,root_span_get_metrics};
use function datadog\appsec\push_address;
use function datadog\appsec\push_addresses;

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

Expand All @@ -17,7 +17,7 @@ $helper = Helper::createInitedRun([

var_dump(rinit());
$is_rasp = true;
push_address("server.request.path_params", 1234, $is_rasp);
push_addresses(["server.request.path_params" => 1234], $is_rasp);
var_dump(rshutdown());
print_r(root_span_get_metrics());

Expand Down
49 changes: 49 additions & 0 deletions appsec/tests/extension/push_params_ok_07.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
--TEST--
Multiple addresses can be sent at once
--INI--
extension=ddtrace.so
datadog.appsec.enabled=1
--FILE--
<?php
use function datadog\appsec\testing\{rinit,rshutdown};
use function datadog\appsec\push_addresses;

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

$helper = Helper::createInitedRun([
response_list(response_request_init([[['ok', []]]])),
response_list(response_request_exec([[['ok', []]], [], [], [], false])),
response_list(response_request_shutdown([[['ok', []]], new ArrayObject(), new ArrayObject()]))
]);

var_dump(rinit());
push_addresses(["server.request.path_params" => ["some" => "params", "more" => "parameters"], "some.other" => 12345]);
var_dump(rshutdown());

var_dump($helper->get_command("request_exec"));

?>
--EXPECTF--
bool(true)
bool(true)
array(2) {
[0]=>
string(12) "request_exec"
[1]=>
array(2) {
[0]=>
bool(false)
[1]=>
array(2) {
["server.request.path_params"]=>
array(2) {
["some"]=>
string(6) "params"
["more"]=>
string(10) "parameters"
}
["some.other"]=>
int(12345)
}
}
}
6 changes: 3 additions & 3 deletions appsec/tests/extension/push_params_redirect_01.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ datadog.appsec.enabled=1
--FILE--
<?php
use function datadog\appsec\testing\{rinit,rshutdown};
use function datadog\appsec\push_address;
use function datadog\appsec\push_addresses;

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

Expand All @@ -16,7 +16,7 @@ $helper = Helper::createInitedRun([
]);

rinit();
push_address("server.request.path_params", ["some" => "params", "more" => "parameters"]);
push_addresses(["server.request.path_params" => ["some" => "params", "more" => "parameters"]]);

var_dump("THIS SHOULD NOT GET IN THE OUTPUT");

Expand All @@ -25,4 +25,4 @@ var_dump("THIS SHOULD NOT GET IN THE OUTPUT");
Status: 303 See Other
Content-type: text/html; charset=UTF-8
--EXPECTF--
Warning: datadog\appsec\push_address(): Datadog blocked the request and attempted a redirection to https://datadoghq.com in %s on line %d
Warning: datadog\appsec\push_addresses(): Datadog blocked the request and attempted a redirection to https://datadoghq.com in %s on line %d
4 changes: 2 additions & 2 deletions appsec/tests/extension/push_params_redirect_02.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ datadog.appsec.enabled=1
--FILE--
<?php
use function datadog\appsec\testing\{rinit,rshutdown};
use function datadog\appsec\push_address;
use function datadog\appsec\push_addresses;

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

Expand All @@ -25,7 +25,7 @@ class SomeIntegration {
private static function hooked_function()
{
return static function (DDTrace\HookData $hook) {
push_address("server.request.path_params", ["some" => "params", "more" => "parameters"]);
push_addresses(["server.request.path_params", ["some" => "params", "more" => "parameters"]]);
var_dump("This should be executed");
};
}
Expand Down
4 changes: 2 additions & 2 deletions appsec/tests/extension/report_backtrace_05.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ datadog.appsec.enabled=1
--FILE--
<?php
use function datadog\appsec\testing\{rinit,rshutdown};
use function datadog\appsec\push_address;
use function datadog\appsec\push_addresses;
use function datadog\appsec\testing\{decode_msgpack};
include __DIR__ . '/inc/ddtrace_version.php';
include __DIR__ . '/inc/mock_helper.php';
Expand All @@ -21,7 +21,7 @@ $helper = Helper::createInitedRun([

function two($param01, $param02)
{
push_address("irrelevant", ["some" => "params", "more" => "parameters"]);
push_addresses(["irrelevant" => ["some" => "params", "more" => "parameters"]]);
}

function one($param01)
Expand Down
Loading
Loading