Skip to content
Open
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
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