Mercurial > hg
comparison mercurial/dispatch.py @ 32050:77eaf9539499 stable 4.1.3
dispatch: protect against malicious 'hg serve --stdio' invocations (sec)
Some shared-ssh installations assume that 'hg serve --stdio' is a safe
command to run for minimally trusted users. Unfortunately, the messy
implementation of argument parsing here meant that trying to access a
repo named '--debugger' would give the user a pdb prompt, thereby
sidestepping any hoped-for sandboxing. Serving repositories over HTTP(S)
is unaffected.
We're not currently hardening any subcommands other than 'serve'. If
your service exposes other commands to users with arbitrary repository
names, it is imperative that you defend against repository names of
'--debugger' and anything starting with '--config'.
The read-only mode of hg-ssh stopped working because it provided its hook
configuration to "hg serve --stdio" via --config parameter. This is banned for
security reasons now. This patch switches it to directly call ui.setconfig().
If your custom hosting infrastructure relies on passing --config to
"hg serve --stdio", you'll need to find a different way to get that configuration
into Mercurial, either by using ui.setconfig() as hg-ssh does in this patch,
or by placing an hgrc file someplace where Mercurial will read it.
mitrandir@fb.com provided some extra fixes for the dispatch code and
for hg-ssh in places that I overlooked.
author | Augie Fackler <augie@google.com> |
---|---|
date | Wed, 12 Apr 2017 11:23:55 -0700 |
parents | caf7e1c5efe4 |
children | 616e788321cc |
comparison
equal
deleted
inserted
replaced
31760:68f263f52d2e | 32050:77eaf9539499 |
---|---|
153 signal.signal(num, catchterm) | 153 signal.signal(num, catchterm) |
154 except ValueError: | 154 except ValueError: |
155 pass # happens if called in a thread | 155 pass # happens if called in a thread |
156 | 156 |
157 def _runcatchfunc(): | 157 def _runcatchfunc(): |
158 realcmd = None | |
159 try: | |
160 cmdargs = fancyopts.fancyopts(req.args[:], commands.globalopts, {}) | |
161 cmd = cmdargs[0] | |
162 aliases, entry = cmdutil.findcmd(cmd, commands.table, False) | |
163 realcmd = aliases[0] | |
164 except (error.UnknownCommand, error.AmbiguousCommand, | |
165 IndexError, getopt.GetoptError): | |
166 # Don't handle this here. We know the command is | |
167 # invalid, but all we're worried about for now is that | |
168 # it's not a command that server operators expect to | |
169 # be safe to offer to users in a sandbox. | |
170 pass | |
171 if realcmd == 'serve' and '--stdio' in cmdargs: | |
172 # We want to constrain 'hg serve --stdio' instances pretty | |
173 # closely, as many shared-ssh access tools want to grant | |
174 # access to run *only* 'hg -R $repo serve --stdio'. We | |
175 # restrict to exactly that set of arguments, and prohibit | |
176 # any repo name that starts with '--' to prevent | |
177 # shenanigans wherein a user does something like pass | |
178 # --debugger or --config=ui.debugger=1 as a repo | |
179 # name. This used to actually run the debugger. | |
180 if (len(req.args) != 4 or | |
181 req.args[0] != '-R' or | |
182 req.args[1].startswith('--') or | |
183 req.args[2] != 'serve' or | |
184 req.args[3] != '--stdio'): | |
185 raise error.Abort( | |
186 _('potentially unsafe serve --stdio invocation: %r') % | |
187 (req.args,)) | |
188 | |
158 try: | 189 try: |
159 debugger = 'pdb' | 190 debugger = 'pdb' |
160 debugtrace = { | 191 debugtrace = { |
161 'pdb' : pdb.set_trace | 192 'pdb' : pdb.set_trace |
162 } | 193 } |