geomyidae

A small C-based gopherd. (gopher://bitreich.org/1/scm/geomyidae)
git clone git://r-36.net/geomyidae
Log | Files | Refs | README | LICENSE

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);