]> git.cameronkatri.com Git - mandoc.git/commitdiff
Security fix to prevent XSS attacks:
authorIngo Schwarze <schwarze@openbsd.org>
Tue, 22 Jul 2014 18:14:13 +0000 (18:14 +0000)
committerIngo Schwarze <schwarze@openbsd.org>
Tue, 22 Jul 2014 18:14:13 +0000 (18:14 +0000)
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>.

cgi.c
man.cgi.8

diff --git a/cgi.c b/cgi.c
index 9445845bc1e77ced9670e6829571e2a26ad33999..0b3ac81405b101beb7f59b875f819f6651b69645 100644 (file)
--- 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>
@@ -466,6 +466,20 @@ resp_searchform(const struct req *req)
        puts("<!-- End search form. //-->");
 }
 
+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)
 {
@@ -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 ) {
index 74ab525aa3d7384424cc3dde87c14a04c50d006b..69335e632ec99453ab02fcda0d86bb3d69d67881 100644 (file)
--- a/man.cgi.8
+++ b/man.cgi.8
@@ -1,4 +1,4 @@
-.\"     $Id: man.cgi.8,v 1.8 2014/07/21 15:45:17 schwarze Exp $
+.\"     $Id: man.cgi.8,v 1.9 2014/07/22 18:14:13 schwarze Exp $
 .\"
 .\" Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
 .\"
@@ -14,7 +14,7 @@
 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
-.Dd $Mdocdate: July 21 2014 $
+.Dd $Mdocdate: July 22 2014 $
 .Dt MAN.CGI 8
 .Os
 .Sh NAME
@@ -267,6 +267,34 @@ For backward compatibility with the traditional
 is supported as an alias for
 .Cm sec .
 .El
+.Ss Restricted character set
+For security reasons, in particular to prevent cross site scripting
+attacks, some strings used by
+.Nm
+can only contain the following characters:
+.Pp
+.Bl -dash -compact -offset indent
+.It
+lower case and upper case ASCII letters
+.It
+the ten decimal digits
+.It
+the dash
+.Pq Sq -
+.It
+the dot
+.Pq Sq \&.
+.It
+the slash
+.Pq Sq /
+.It
+the underscore
+.Pq Sq _
+.El
+.Pp
+In particular, this applies to the
+.Ev SCRIPT_NAME ,
+to all manpaths, and to all architecture names.
 .Sh ENVIRONMENT
 The web server may pass the following CGI variables to
 .Nm :
@@ -293,6 +321,10 @@ binary relative to the server root, usually
 .Pa /cgi-bin/man.cgi .
 This is used for generating URIs to be embedded
 in generated HTML code and HTTP headers.
+If this contains any character not contained in the
+.Sx Restricted character set ,
+.Nm
+reports an internal server error and exits without doing anything.
 .El
 .Sh FILES
 .Bl -tag -width Ds
@@ -332,6 +364,12 @@ Manual pages documenting
 itself, linked from the index page.
 .It Pa /man/manpath.conf
 The list of available manpaths, one per line.
+If any of the lines in this file contains a slash
+.Pq Sq /
+or any character not contained in the
+.Sx Restricted character set ,
+.Nm
+reports an internal server error and exits without doing anything.
 .It Pa /man/OpenBSD-current/man1/mandoc.1
 An example
 .Xr mdoc 7