Skip to content

Commit 955b97f

Browse files
committed
Add test for payload size limits (security issue #3)
1 parent d219e10 commit 955b97f

2 files changed

Lines changed: 104 additions & 0 deletions

File tree

CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,10 @@ if(FASTMCPP_BUILD_TESTS)
250250
target_link_libraries(fastmcpp_server_context_meta PRIVATE fastmcpp_core)
251251
add_test(NAME fastmcpp_server_context_meta COMMAND fastmcpp_server_context_meta)
252252

253+
add_executable(fastmcpp_server_security_limits tests/server/security_limits.cpp)
254+
target_link_libraries(fastmcpp_server_security_limits PRIVATE fastmcpp_core)
255+
add_test(NAME fastmcpp_server_security_limits COMMAND fastmcpp_server_security_limits)
256+
253257
add_executable(fastmcpp_client_transports tests/client/transports.cpp)
254258
target_link_libraries(fastmcpp_client_transports PRIVATE fastmcpp_core)
255259
add_test(NAME fastmcpp_client_transports COMMAND fastmcpp_client_transports)

tests/server/security_limits.cpp

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
#include "fastmcpp/server/http_server.hpp"
2+
#include "fastmcpp/server/server.hpp"
3+
#include "fastmcpp/util/json.hpp"
4+
5+
#include <httplib.h>
6+
#include <iostream>
7+
#include <string>
8+
9+
using fastmcpp::Json;
10+
using fastmcpp::server::HttpServerWrapper;
11+
using fastmcpp::server::Server;
12+
13+
int main()
14+
{
15+
std::cout << "Running security limits tests...\n";
16+
17+
// Create a simple echo server
18+
auto srv = std::make_shared<Server>();
19+
srv->route(
20+
"tools/list",
21+
[](const Json&)
22+
{
23+
return Json{{"tools", Json::array()}};
24+
});
25+
26+
// Start HTTP server on unique port
27+
int port = 18199;
28+
HttpServerWrapper http_server(srv, "127.0.0.1", port);
29+
30+
if (!http_server.start())
31+
{
32+
std::cerr << "Failed to start HTTP server\n";
33+
return 1;
34+
}
35+
36+
// Wait for server to be ready
37+
std::this_thread::sleep_for(std::chrono::milliseconds(100));
38+
39+
// Test 1: Normal request within limits should succeed
40+
{
41+
std::cout << "Test: normal request within payload limits...\n";
42+
httplib::Client client("127.0.0.1", port);
43+
client.set_connection_timeout(std::chrono::seconds(5));
44+
45+
Json request = {{"jsonrpc", "2.0"}, {"id", 1}, {"method", "tools/list"}};
46+
47+
auto res = client.Post("/tools/list", request.dump(), "application/json");
48+
49+
if (!res || res->status != 200)
50+
{
51+
std::cerr << "Normal request failed\n";
52+
http_server.stop();
53+
return 1;
54+
}
55+
std::cout << " [PASS] normal request succeeded\n";
56+
}
57+
58+
// Test 2: Oversized payload should be rejected
59+
{
60+
std::cout << "Test: oversized payload (>10MB) is rejected...\n";
61+
httplib::Client client("127.0.0.1", port);
62+
client.set_connection_timeout(std::chrono::seconds(5));
63+
64+
// Create >10MB payload (10MB + 1KB)
65+
std::string huge_payload(10 * 1024 * 1024 + 1024, 'A');
66+
Json request = {{"jsonrpc", "2.0"},
67+
{"id", 1},
68+
{"method", "tools/list"},
69+
{"params", {{"data", huge_payload}}}};
70+
71+
auto res = client.Post("/tools/list", request.dump(), "application/json");
72+
73+
// Server should reject with 413 (Payload Too Large) or connection error
74+
if (!res)
75+
{
76+
std::cout << " [PASS] oversized payload rejected (connection error)\n";
77+
}
78+
else if (res->status == 413)
79+
{
80+
std::cout << " [PASS] oversized payload rejected with 413\n";
81+
}
82+
else if (res->status >= 400)
83+
{
84+
std::cout << " [PASS] oversized payload rejected with status " << res->status
85+
<< "\n";
86+
}
87+
else
88+
{
89+
std::cerr << " [FAIL] oversized payload was accepted (status " << res->status
90+
<< ")\n";
91+
http_server.stop();
92+
return 1;
93+
}
94+
}
95+
96+
http_server.stop();
97+
98+
std::cout << "\n[OK] All security limits tests passed!\n";
99+
return 0;
100+
}

0 commit comments

Comments
 (0)