Mercurial > hg-stable
view doc/docchecker @ 41314:31286c9282df stable
subrepo: extend path auditing test to include more weird patterns (SEC)
While reviewing patches for the issue 5739, "$foo in repository path
expanded", I realized that subrepo paths can also be cheated. This patch
includes various subrepo paths which are potentially unsafe.
Since an expanded subrepo path isn't audited, this bug allows symlink check
bypass. As a result, a malicious subrepository could be checked out to a
sub tree of e.g. $HOME directory. The good news is that the destination
directory must be empty or nonexistent, so the existing ~/.bashrc wouldn't
be overwritten. See the last part of the tests for details.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Tue, 08 Jan 2019 21:51:54 +0900 |
parents | 9bfbb9fc5871 |
children | 47ef023d0165 |
line wrap: on
line source
#!/usr/bin/env python # # docchecker - look for problematic markup # # Copyright 2016 timeless <timeless@mozdev.org> and others # # This software may be used and distributed according to the terms of the # GNU General Public License version 2 or any later version. from __future__ import absolute_import, print_function import os import re import sys try: import msvcrt msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) msvcrt.setmode(sys.stderr.fileno(), os.O_BINARY) except ImportError: pass stdout = getattr(sys.stdout, 'buffer', sys.stdout) leadingline = re.compile(br'(^\s*)(\S.*)$') checks = [ (br""":hg:`[^`]*'[^`]*`""", b"""warning: please avoid nesting ' in :hg:`...`"""), (br'\w:hg:`', b'warning: please have a space before :hg:'), (br"""(?:[^a-z][^'.])hg ([^,;"`]*'(?!hg)){2}""", b'''warning: please use " instead of ' for hg ... "..."'''), ] def check(line): messages = [] for match, msg in checks: if re.search(match, line): messages.append(msg) if messages: stdout.write(b'%s\n' % line) for msg in messages: stdout.write(b'%s\n' % msg) def work(file): (llead, lline) = (b'', b'') for line in file: # this section unwraps lines match = leadingline.match(line) if not match: check(lline) (llead, lline) = (b'', b'') continue lead, line = match.group(1), match.group(2) if (lead == llead): if (lline != b''): lline += b' ' + line else: lline = line else: check(lline) (llead, lline) = (lead, line) check(lline) def main(): for f in sys.argv[1:]: try: with open(f, 'rb') as file: work(file) except BaseException as e: sys.stdout.write(r"failed to process %s: %s\n" % (f, e)) main()