Network System 0.1.1
High-performance modular networking library for scalable client-server applications
Loading...
Searching...
No Matches
message_validator.h
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2021-2025, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
32#pragma once
33
34#include <cstdint>
35#include <cstddef>
36#include <cstring>
37#include <string>
38#include <string_view>
39#include <stdexcept>
40#include <algorithm>
41
42namespace kcenon::network {
43
52 static constexpr size_t MAX_MESSAGE_SIZE = 16 * 1024 * 1024;
53
55 static constexpr size_t MAX_HEADER_SIZE = 8192;
56
58 static constexpr size_t MAX_WEBSOCKET_FRAME = 1 * 1024 * 1024;
59
61 static constexpr size_t MAX_HTTP_LINE = 8192;
62
64 static constexpr size_t MAX_HEADER_COUNT = 100;
65
67 static constexpr size_t MAX_URL_LENGTH = 2048;
68
70 static constexpr size_t MAX_COOKIE_SIZE = 4096;
71};
72
84
88inline const char* to_string(validation_result result) {
89 switch (result) {
91 return "ok";
93 return "size_exceeded";
95 return "null_byte_detected";
97 return "invalid_format";
99 return "invalid_character";
101 return "header_count_exceeded";
102 default:
103 return "unknown";
104 }
105}
106
122public:
130 [[nodiscard]] static validation_result validate_size(
131 size_t size,
132 size_t max_size = message_limits::MAX_MESSAGE_SIZE) noexcept {
133 if (size > max_size) {
135 }
137 }
138
139
152 [[nodiscard]] static size_t safe_copy(
153 void* dest,
154 size_t dest_size,
155 const void* src,
156 size_t src_size) noexcept {
157 if (!dest || !src || dest_size == 0 || src_size == 0) {
158 return 0;
159 }
160
161 size_t copy_size = std::min(dest_size, src_size);
162 std::memcpy(dest, src, copy_size);
163 return copy_size;
164 }
165
174 [[nodiscard]] static size_t safe_strcpy(
175 char* dest,
176 size_t dest_size,
177 const char* src) noexcept {
178 if (!dest || dest_size == 0 || !src) {
179 return 0;
180 }
181
182 size_t src_len = std::strlen(src);
183 size_t copy_len = std::min(dest_size - 1, src_len);
184
185 std::memcpy(dest, src, copy_len);
186 dest[copy_len] = '\0';
187
188 return copy_len;
189 }
190
203 std::string_view header) noexcept {
204 // Check size
205 if (header.size() > message_limits::MAX_HEADER_SIZE) {
207 }
208
209 // Check for NULL bytes (NULL byte injection attack)
210 if (header.find('\0') != std::string_view::npos) {
212 }
213
214 // Check for invalid control characters (except \r\n\t)
215 for (char c : header) {
216 if (c < 0x20 && c != '\r' && c != '\n' && c != '\t') {
218 }
219 }
220
222 }
223
230 [[nodiscard]] static bool validate_header_count(size_t count) noexcept {
231 return count <= message_limits::MAX_HEADER_COUNT;
232 }
233
241 [[nodiscard]] static bool validate_websocket_frame(
242 size_t payload_length,
243 size_t max_size = message_limits::MAX_WEBSOCKET_FRAME) noexcept {
244 return payload_length <= max_size;
245 }
246
253 [[nodiscard]] static validation_result validate_url(
254 std::string_view url) noexcept {
255 if (url.size() > message_limits::MAX_URL_LENGTH) {
257 }
258
259 if (url.find('\0') != std::string_view::npos) {
261 }
262
264 }
265
275 [[nodiscard]] static bool contains_suspicious_pattern(
276 std::string_view data) noexcept {
277 // Check for NULL byte injection
278 if (data.find('\0') != std::string_view::npos) {
279 return true;
280 }
281
282 // Check for HTTP response splitting
283 if (data.find("\r\n\r\n") != std::string_view::npos) {
284 return true;
285 }
286
287 return false;
288 }
289
296 [[nodiscard]] static std::string sanitize_string(std::string_view input) {
297 std::string result;
298 result.reserve(input.size());
299
300 for (char c : input) {
301 // Keep printable ASCII and common whitespace
302 if (c >= 0x20 || c == '\t' || c == '\n' || c == '\r') {
303 result += c;
304 }
305 }
306
307 return result;
308 }
309
319 [[nodiscard]] static size_t safe_buffer_size(
320 size_t requested_size,
321 size_t max_size = message_limits::MAX_MESSAGE_SIZE) noexcept {
322 return std::min(requested_size, max_size);
323 }
324};
325
326} // namespace kcenon::network
Message validator for network input validation.
static validation_result validate_http_header(std::string_view header) noexcept
Validate HTTP header.
static size_t safe_strcpy(char *dest, size_t dest_size, const char *src) noexcept
Safe string copy with null termination.
static bool contains_suspicious_pattern(std::string_view data) noexcept
Check if data contains potential injection patterns.
static bool validate_header_count(size_t count) noexcept
Validate HTTP header count.
static size_t safe_copy(void *dest, size_t dest_size, const void *src, size_t src_size) noexcept
Safe buffer copy with size validation.
static std::string sanitize_string(std::string_view input)
Sanitize string by removing control characters.
static validation_result validate_size(size_t size, size_t max_size=message_limits::MAX_MESSAGE_SIZE) noexcept
Validate message size against limit.
static bool validate_websocket_frame(size_t payload_length, size_t max_size=message_limits::MAX_WEBSOCKET_FRAME) noexcept
Validate WebSocket frame payload size.
static validation_result validate_url(std::string_view url) noexcept
Validate URL length.
static size_t safe_buffer_size(size_t requested_size, size_t max_size=message_limits::MAX_MESSAGE_SIZE) noexcept
Calculate safe buffer size for operations.
Main namespace for all Network System components.
const char * to_string(validation_result result)
Convert validation result to string.
validation_result
Result type for validation operations.
@ size_exceeded
Size limit exceeded.
@ null_byte_detected
NULL byte found in string.
@ invalid_format
Invalid data format.
@ header_count_exceeded
Too many headers.
@ invalid_character
Invalid character detected.
VoidResult ok()
Configurable message size limits.
static constexpr size_t MAX_HEADER_SIZE
Maximum HTTP header size (default: 8KB - Apache default)
static constexpr size_t MAX_URL_LENGTH
Maximum URL length (default: 2KB)
static constexpr size_t MAX_HEADER_COUNT
Maximum number of HTTP headers (default: 100)
static constexpr size_t MAX_HTTP_LINE
Maximum HTTP request line length (default: 8KB)
static constexpr size_t MAX_WEBSOCKET_FRAME
Maximum WebSocket frame payload (default: 1MB)
static constexpr size_t MAX_MESSAGE_SIZE
Maximum allowed message size (default: 16MB)
static constexpr size_t MAX_COOKIE_SIZE
Maximum cookie size (default: 4KB)