aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/http.c23
-rw-r--r--src/routing.c9
-rw-r--r--src/template.c19
3 files changed, 41 insertions, 10 deletions
diff --git a/src/http.c b/src/http.c
index 349f66f..3f6294d 100644
--- a/src/http.c
+++ b/src/http.c
@@ -19,27 +19,32 @@ static void build_cookie_headers(char *cookie_headers_buffer,
cookies_to_set[i].value);
if (strlen(cookies_to_set[i].expires) > 0) {
- strcat(single_cookie_header, "; Expires=");
- strcat(single_cookie_header, cookies_to_set[i].expires);
+ strncat(single_cookie_header, "; Expires=", sizeof(single_cookie_header) - strlen(single_cookie_header) - 1);
+ strncat(single_cookie_header, cookies_to_set[i].expires, sizeof(single_cookie_header) - strlen(single_cookie_header) - 1);
}
if (strlen(cookies_to_set[i].path) > 0) {
- strcat(single_cookie_header, "; Path=");
- strcat(single_cookie_header, cookies_to_set[i].path);
+ strncat(single_cookie_header, "; Path=", sizeof(single_cookie_header) - strlen(single_cookie_header) - 1);
+ strncat(single_cookie_header, cookies_to_set[i].path, sizeof(single_cookie_header) - strlen(single_cookie_header) - 1);
}
if (cookies_to_set[i].http_only) {
- strcat(single_cookie_header, "; HttpOnly");
+ strncat(single_cookie_header, "; HttpOnly", sizeof(single_cookie_header) - strlen(single_cookie_header) - 1);
}
if (cookies_to_set[i].secure) {
- strcat(single_cookie_header, "; Secure");
+ strncat(single_cookie_header, "; Secure", sizeof(single_cookie_header) - strlen(single_cookie_header) - 1);
}
- strcat(single_cookie_header, "\r\n");
+ strncat(single_cookie_header, "\r\n", sizeof(single_cookie_header) - strlen(single_cookie_header) - 1);
- strncat(cookie_headers_buffer, single_cookie_header,
- buffer_size - strlen(cookie_headers_buffer) - 1);
+ if (strlen(cookie_headers_buffer) + strlen(single_cookie_header) < buffer_size) {
+ strncat(cookie_headers_buffer, single_cookie_header,
+ buffer_size - strlen(cookie_headers_buffer) - 1);
+ } else {
+ fprintf(stderr, "[WARNING] build_cookie_headers: Cookie headers buffer full, truncating\n");
+ break;
+ }
}
}
diff --git a/src/routing.c b/src/routing.c
index 98bb531..d5d3969 100644
--- a/src/routing.c
+++ b/src/routing.c
@@ -256,7 +256,14 @@ char *parse_request_url(const char *request_line, UrlParams *params) {
bool serve_static_file_with_mime(const char *request_path_relative_to_static, const char *mime_type) {
char full_static_path[MAX_PATH_LEN];
- if (strstr(request_path_relative_to_static, "..") != NULL) {
+ if (request_path_relative_to_static == NULL || strlen(request_path_relative_to_static) == 0) {
+ fprintf(stderr, "[ERROR] serve_static_file_with_mime: Empty path provided\n");
+ return false;
+ }
+
+ if (strstr(request_path_relative_to_static, "..") != NULL ||
+ strstr(request_path_relative_to_static, "//") != NULL ||
+ request_path_relative_to_static[0] == '/') {
fprintf(stderr, "[SECURITY] Attempted directory traversal: %s\n",
request_path_relative_to_static);
const char *forbidden_response =
diff --git a/src/template.c b/src/template.c
index 3bd583b..20cf10b 100644
--- a/src/template.c
+++ b/src/template.c
@@ -757,6 +757,18 @@ static char *render_template_segment(const char *template_segment,
strncpy(included_filename, filename_start, filename_len);
included_filename[filename_len] = '\0';
+ if (strstr(included_filename, "..") != NULL || strchr(included_filename, '/') != NULL) {
+ fprintf(stderr,
+ "[SECURITY] render_template_segment: Path traversal attempt in include: %s\n",
+ included_filename);
+ free(included_filename);
+ append_to_buffer(&rendered_buffer, &current_len, &max_len,
+ "<!-- Include blocked: path traversal not allowed -->");
+ current_pos = end_tag + 2;
+ free(tag_content_raw);
+ continue;
+ }
+
char *included_html = render_template(included_filename, ctx);
if (included_html) {
append_to_buffer(&rendered_buffer, &current_len, &max_len,
@@ -926,6 +938,13 @@ static char *render_template_segment(const char *template_segment,
char *render_template(const char *template_file, TemplateContext *ctx) {
char full_path[MAX_PATH_LEN];
+ if (strstr(template_file, "..") != NULL) {
+ fprintf(stderr,
+ "[SECURITY] render_template: Path traversal attempt: %s\n",
+ template_file);
+ return NULL;
+ }
+
snprintf(full_path, sizeof(full_path), "%s%s", TEMPLATES_DIR, template_file);
FILE *fp = fopen(full_path, "r");