changeset 37156:7de7bd407251 stable 4.5.3

server: ensure the incoming request falls under the prefix value Prior to this, the first test asserted in wsgiref.validate.check_environ() saying PATH didn't start with '/', but the second test served up the repo. The assertion was just added in this cycle (though the value of PATH is still wrong without the assertion). Allowing access to the repo at any URL outside of the prefix is a long standing bug. This also affected hgwebdir, at least when used via --subrepo. Paths are not being canonicalized, so accesses to things like 'foo/../bar' will get tossed out here, unless the prefix also matches.
author Matt Harbison <matt_harbison@yahoo.com>
date Sun, 01 Apr 2018 01:27:18 -0400
parents 177f3b90335f
children 61f6cee88940
files mercurial/hgweb/server.py tests/test-serve.t
diffstat 2 files changed, 28 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/hgweb/server.py	Thu Mar 15 22:35:07 2018 -0700
+++ b/mercurial/hgweb/server.py	Sun Apr 01 01:27:18 2018 -0400
@@ -118,6 +118,14 @@
         self.sent_headers = False
         path, query = _splitURI(self.path)
 
+        # Ensure the slicing of path below is valid
+        if (path != self.server.prefix
+            and not path.startswith(self.server.prefix + b'/')):
+            self._start_response(common.statusmessage(404), [])
+            self._write("Not Found")
+            self._done()
+            return
+
         env = {}
         env[r'GATEWAY_INTERFACE'] = r'CGI/1.1'
         env[r'REQUEST_METHOD'] = self.command
--- a/tests/test-serve.t	Thu Mar 15 22:35:07 2018 -0700
+++ b/tests/test-serve.t	Sun Apr 01 01:27:18 2018 -0400
@@ -78,4 +78,24 @@
   listening at http://localhost/foo/ (bound to *$LOCALIP*:HGPORT1) (glob) (?)
   % errors
 
+  $ $PYTHON $RUNTESTDIR/killdaemons.py $DAEMON_PIDS
+
+With out of bounds accesses
+
+  $ rm access.log
+  $ hg serve -a localhost -p $HGPORT -d --prefix some/dir \
+  >    --pid-file=hg.pid -E errors.log
+  $ cat hg.pid >> "$DAEMON_PIDS"
+
+  $ hg id http://localhost:$HGPORT/some/dir7
+  abort: HTTP Error 404: Not Found
+  [255]
+  $ hg id http://localhost:$HGPORT/some
+  abort: HTTP Error 404: Not Found
+  [255]
+
+  $ cat access.log errors.log
+  $LOCALIP - - [$LOGDATE$] "GET /some/dir7?cmd=capabilities HTTP/1.1" 404 - (glob)
+  $LOCALIP - - [$LOGDATE$] "GET /some?cmd=capabilities HTTP/1.1" 404 - (glob)
+
   $ cd ..