120 lines
5.4 KiB
C
120 lines
5.4 KiB
C
#include "test_framework.h"
|
|
#include "graph_buffer/graph_buffer.h"
|
|
#include "pipeline/pipeline_internal.h"
|
|
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
|
|
bool cbm_service_pattern_is_http_route_literal(const char *literal, const char *callee_name);
|
|
|
|
static int has_data_flow(cbm_gbuf_t *gb, int64_t source_id, int64_t target_id) {
|
|
const cbm_gbuf_edge_t **edges = NULL;
|
|
int count = 0;
|
|
cbm_gbuf_find_edges_by_source_type(gb, source_id, "DATA_FLOWS", &edges, &count);
|
|
for (int i = 0; i < count; i++) {
|
|
if (edges[i]->target_id == target_id) {
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
TEST(infrascan_http_route_literal_guard_rejects_filesystem_paths) {
|
|
ASSERT_FALSE(cbm_service_pattern_is_http_route_literal("/etc/crio/crio.conf", "requests.get"));
|
|
ASSERT_FALSE(
|
|
cbm_service_pattern_is_http_route_literal("/root/.aws/credentials", "requests.get"));
|
|
ASSERT_FALSE(cbm_service_pattern_is_http_route_literal("/var/run/app.json", "requests.get"));
|
|
ASSERT_FALSE(cbm_service_pattern_is_http_route_literal("/locations/", "str.split"));
|
|
ASSERT_FALSE(cbm_service_pattern_is_http_route_literal("/api", "os.path.join"));
|
|
ASSERT_FALSE(cbm_service_pattern_is_http_route_literal(NULL, "requests.get"));
|
|
ASSERT_FALSE(cbm_service_pattern_is_http_route_literal("", "requests.get"));
|
|
ASSERT_TRUE(cbm_service_pattern_is_http_route_literal("/api/orders", "requests.get"));
|
|
ASSERT_TRUE(cbm_service_pattern_is_http_route_literal("https://orders.example/api/orders",
|
|
"requests.get"));
|
|
PASS();
|
|
}
|
|
|
|
TEST(infrascan_route_nodes_skip_bad_http_url_paths) {
|
|
cbm_gbuf_t *gb = cbm_gbuf_new("test", "/tmp/cbm_infrascan_route_guard");
|
|
ASSERT_NOT_NULL(gb);
|
|
int64_t caller =
|
|
cbm_gbuf_upsert_node(gb, "Function", "client", "test.client", "client.py", 1, 3, "{}");
|
|
int64_t fs_callee =
|
|
cbm_gbuf_upsert_node(gb, "Function", "requests.get", "requests.get", "", 0, 0, "{}");
|
|
int64_t split_callee =
|
|
cbm_gbuf_upsert_node(gb, "Function", "str.split", "str.split", "", 0, 0, "{}");
|
|
int64_t empty_callee =
|
|
cbm_gbuf_upsert_node(gb, "Function", "requests.post", "requests.post", "", 0, 0, "{}");
|
|
ASSERT_GT(caller, 0);
|
|
ASSERT_GT(fs_callee, 0);
|
|
ASSERT_GT(split_callee, 0);
|
|
ASSERT_GT(empty_callee, 0);
|
|
|
|
cbm_gbuf_insert_edge(gb, caller, fs_callee, "HTTP_CALLS",
|
|
"{\"callee\":\"requests.get\",\"url_path\":\"/etc/crio/crio.conf\","
|
|
"\"method\":\"GET\"}");
|
|
cbm_gbuf_insert_edge(gb, caller, split_callee, "HTTP_CALLS",
|
|
"{\"callee\":\"str.split\",\"url_path\":\"/locations/\","
|
|
"\"method\":\"ANY\"}");
|
|
cbm_gbuf_insert_edge(gb, caller, empty_callee, "HTTP_CALLS",
|
|
"{\"callee\":\"requests.get\",\"method\":\"GET\"}");
|
|
|
|
cbm_pipeline_create_route_nodes(gb);
|
|
|
|
ASSERT_NULL(cbm_gbuf_find_by_qn(gb, "__route__GET__/etc/crio/crio.conf"));
|
|
ASSERT_NULL(cbm_gbuf_find_by_qn(gb, "__route__ANY__/locations/"));
|
|
ASSERT_NULL(cbm_gbuf_find_by_qn(gb, "__route__GET__"));
|
|
|
|
cbm_gbuf_free(gb);
|
|
PASS();
|
|
}
|
|
|
|
TEST(infrascan_http_calls_join_matching_handler_route) {
|
|
cbm_gbuf_t *gb = cbm_gbuf_new("test", "/tmp/cbm_infrascan_route_join");
|
|
ASSERT_NOT_NULL(gb);
|
|
|
|
int64_t route = cbm_gbuf_upsert_node(gb, "Route", "/api/orders", "__route__GET__/api/orders",
|
|
"", 0, 0, "{\"method\":\"GET\"}");
|
|
int64_t handler = cbm_gbuf_upsert_node(gb, "Function", "get_orders", "test.get_orders",
|
|
"server.py", 1, 3, "{}");
|
|
int64_t client =
|
|
cbm_gbuf_upsert_node(gb, "Function", "client", "test.client", "client.py", 1, 3, "{}");
|
|
int64_t bad_route =
|
|
cbm_gbuf_upsert_node(gb, "Route", "/etc/crio/crio.conf",
|
|
"__route__GET__/etc/crio/crio.conf", "", 0, 0, "{\"method\":\"GET\"}");
|
|
int64_t bad_handler = cbm_gbuf_upsert_node(gb, "Function", "bad_handler", "test.bad_handler",
|
|
"server.py", 5, 7, "{}");
|
|
int64_t bad_client = cbm_gbuf_upsert_node(gb, "Function", "bad_client", "test.bad_client",
|
|
"client.py", 5, 7, "{}");
|
|
ASSERT_GT(route, 0);
|
|
ASSERT_GT(handler, 0);
|
|
ASSERT_GT(client, 0);
|
|
ASSERT_GT(bad_route, 0);
|
|
ASSERT_GT(bad_handler, 0);
|
|
ASSERT_GT(bad_client, 0);
|
|
|
|
cbm_gbuf_insert_edge(gb, handler, route, "HANDLES", "{\"handler\":\"test.get_orders\"}");
|
|
cbm_gbuf_insert_edge(gb, client, route, "HTTP_CALLS",
|
|
"{\"callee\":\"requests.get\",\"url_path\":\"/api/orders\","
|
|
"\"method\":\"GET\"}");
|
|
cbm_gbuf_insert_edge(gb, bad_handler, bad_route, "HANDLES",
|
|
"{\"handler\":\"test.bad_handler\"}");
|
|
cbm_gbuf_insert_edge(gb, bad_client, bad_route, "HTTP_CALLS",
|
|
"{\"callee\":\"requests.get\",\"url_path\":\"/etc/crio/crio.conf\","
|
|
"\"method\":\"GET\"}");
|
|
|
|
cbm_pipeline_create_route_nodes(gb);
|
|
|
|
ASSERT_TRUE(has_data_flow(gb, client, handler));
|
|
ASSERT_FALSE(has_data_flow(gb, bad_client, bad_handler));
|
|
|
|
cbm_gbuf_free(gb);
|
|
PASS();
|
|
}
|
|
|
|
SUITE(infrascan) {
|
|
RUN_TEST(infrascan_http_route_literal_guard_rejects_filesystem_paths);
|
|
RUN_TEST(infrascan_route_nodes_skip_bad_http_url_paths);
|
|
RUN_TEST(infrascan_http_calls_join_matching_handler_route);
|
|
}
|