Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion appsec/src/extension/commands/request_shutdown.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include "request_shutdown.h"
#include "../commands_helpers.h"
#include "../configuration.h"
#include "../ddappsec.h"
#include "../ddtrace.h"
#include "../entity_body.h"
Expand Down Expand Up @@ -62,7 +63,11 @@ static dd_result _request_pack(mpack_writer_t *nonnull w, void *nonnull ctx)
}
}

mpack_start_map(w, 2 + (Z_TYPE(resp_body) != IS_NULL ? 1 : 0));
bool send_raw_body = get_global_DD_APPSEC_RAW_RESPONSE_BODY_ENABLED() &&
req_info->entity != NULL && req_info->entity->len > 0;

mpack_start_map(w, 2 + (Z_TYPE(resp_body) != IS_NULL ? 1 : 0) +
(send_raw_body ? 1 : 0));

// 1.1.
{
Expand Down Expand Up @@ -94,6 +99,13 @@ static dd_result _request_pack(mpack_writer_t *nonnull w, void *nonnull ctx)
}
}

// 1.4.?
if (send_raw_body) {
dd_mpack_write_lstr(w, "server.response.body.raw");
mpack_write_str(w, ZSTR_VAL(req_info->entity),
(uint32_t)ZSTR_LEN(req_info->entity));
}

mpack_finish_map(w);

// 2.
Expand Down
1 change: 1 addition & 0 deletions appsec/src/extension/configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ extern bool runtime_config_first_init;
CONFIG(STRING, DD_AGENT_HOST, "localhost") \
CONFIG(INT, DD_TRACE_AGENT_PORT, "0") \
CONFIG(INT, DD_APPSEC_MAX_BODY_BUFF_SIZE, "524288") \
SYSCFG(BOOL, DD_APPSEC_RAW_RESPONSE_BODY_ENABLED, "false") \
CONFIG(STRING, DD_TRACE_AGENT_URL, "") \
CONFIG(BOOL, DD_TRACE_ENABLED, "true") \
CALIAS(CUSTOM(STRING), DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE, "ident", \
Expand Down
33 changes: 33 additions & 0 deletions appsec/tests/extension/rshutdown_command_raw_body_disabled.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
--TEST--
request_shutdown — server.response.body.raw not sent when feature is disabled (default)
--INI--
expose_php=0
datadog.appsec.enabled=1
--GET--
a=b
--FILE--
<?php
use function datadog\appsec\testing\{rinit,rshutdown};

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

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

var_dump(rinit());
header('content-type: text/plain');
http_response_code(200);
echo "plain text body\n";
$helper->get_commands(); // ignore

var_dump(rshutdown());
$c = $helper->get_commands();
var_dump(array_key_exists('server.response.body.raw', $c[0][1][0]));
?>
--EXPECT--
bool(true)
plain text body
bool(true)
bool(false)
46 changes: 46 additions & 0 deletions appsec/tests/extension/rshutdown_command_raw_body_json.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
--TEST--
request_shutdown — server.response.body.raw sent alongside parsed server.response.body for JSON
--INI--
expose_php=0
datadog.appsec.enabled=1
datadog.appsec.raw_response_body_enabled=1
--GET--
a=b
--FILE--
<?php
use function datadog\appsec\testing\{rinit,rshutdown};

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

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

var_dump(rinit());
header('content-type: application/json');
http_response_code(200);
echo '{"key":"value"}', "\n";
$helper->get_commands(); // ignore

var_dump(rshutdown());
$c = $helper->get_commands();
$data = $c[0][1][0];

// both structured and raw body are present
var_dump(isset($data['server.response.body']));
var_dump(isset($data['server.response.body.raw']));
print_r($data['server.response.body']);
echo $data['server.response.body.raw'];
?>
--EXPECT--
bool(true)
{"key":"value"}
bool(true)
bool(true)
bool(true)
Array
(
[key] => value
)
{"key":"value"}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
--TEST--
request_shutdown — server.response.body.raw sent for non-JSON/XML content types
--INI--
expose_php=0
datadog.appsec.enabled=1
datadog.appsec.raw_response_body_enabled=1
--GET--
a=b
--FILE--
<?php
use function datadog\appsec\testing\{rinit,rshutdown};

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

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

var_dump(rinit());
header('content-type: text/plain');
http_response_code(200);
echo "plain text body\n";
$helper->get_commands(); // ignore

var_dump(rshutdown());
$c = $helper->get_commands();
$data = $c[0][1][0];

// server.response.body is absent for non-JSON/XML
var_dump(isset($data['server.response.body']));
// server.response.body.raw is present with the raw text
var_dump(isset($data['server.response.body.raw']));
echo $data['server.response.body.raw'];
?>
--EXPECT--
bool(true)
plain text body
bool(true)
bool(false)
bool(true)
plain text body
61 changes: 61 additions & 0 deletions appsec/tests/extension/rshutdown_command_raw_body_xml.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
--TEST--
request_shutdown — server.response.body.raw sent alongside parsed server.response.body for XML
--INI--
expose_php=0
datadog.appsec.enabled=1
datadog.appsec.raw_response_body_enabled=1
--GET--
a=b
--FILE--
<?php
use function datadog\appsec\testing\{rinit,rshutdown};

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

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

var_dump(rinit());
header('content-type: application/xml');
http_response_code(200);
$xml = <<<XML
<?xml version="1.0" standalone="yes"?>
<foo attr="bar">baz</foo>
XML;
echo "$xml\n";
$helper->get_commands(); // ignore

var_dump(rshutdown());
$c = $helper->get_commands();
$data = $c[0][1][0];

// both structured and raw body are present
var_dump(isset($data['server.response.body']));
var_dump(isset($data['server.response.body.raw']));
print_r($data['server.response.body']);
echo $data['server.response.body.raw'];
?>
--EXPECT--
bool(true)
<?xml version="1.0" standalone="yes"?>
<foo attr="bar">baz</foo>
bool(true)
bool(true)
bool(true)
Array
(
[foo] => Array
(
[0] => Array
(
[@attr] => bar
)

[1] => baz
)

)
<?xml version="1.0" standalone="yes"?>
<foo attr="bar">baz</foo>
Loading