summaryrefslogtreecommitdiffstats
path: root/cgi.c
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2014-07-19 13:15:11 +0000
committerIngo Schwarze <schwarze@openbsd.org>2014-07-19 13:15:11 +0000
commit28d7e7b9d246e8eb2a7500e0f10b1c56e146c901 (patch)
tree9bbf2aaa4a1f727690da47a64c04186afaa3ec49 /cgi.c
parenta96928e9475061fac88468b762b3335bb8af06f2 (diff)
downloadmandoc-28d7e7b9d246e8eb2a7500e0f10b1c56e146c901.tar.gz
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 <semarie-openbsd at latrappe dot fr>, but avoiding a couple of issues with that patch and approaching the issue in a somewhat more rigorous way.
Diffstat (limited to 'cgi.c')
-rw-r--r--cgi.c37
1 files changed, 33 insertions, 4 deletions
diff --git a/cgi.c b/cgi.c
index 1e962ebe..59e767e5 100644
--- a/cgi.c
+++ b/cgi.c
@@ -467,6 +467,21 @@ resp_searchform(const struct req *req)
}
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)
{
@@ -819,6 +834,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
@@ -826,8 +847,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;
}
@@ -861,8 +883,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;
}
@@ -954,6 +977,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");