From 631ce2c6d6043f2c2f0c8a27faa369ce71f89756 Mon Sep 17 00:00:00 2001 From: schwarze Date: Sat, 19 Jul 2014 13:15:07 +0000 Subject: [PATCH] Security fix: Validate the manpath up front and report a Bad Request if it is not listed in manpath.conf, such that clients can't probe which directories exist on the server. In case of configuration errors, consistently report Internal Server Error without disclosing any further information. Partially based on a patch from Sebastien Marie , but avoiding a couple of issues with that patch and approaching the issue in a somewhat more rigorous way. --- usr.bin/mandoc/cgi.c | 39 ++++++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/usr.bin/mandoc/cgi.c b/usr.bin/mandoc/cgi.c index bf175c8e4b9..ceb3e8d903e 100644 --- a/usr.bin/mandoc/cgi.c +++ b/usr.bin/mandoc/cgi.c @@ -1,4 +1,4 @@ -/* $Id: cgi.c,v 1.16 2014/07/19 11:35:09 schwarze Exp $ */ +/* $Id: cgi.c,v 1.17 2014/07/19 13:15:07 schwarze Exp $ */ /* * Copyright (c) 2011, 2012 Kristaps Dzonsons * Copyright (c) 2014 Ingo Schwarze @@ -462,6 +462,21 @@ resp_searchform(const struct req *req) puts(""); } +static int +validate_manpath(const struct req *req, const char* manpath) +{ + size_t i; + + if ( ! strcmp(manpath, "mandoc")) + return(1); + + for (i = 0; i < req->psz; i++) + if ( ! strcmp(manpath, req->p[i])) + return(1); + + return(0); +} + static int validate_filename(const char *file) { @@ -815,6 +830,12 @@ pg_show(const struct req *req, const char *path) } *sub++ = '\0'; + if ( ! validate_manpath(req, path)) { + pg_error_badrequest( + "You specified an invalid manpath."); + return; + } + /* * Begin by chdir()ing into the manpath. * This way we can pick up the database files, which are @@ -822,8 +843,9 @@ pg_show(const struct req *req, const char *path) */ if (-1 == chdir(path)) { - pg_error_badrequest( - "You specified an invalid manpath."); + fprintf(stderr, "chdir %s: %s\n", + path, strerror(errno)); + pg_error_internal(); return; } @@ -857,8 +879,9 @@ pg_search(const struct req *req) */ if (-1 == (chdir(req->q.manpath))) { - pg_error_badrequest( - "You specified an invalid manpath."); + fprintf(stderr, "chdir %s: %s\n", + req->q.manpath, strerror(errno)); + pg_error_internal(); return; } @@ -950,6 +973,12 @@ main(void) if (NULL != (querystring = getenv("QUERY_STRING"))) http_parse(&req, querystring); + if ( ! validate_manpath(&req, req.q.manpath)) { + pg_error_badrequest( + "You specified an invalid manpath."); + return(EXIT_FAILURE); + } + /* Dispatch to the three different pages. */ path = getenv("PATH_INFO"); -- 2.20.1