aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/cgi.c
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2014-07-22 18:14:13 +0000
committerIngo Schwarze <schwarze@openbsd.org>2014-07-22 18:14:13 +0000
commitb60b23600ca14efd4017a9f23b6e2044118a886c (patch)
treeb142b381b0eb342d20376912a5fead60878a1cee /cgi.c
parentaba9031e6363caf45106966958a9572dde8fc7f3 (diff)
downloadmandoc-b60b23600ca14efd4017a9f23b6e2044118a886c.tar.gz
mandoc-b60b23600ca14efd4017a9f23b6e2044118a886c.tar.zst
mandoc-b60b23600ca14efd4017a9f23b6e2044118a886c.zip
Security fix to prevent XSS attacks:
Restrict the character set of strings passed into html_alloc(), in particular architecture names that come from the QUERY_STRING, but also SCRIPT_NAME and manpath.conf content for additional safety, and bail out safely on violations. Issue reported by Sebastien Marie <semarie-openbsd at latrappe dot fr>.
Diffstat (limited to 'cgi.c')
-rw-r--r--cgi.c44
1 files changed, 42 insertions, 2 deletions
diff --git a/cgi.c b/cgi.c
index 9445845b..0b3ac814 100644
--- a/cgi.c
+++ b/cgi.c
@@ -1,4 +1,4 @@
-/* $Id: cgi.c,v 1.79 2014/07/21 22:33:01 schwarze Exp $ */
+/* $Id: cgi.c,v 1.80 2014/07/22 18:14:13 schwarze Exp $ */
/*
* Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2014 Ingo Schwarze <schwarze@usta.de>
@@ -467,6 +467,20 @@ resp_searchform(const struct req *req)
}
static int
+validate_urifrag(const char *frag)
+{
+
+ while ('\0' != *frag) {
+ if ( ! (isalnum((unsigned char)*frag) ||
+ '-' == *frag || '.' == *frag ||
+ '/' == *frag || '_' == *frag))
+ return(0);
+ frag++;
+ }
+ return(1);
+}
+
+static int
validate_manpath(const struct req *req, const char* manpath)
{
size_t i;
@@ -960,6 +974,13 @@ main(void)
if (NULL == (scriptname = getenv("SCRIPT_NAME")))
scriptname = "";
+ if ( ! validate_urifrag(scriptname)) {
+ fprintf(stderr, "unsafe SCRIPT_NAME \"%s\"\n",
+ scriptname);
+ pg_error_internal();
+ return(EXIT_FAILURE);
+ }
+
/*
* First we change directory into the MAN_DIR so that
* subsequent scanning for manpath directories is rooted
@@ -987,6 +1008,12 @@ main(void)
return(EXIT_FAILURE);
}
+ if ( ! (NULL == req.q.arch || validate_urifrag(req.q.arch))) {
+ pg_error_badrequest(
+ "You specified an invalid architecture.");
+ return(EXIT_FAILURE);
+ }
+
/* Dispatch to the three different pages. */
path = getenv("PATH_INFO");
@@ -1038,7 +1065,20 @@ pathgen(struct req *req)
dpsz--;
req->p = mandoc_realloc(req->p,
(req->psz + 1) * sizeof(char *));
- req->p[req->psz++] = mandoc_strndup(dp, dpsz);
+ dp = mandoc_strndup(dp, dpsz);
+ if ( ! validate_urifrag(dp)) {
+ fprintf(stderr, "%s/manpath.conf contains "
+ "unsafe path \"%s\"\n", MAN_DIR, dp);
+ pg_error_internal();
+ exit(EXIT_FAILURE);
+ }
+ if (NULL != strchr(dp, '/')) {
+ fprintf(stderr, "%s/manpath.conf contains "
+ "path with slash \"%s\"\n", MAN_DIR, dp);
+ pg_error_internal();
+ exit(EXIT_FAILURE);
+ }
+ req->p[req->psz++] = dp;
}
if ( req->p == NULL ) {