summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Douillet <vincent@vdouillet.fr>2023-09-21 14:47:34 +0200
committerVincent Douillet <vincent@vdouillet.fr>2023-09-21 15:12:22 +0200
commit3ce346efc3211c214c8953c43f936a2da40abd92 (patch)
tree71c19c496f16c86da615ac5cedbea90f4010b2eb
parent2acc8db2762b98eb061241109877527d58a560bc (diff)
use realpath
-rw-r--r--url.c25
1 files changed, 19 insertions, 6 deletions
diff --git a/url.c b/url.c
index 53a26dc..72c02a0 100644
--- a/url.c
+++ b/url.c
@@ -31,24 +31,37 @@
#include <assert.h>
#include <limits.h>
#include <stdarg.h>
+#include <stdlib.h>
#include <string.h>
+#include "config.h"
#include "url.h"
bool
check_request_path(char *path)
{
- char *p_found;
+ char p [PATH_MAX], resolved[PATH_MAX];
+ char *rp;
- if (strlen(path) >= PATH_MAX)
+ /* build absolute path from DATA_DIR */
+ if (strlcpy(p, DATA_DIR, sizeof(p)) >= sizeof(p))
+ return false;
+ if (strlcat(p, "/", sizeof(p)) >= sizeof(p))
+ return false;
+ if (strlcat(p, path, sizeof(p)) >= sizeof(p))
+ return false;
+
+ /* canonicalize the path */
+ rp = realpath(p, resolved);
+ if (rp == NULL)
return false;
- p_found = strstr(path, "/..");
- if (p_found != NULL)
+ /* path must start with DATA_DIR */
+ rp[PATH_MAX - 1] = '\0';
+ if (strstr(rp, DATA_DIR) != rp)
return false;
- p_found = strstr(path, "../");
- return p_found == NULL;
+ return true;
}
size_t