Mercurial > hg
changeset 31790:62f9679df1f2
hgweb: extract path traversal checking into standalone function
A common exploit in web applications that access paths is to insert
path separator strings like ".." to try to get the server to serve up
files it shouldn't.
We have code for detecting this in staticfile(). A subsequent commit
will need to perform this test as well. Since this is security code,
let's factor the check so we don't have to reinvent the wheel.
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Fri, 31 Mar 2017 21:47:26 -0700 |
parents | 161a87ed456e |
children | 39f6333e968c |
files | mercurial/hgweb/common.py |
diffstat | 1 files changed, 15 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/hgweb/common.py Fri Mar 31 22:30:38 2017 -0700 +++ b/mercurial/hgweb/common.py Fri Mar 31 21:47:26 2017 -0700 @@ -135,6 +135,17 @@ def get_mtime(spath): return get_stat(spath, "00changelog.i").st_mtime +def ispathsafe(path): + """Determine if a path is safe to use for filesystem access.""" + parts = path.split('/') + for part in parts: + if (part in ('', os.curdir, os.pardir) or + pycompat.ossep in part or + pycompat.osaltsep is not None and pycompat.osaltsep in part): + return False + + return True + def staticfile(directory, fname, req): """return a file inside directory with guessed Content-Type header @@ -144,13 +155,10 @@ Return an empty string if fname is illegal or file not found. """ - parts = fname.split('/') - for part in parts: - if (part in ('', os.curdir, os.pardir) or - pycompat.ossep in part or - pycompat.osaltsep is not None and pycompat.osaltsep in part): - return - fpath = os.path.join(*parts) + if not ispathsafe(fname): + return + + fpath = os.path.join(*fname.split('/')) if isinstance(directory, str): directory = [directory] for d in directory: