Skip to content

Commit

Permalink
Decode msgpack on phpt tests
Browse files Browse the repository at this point in the history
  • Loading branch information
estringana committed Aug 9, 2024
1 parent 5668367 commit 0f4dfea
Show file tree
Hide file tree
Showing 4 changed files with 160 additions and 9 deletions.
2 changes: 2 additions & 0 deletions appsec/src/extension/ddappsec.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include "string_helpers.h"
#include "tags.h"
#include "user_tracking.h"
#include "msgpack_helpers.h"

#include <json/json.h>

Expand Down Expand Up @@ -220,6 +221,7 @@ static PHP_MINIT_FUNCTION(ddappsec)
dd_ip_extraction_startup();
dd_entity_body_startup();
dd_backtrace_startup();
dd_msgpack_helpers_startup();

return SUCCESS;
}
Expand Down
118 changes: 118 additions & 0 deletions appsec/src/extension/msgpack_helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "logging.h"
#include "msgpack_helpers.h"
#include "php_helpers.h"
#include "php_objects.h"

static void _mpack_write_zval(mpack_writer_t *nonnull w, zval *nonnull zv);

Expand Down Expand Up @@ -262,3 +263,120 @@ static void _iovec_writer_teardown(mpack_writer_t *w)
w->buffer = NULL;
w->context = NULL;
}

static void parse_element(mpack_reader_t *reader, int depth, zval *output)
{
if (depth >= 32) { // critical check!
mpack_reader_flag_error(reader, mpack_error_too_big);
mlog(dd_log_error, "decode_msgpack error: msgpack object too big");
return;
}

mpack_tag_t tag = mpack_read_tag(reader);
if (mpack_reader_error(reader) != mpack_ok) {
return;
}

switch (mpack_tag_type(&tag)) {
case mpack_type_nil:
ZVAL_NULL(output);
break;
case mpack_type_bool:
ZVAL_BOOL(output, mpack_tag_bool_value(&tag));
break;
case mpack_type_int:
ZVAL_LONG(output, mpack_tag_int_value(&tag));
break;
case mpack_type_uint:
ZVAL_LONG(output, mpack_tag_int_value(&tag));
break;

case mpack_type_str: {
uint32_t length = mpack_tag_str_length(&tag);
const char *data = mpack_read_bytes_inplace(reader, length);
ZVAL_STRINGL(output, data, length);
mpack_done_str(reader);
break;
}
case mpack_type_array: {
uint32_t count = mpack_tag_array_count(&tag);
array_init(output);
while (count-- > 0) {
zval new;
parse_element(reader, depth + 1, &new);
if (mpack_reader_error(reader) != mpack_ok) { // critical check!
zval_dtor(&new);
mlog(
dd_log_error, "decode_msgpack error: error decoding array");
break;
}
zend_hash_next_index_insert(Z_ARRVAL_P(output), &new);
}
mpack_done_array(reader);
break;
}
case mpack_type_map: {
uint32_t count = mpack_tag_map_count(&tag);
array_init(output);
while (count-- > 0) {
zval key, value;
parse_element(reader, depth + 1, &key);
parse_element(reader, depth + 1, &value);
if (mpack_reader_error(reader) != mpack_ok) { // critical check!
zval_dtor(&key);
mlog(dd_log_error, "decode_msgpack error: error decoding map");
break;
}
zend_hash_add_new(Z_ARRVAL_P(output), Z_STR(key), &value);
zval_dtor(&key);
}
mpack_done_map(reader);
break;
}
default:
mlog(dd_log_error, "decode_msgpack error: type %s not implemented.\n",
mpack_type_to_string(mpack_tag_type(&tag)));
return;
}
}

static bool parse_messagepack(const char *data, size_t length, zval *output)
{
mpack_reader_t reader;
mpack_reader_init_data(&reader, data, length);
parse_element(&reader, 0, output);
return mpack_ok == mpack_reader_destroy(&reader);
}

static PHP_FUNCTION(datadog_appsec_testing_decode_msgpack)
{
zend_string *encoded = NULL;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &encoded) != SUCCESS) {
RETURN_FALSE;
}

parse_messagepack(ZSTR_VAL(encoded), ZSTR_LEN(encoded), return_value);
}

ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(
zval_ret_string_arginfo, 0, 1, IS_ARRAY, 0)
ZEND_ARG_TYPE_INFO(0, id, IS_STRING, 0)
ZEND_END_ARG_INFO()

// clang-format off
static const zend_function_entry testing_functions[] = {
ZEND_RAW_FENTRY(DD_TESTING_NS "decode_msgpack", PHP_FN(datadog_appsec_testing_decode_msgpack), zval_ret_string_arginfo, 0)
PHP_FE_END
};
// clang-format on

static void _register_testing_objects()
{
if (!get_global_DD_APPSEC_TESTING()) {
return;
}

dd_phpobj_reg_funcs(testing_functions);
}

void dd_msgpack_helpers_startup() { _register_testing_objects(); }
2 changes: 2 additions & 0 deletions appsec/src/extension/msgpack_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,6 @@ void dd_mpack_write_zval(mpack_writer_t *nonnull w, zval *nullable zv);
void dd_mpack_writer_init_iov(
mpack_writer_t *nonnull writer, zend_llist *nonnull iovec_list);

void dd_msgpack_helpers_startup();

#endif // DD_MSGPACK_HELPERS_H
47 changes: 38 additions & 9 deletions appsec/tests/extension/report_backtrace_01.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ extension=ddtrace.so
<?php
include __DIR__ . '/inc/ddtrace_version.php';

use function datadog\appsec\testing\report_exploit_backtrace;
use function datadog\appsec\testing\{report_exploit_backtrace, decode_msgpack};

function two($param01, $param02)
{
Expand All @@ -26,16 +26,45 @@ one("foo");
DDTrace\close_span(0);
$span = dd_trace_serialize_closed_spans();
$meta_struct = $span[0]["meta_struct"];
foreach($meta_struct as &$m)
{
$m = bin2hex($m);
}
var_dump($meta_struct);
var_dump(decode_msgpack($meta_struct["_dd.stack"]));
DDTrace\flush();
?>
--EXPECTF--
bool(true)
array(1) {
["_dd.stack"]=>
&string(%d) "81a76578706c6f69749183a86c616e6775616765a3706870a26964a7736f6d65206964a66672616d65739284a46c696e650da866756e6374696f6ea374776fa466696c65b77265706f72745f6261636b74726163655f30312e706870a269640084a46c696e6512a866756e6374696f6ea36f6e65a466696c65b77265706f72745f6261636b74726163655f30312e706870a2696401"
}
["exploit"]=>
array(1) {
[0]=>
array(3) {
["language"]=>
string(3) "php"
["id"]=>
string(7) "some id"
["frames"]=>
array(2) {
[0]=>
array(4) {
["line"]=>
int(13)
["function"]=>
string(3) "two"
["file"]=>
string(23) "report_backtrace_01.php"
["id"]=>
int(0)
}
[1]=>
array(4) {
["line"]=>
int(18)
["function"]=>
string(3) "one"
["file"]=>
string(23) "report_backtrace_01.php"
["id"]=>
int(1)
}
}
}
}
}

0 comments on commit 0f4dfea

Please sign in to comment.