commit 4028ae9814ff6ca97632004c67557e04ce639df3
parent 3ed956cf71a15015b443dd7ab36299c242acd1af
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Fri, 30 Jun 2017 15:12:40 +0200
remove securepath, simply reject relative paths: .., check / prefix
we could escape the path if for example the base dir was "base" and a
secret directory starts with a name: "base.secret". The request
".secret/secretfile" would translate to "base.secret/secretfile".
reject relative paths: securepath() currently converts paths from
"/../file" to "/.//file" which won't work, so remove it.
always check if a path starts with "/" or is empty.
Signed-off-by: Christoph Lohmann <20h@r-36.net>
Diffstat:
main.c | | | 27 | +++------------------------ |
1 file changed, 3 insertions(+), 24 deletions(-)
diff --git a/main.c b/main.c
@@ -82,28 +82,6 @@ dropprivileges(struct group *gr, struct passwd *pw)
return 0;
}
-char *
-securepath(char *p, int len)
-{
- int i;
-
- if(len < 2)
- return p;
-
- for(i = 1; i < strlen(p); i++) {
- if(p[i - 1] == '.' && p[i] == '.') {
- if(p[i - 2] == '/')
- p[i] = '/';
- if(p[i + 1] == '/')
- p[i] = '/';
- if(len == 2)
- p[i] = '/';
- }
- }
-
- return p;
-}
-
void
logentry(char *host, char *port, char *qry, char *status)
{
@@ -171,11 +149,12 @@ handlerequest(int sock, char *base, char *ohost, char *port, char *clienth,
if(args != nil)
*args++ = '\0';
- securepath(recvb, len - 2);
- if(strlen(recvb) == 0) {
+ if(recvb[0] == '\0') {
recvb[0] = '/';
recvb[1] = '\0';
}
+ if(recvb[0] != '/' || strstr(recvb, ".."))
+ return;
snprintf(path, sizeof(path), "%s%s", base, recvb);