Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
/Debug
/Release
/RelWithDebInfo
/build
108 changes: 69 additions & 39 deletions examples/example.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,37 +9,41 @@ namespace YAML {
template <> struct as_if<ddwaf_object, void> {
explicit as_if(const Node &node_) : node(node_) {}

static ddwaf_object yaml_to_object_helper(const Node &node)
static ddwaf_object yaml_to_object_helper(const Node &node, ddwaf_allocator alloc)
{
ddwaf_object arg;
switch (node.Type()) {
case NodeType::Sequence:
ddwaf_object_array(&arg);
ddwaf_object_set_array(&arg, 0, alloc);
break;
case NodeType::Map:
ddwaf_object_map(&arg);
ddwaf_object_set_map(&arg, 0, alloc);
break;
case NodeType::Scalar:
ddwaf_object_string(&arg, node.Scalar().c_str());
{
auto scalar = node.Scalar();
ddwaf_object_set_string(&arg, scalar.c_str(), scalar.size(), alloc);
}
break;
case NodeType::Null:
ddwaf_object_null(&arg);
ddwaf_object_set_null(&arg);
break;
case NodeType::Undefined:
default:
ddwaf_object_invalid(&arg);
ddwaf_object_set_invalid(&arg);
break;
}
return arg;
}

ddwaf_object operator()() const
{
std::list<std::tuple<ddwaf_object &, YAML::Node, YAML::Node::const_iterator>> stack;
auto alloc = ddwaf_get_default_allocator();
std::list<std::tuple<ddwaf_object *, YAML::Node, YAML::Node::const_iterator>> stack;

ddwaf_object root = yaml_to_object_helper(node);
ddwaf_object root = yaml_to_object_helper(node, alloc);
if (root.type == DDWAF_OBJ_MAP || root.type == DDWAF_OBJ_ARRAY) {
stack.emplace_back(root, node, node.begin());
stack.emplace_back(&root, node, node.begin());
}

while (!stack.empty()) {
Expand All @@ -48,16 +52,18 @@ template <> struct as_if<ddwaf_object, void> {

for (; it != parent_node.end(); ++it) {
YAML::Node child_node = parent_node.IsMap() ? it->second : *it;
auto child_obj = yaml_to_object_helper(child_node);
if (parent_obj.type == DDWAF_OBJ_MAP) {
auto child_obj = yaml_to_object_helper(child_node, alloc);
ddwaf_object *child_ptr = nullptr;
if (parent_obj->type == DDWAF_OBJ_MAP) {
auto key = it->first.as<std::string>();
ddwaf_object_map_add(&parent_obj, key.c_str(), &child_obj);
} else if (parent_obj.type == DDWAF_OBJ_ARRAY) {
ddwaf_object_array_add(&parent_obj, &child_obj);
child_ptr = ddwaf_object_insert_key(parent_obj, key.c_str(), key.size(), alloc);
*child_ptr = child_obj;
} else if (parent_obj->type == DDWAF_OBJ_ARRAY) {
child_ptr = ddwaf_object_insert(parent_obj, alloc);
*child_ptr = child_obj;
}

if (child_obj.type == DDWAF_OBJ_MAP || child_obj.type == DDWAF_OBJ_ARRAY) {
auto &child_ptr = parent_obj.array[parent_obj.nbEntries - 1];
stack.emplace_back(child_ptr, child_node, child_node.begin());
++it;
break;
Expand All @@ -83,19 +89,25 @@ YAML::Node object_to_yaml_helper(const ddwaf_object &obj)
YAML::Node output;
switch (obj.type) {
case DDWAF_OBJ_BOOL:
output = obj.boolean;
output = ddwaf_object_get_bool(&obj);
break;
case DDWAF_OBJ_SIGNED:
output = obj.intValue;
output = ddwaf_object_get_signed(&obj);
break;
case DDWAF_OBJ_UNSIGNED:
output = obj.uintValue;
output = ddwaf_object_get_unsigned(&obj);
break;
case DDWAF_OBJ_FLOAT:
output = obj.f64;
output = ddwaf_object_get_float(&obj);
break;
case DDWAF_OBJ_STRING:
output = std::string{obj.stringValue, obj.nbEntries};
case DDWAF_OBJ_LITERAL_STRING:
case DDWAF_OBJ_SMALL_STRING:
{
size_t length;
const char* str = ddwaf_object_get_string(&obj, &length);
output = std::string{str, length};
}
break;
case DDWAF_OBJ_MAP:
output = YAML::Load("{}");
Expand Down Expand Up @@ -126,21 +138,34 @@ YAML::Node object_to_yaml(const ddwaf_object &obj)
auto current_depth = stack.size();
auto &[parent_obj, parent_node, index] = stack.back();

for (; index < parent_obj.nbEntries; ++index) {
auto &child_obj = parent_obj.array[index];
auto child_node = object_to_yaml_helper(child_obj);

size_t size = ddwaf_object_get_size(&parent_obj);
for (; index < size; ++index) {
const ddwaf_object *child_obj = nullptr;
if (parent_obj.type == DDWAF_OBJ_MAP) {
std::string key{child_obj.parameterName, child_obj.parameterNameLength};
child_obj = ddwaf_object_at_value(&parent_obj, index);
auto *key_obj = ddwaf_object_at_key(&parent_obj, index);
size_t key_len;
const char* key_str = ddwaf_object_get_string(key_obj, &key_len);
std::string key{key_str, key_len};

auto child_node = object_to_yaml_helper(*child_obj);
parent_node[key] = child_node;

if (child_obj->type == DDWAF_OBJ_MAP || child_obj->type == DDWAF_OBJ_ARRAY) {
stack.emplace_back(*child_obj, child_node, 0);
++index;
break;
}
} else if (parent_obj.type == DDWAF_OBJ_ARRAY) {
child_obj = ddwaf_object_at_value(&parent_obj, index);
auto child_node = object_to_yaml_helper(*child_obj);
parent_node.push_back(child_node);
}

if (child_obj.type == DDWAF_OBJ_MAP || child_obj.type == DDWAF_OBJ_ARRAY) {
stack.emplace_back(child_obj, child_node, 0);
++index;
break;
if (child_obj->type == DDWAF_OBJ_MAP || child_obj->type == DDWAF_OBJ_ARRAY) {
stack.emplace_back(*child_obj, child_node, 0);
++index;
break;
}
}
}

Expand Down Expand Up @@ -175,29 +200,34 @@ version: "2.1"

int main()
{
YAML::Node doc = YAML::Load(waf_rule.data(), waf_rule.size());
auto alloc = ddwaf_get_default_allocator();

auto rule = doc.as<ddwaf_object>(); //= convert_yaml_to_args(doc);
ddwaf_handle handle = ddwaf_init(&rule, nullptr, nullptr);
YAML::Node doc = YAML::Load(waf_rule.data());

auto rule = doc.as<ddwaf_object>();
ddwaf_handle handle = ddwaf_init(&rule, nullptr);
ddwaf_object_destroy(&rule, alloc);
if (handle == nullptr) {
return EXIT_FAILURE;
}

ddwaf_context context = ddwaf_context_init(handle);
ddwaf_context context = ddwaf_context_init(handle, alloc);
if (context == nullptr) {
ddwaf_destroy(handle);
return EXIT_FAILURE;
}

ddwaf_object root;
ddwaf_object tmp;
ddwaf_object_map(&root);
ddwaf_object_map_add(&root, "arg1", ddwaf_object_string(&tmp, "string 1"));
ddwaf_object_map_add(&root, "arg2", ddwaf_object_string(&tmp, "string 2"));
ddwaf_object_set_map(&root, 2, alloc);

ddwaf_object *arg1 = ddwaf_object_insert_literal_key(&root, "arg1", 4, alloc);
ddwaf_object_set_string_literal(arg1, "string 1", 8);

ddwaf_object *arg2 = ddwaf_object_insert_literal_key(&root, "arg2", 4, alloc);
ddwaf_object_set_string_literal(arg2, "string 2", 8);

ddwaf_object ret;
auto code = ddwaf_context_eval(context, &root, nullptr, &ret, LONG_TIME);
auto code = ddwaf_context_eval(context, &root, alloc, &ret, LONG_TIME);
std::cout << "Output second run: " << code << '\n';
if (code == DDWAF_MATCH) {
YAML::Emitter out(std::cout);
Expand Down
14 changes: 9 additions & 5 deletions fuzzer/cmdi_detector/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,11 +188,15 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *bytes, size_t size)

auto [resource, param] = deserialize(bytes, size);

auto root = owned_object::make_map();
root.emplace("server.request.query", owned_object::make_string(param));

auto array = root.emplace("server.sys.exec.cmd", owned_object::make_array());
for (auto arg : resource) { array.emplace_back(owned_object::make_string(arg)); }
auto root = owned_object::make_map(0, ddwaf::memory::get_default_resource());
root.emplace("server.request.query",
owned_object::make_string(param, ddwaf::memory::get_default_resource()));

auto array = root.emplace(
"server.sys.exec.cmd", owned_object::make_array(0, ddwaf::memory::get_default_resource()));
for (auto arg : resource) {
array.emplace_back(owned_object::make_string(arg, ddwaf::memory::get_default_resource()));
}

object_store store;
store.insert(std::move(root));
Expand Down
8 changes: 4 additions & 4 deletions fuzzer/http_endpoint_fingerprint/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *bytes, size_t size)
{
random_buffer buffer{bytes, size};

auto query = owned_object::make_map();
auto query = owned_object::make_map(0, ddwaf::memory::get_default_resource());
auto query_size = buffer.get<uint8_t>();
for (uint8_t i = 0; i < query_size; ++i) {
auto key = buffer.get<std::string_view>();
auto value = buffer.get<std::string_view>();
query.emplace(key, value);
}

auto body = owned_object::make_map();
auto body = owned_object::make_map(0, ddwaf::memory::get_default_resource());
auto body_size = buffer.get<uint8_t>();
for (uint8_t i = 0; i < body_size; ++i) {
auto key = buffer.get<std::string_view>();
Expand All @@ -41,8 +41,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *bytes, size_t size)
gen.eval_impl({.address = {}, .key_path = {}, .value = buffer.get<std::string_view>()},
{.address = {}, .key_path = {}, .value = buffer.get<std::string_view>()},
{{.address = {}, .key_path = {}, .value = query}},
{{.address = {}, .key_path = {}, .value = body}}, cache, memory::get_default_resource(),
deadline);
{{.address = {}, .key_path = {}, .value = body}}, cache,
ddwaf::memory::get_default_resource(), deadline);

return 0;
}
4 changes: 2 additions & 2 deletions fuzzer/http_header_fingerprint/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *bytes, size_t size)

random_buffer buffer{bytes, size};

auto header = owned_object::make_map();
auto header = owned_object::make_map(0, ddwaf::memory::get_default_resource());
auto header_size = buffer.get<uint8_t>();
for (uint8_t i = 0; i < header_size; ++i) {
auto value = buffer.get<std::string_view>();
Expand All @@ -41,7 +41,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *bytes, size_t size)
processor_cache cache;
ddwaf::timer deadline{2s};
auto output = gen.eval_impl({.address = {}, .key_path = {}, .value = header}, cache,
memory::get_default_resource(), deadline);
ddwaf::memory::get_default_resource(), deadline);

return 0;
}
4 changes: 2 additions & 2 deletions fuzzer/http_network_fingerprint/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *bytes, size_t size)

random_buffer buffer{bytes, size};

auto header = owned_object::make_map();
auto header = owned_object::make_map(0, ddwaf::memory::get_default_resource());
auto header_size = buffer.get<uint8_t>();
for (uint8_t i = 0; i < header_size; ++i) {
auto value = buffer.get<std::string_view>();
Expand All @@ -40,7 +40,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *bytes, size_t size)
processor_cache cache;
ddwaf::timer deadline{2s};
auto output = gen.eval_impl({.address = {}, .key_path = {}, .value = header}, cache,
memory::get_default_resource(), deadline);
ddwaf::memory::get_default_resource(), deadline);

return 0;
}
5 changes: 3 additions & 2 deletions fuzzer/jwt_decode/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,16 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *bytes, size_t size)
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
std::string_view value{reinterpret_cast<const char *>(bytes), size};

auto headers = object_builder::map({{"authorization", value}});
auto headers =
object_builder::map({{"authorization", value}}, ddwaf::memory::get_default_resource());

jwt_decode gen{"id", {}, {}, false, true};

processor_cache cache;
ddwaf::timer deadline{2s};
static const std::vector<std::variant<std::string, int64_t>> key_path{"authorization"};
auto output = gen.eval_impl({.address = {}, .key_path = key_path, .value = headers}, cache,
memory::get_default_resource(), deadline);
ddwaf::memory::get_default_resource(), deadline);

return 0;
}
8 changes: 5 additions & 3 deletions fuzzer/lfi_detector/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,11 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *bytes, size_t size)
lfi_detector cond{{gen_param_def("server.io.fs.file", "server.request.query")}};

auto [resource, param] = deserialize(bytes, size);
auto root = owned_object::make_map();
root.emplace("server.request.query", owned_object::make_string(param));
root.emplace("server.io.fs.file", owned_object::make_string(resource));
auto root = owned_object::make_map(0, ddwaf::memory::get_default_resource());
root.emplace("server.request.query",
owned_object::make_string(param, ddwaf::memory::get_default_resource()));
root.emplace("server.io.fs.file",
owned_object::make_string(resource, ddwaf::memory::get_default_resource()));

object_store store;
store.insert(std::move(root));
Expand Down
4 changes: 2 additions & 2 deletions fuzzer/session_fingerprint/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *bytes, size_t size)
{
random_buffer buffer{bytes, size};

auto cookies = owned_object::make_map();
auto cookies = owned_object::make_map(0, ddwaf::memory::get_default_resource());
auto cookies_size = buffer.get<uint8_t>();
for (uint8_t i = 0; i < cookies_size; ++i) {
auto key = buffer.get<std::string_view>();
Expand All @@ -34,7 +34,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *bytes, size_t size)
auto output = gen.eval_impl({{.address = {}, .key_path = {}, .value = cookies}},
{{.address = {}, .key_path = {}, .value = buffer.get<std::string_view>()}},
{{.address = {}, .key_path = {}, .value = buffer.get<std::string_view>()}}, cache,
memory::get_default_resource(), deadline);
ddwaf::memory::get_default_resource(), deadline);

return 0;
}
14 changes: 9 additions & 5 deletions fuzzer/shi_detector_array/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,11 +188,15 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *bytes, size_t size)

auto [resource, param] = deserialize(bytes, size);

auto root = owned_object::make_map();
root.emplace("server.request.query", owned_object::make_string(param));

auto array = root.emplace("server.sys.shell.cmd", owned_object::make_array());
for (auto arg : resource) { array.emplace_back(owned_object::make_string(arg)); }
auto root = owned_object::make_map(0, ddwaf::memory::get_default_resource());
root.emplace("server.request.query",
owned_object::make_string(param, ddwaf::memory::get_default_resource()));

auto array = root.emplace(
"server.sys.shell.cmd", owned_object::make_array(0, ddwaf::memory::get_default_resource()));
for (auto arg : resource) {
array.emplace_back(owned_object::make_string(arg, ddwaf::memory::get_default_resource()));
}

object_store store;
store.insert(std::move(root));
Expand Down
8 changes: 5 additions & 3 deletions fuzzer/shi_detector_string/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,11 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *bytes, size_t size)

auto [resource, param] = deserialize(bytes, size);

auto root = owned_object::make_map();
root.emplace("server.request.query", owned_object::make_string(param));
root.emplace("server.sys.shell.cmd", owned_object::make_string(resource));
auto root = owned_object::make_map(0, ddwaf::memory::get_default_resource());
root.emplace("server.request.query",
owned_object::make_string(param, ddwaf::memory::get_default_resource()));
root.emplace("server.sys.shell.cmd",
owned_object::make_string(resource, ddwaf::memory::get_default_resource()));

object_store store;
store.insert(std::move(root));
Expand Down
11 changes: 7 additions & 4 deletions fuzzer/sqli_detector/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,13 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *bytes, size_t size)

auto dialect_str = ddwaf::sql_dialect_to_string(dialect);

auto root = owned_object::make_map();
root.emplace("server.request.query", owned_object::make_string(param));
root.emplace("server.db.system", owned_object::make_string(dialect_str));
root.emplace("server.db.statement", owned_object::make_string(resource));
auto root = owned_object::make_map(0, ddwaf::memory::get_default_resource());
root.emplace("server.request.query",
owned_object::make_string(param, ddwaf::memory::get_default_resource()));
root.emplace("server.db.system",
owned_object::make_string(dialect_str, ddwaf::memory::get_default_resource()));
root.emplace("server.db.statement",
owned_object::make_string(resource, ddwaf::memory::get_default_resource()));

object_store store;
store.insert(std::move(root));
Expand Down
Loading
Loading