Edgewall Software
Modify

Opened 5 years ago

Closed 5 years ago

Last modified 5 years ago

#12403 closed defect (fixed)

TypeError: execv() arg 2 must contain only strings

Reported by: Ryan J Ollos Owned by: Jun Omae
Priority: normal Milestone: 1.0.11
Component: web frontend Version:
Severity: normal Keywords:
Cc: Branch:
Release Notes:

Null bytes in request argument for name, value or filename raises an HTTPBadRequest exception.

API Changes:
Internal Changes:

Description

From the logs:

[pid 7564 139730844530432] 2016-03-14 16:05:09,876 Trac[main] ERROR: Internal Server Error: <RequestWithSession "GET '/changeset?new=302bd3796163449f419a328fb5ce566b6cc55948@/&old=14519%2540/<%00ScRiPt%20%0d%0a>prompt(937841)</ScRiPt>&reponame=psuter.git&sfph_mail=&sfp_email=sample@email.tst'">, referrer 'http://trac.edgewall.org/'
Traceback (most recent call last):
  File "/usr/local/virtualenv/1.1dev/lib/python2.7/site-packages/trac/web/main.py", line 607, in _dispatch_request
    dispatcher.dispatch(req)
  File "/usr/local/virtualenv/1.1dev/lib/python2.7/site-packages/trac/web/main.py", line 256, in dispatch
    resp = chosen_handler.process_request(req)
  File "/usr/local/virtualenv/1.1dev/lib/python2.7/site-packages/trac/versioncontrol/web_ui/changeset.py", line 256, in process_request
    old = repos.normalize_rev(old or new)
  File "/usr/local/virtualenv/1.1dev/lib/python2.7/site-packages/tracopt/versioncontrol/git/git_fs.py", line 534, in normalize_rev
    normrev = self.git.verifyrev(rev)
  File "/usr/local/virtualenv/1.1dev/lib/python2.7/site-packages/tracopt/versioncontrol/git/PyGIT.py", line 717, in verifyrev
    rc = self.repo.rev_parse('--verify', rev).strip()
  File "/usr/local/virtualenv/1.1dev/lib/python2.7/site-packages/tracopt/versioncontrol/git/PyGIT.py", line 139, in __execute
    p = self.__pipe(git_cmd, stdout=PIPE, stderr=PIPE, *cmd_args)
  File "/usr/local/virtualenv/1.1dev/lib/python2.7/site-packages/tracopt/versioncontrol/git/PyGIT.py", line 132, in __pipe
    close_fds=close_fds, **kw)
  File "/usr/lib/python2.7/subprocess.py", line 710, in __init__
    errread, errwrite)
  File "/usr/lib/python2.7/subprocess.py", line 1335, in _execute_child
    raise child_exception
TypeError: execv() arg 2 must contain only strings

This looks to be similar to #11291.

Attachments (0)

Change History (7)

comment:1 by Jun Omae, 5 years ago

Null byte attack. This issue is caused by passing null byte to Popen().

>>> from subprocess import Popen
>>> Popen(('/bin/echo', '123')).wait()
123
0
>>> Popen(('/bin/echo', '12\x003')).wait()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/subprocess.py", line 710, in __init__
    errread, errwrite)
  File "/usr/lib/python2.7/subprocess.py", line 1327, in _execute_child
    raise child_exception
TypeError: execv() arg 2 must contain only strings

It seems os.exec* family disallows null bytes.

$ LANG=C python -c "import os; os.execv('/bin/echo', ('/bin/echo', '1\x0023'))"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
TypeError: execv() arg 2 must contain only strings
$ LANG=en_US.UTF-8 python -c "import os; os.execv('/bin/echo', ('/bin/echo', '1\x0023'))"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
TypeError: execv() arg 2 must contain only strings
Version 0, edited 5 years ago by Jun Omae (next)

comment:2 by Jun Omae, 5 years ago

I think we could reject such a request with null bytes.

  • trac/web/api.py

    diff --git a/trac/web/api.py b/trac/web/api.py
    index 0ea3e05af..b2599330c 100644
    a b class Request(object):  
    729729        args = []
    730730        for value in fs.list or ():
    731731            try:
    732                 name = unicode(value.name, 'utf-8')
    733                 if not value.filename:
    734                     value = unicode(value.value, 'utf-8')
     732                name = value.name
     733                if '\x00' in name:
     734                    raise HTTPBadRequest(_("Invalid request arguments."))
     735                name = unicode(name, 'utf-8')
     736                if value.filename:
     737                    if '\x00' in value.filename:
     738                        raise HTTPBadRequest(_("Invalid request arguments."))
     739                else:
     740                    value = value.value
     741                    if '\x00' in value:
     742                        raise HTTPBadRequest(_("Invalid request arguments."))
     743                    value = unicode(value, 'utf-8')
    735744            except UnicodeDecodeError, e:
    736745                raise HTTPBadRequest(
    737746                    _("Invalid encoding in form data: %(msg)s",
Last edited 5 years ago by Jun Omae (previous) (diff)

comment:3 by Ryan J Ollos, 5 years ago

#12404 closed as a duplicate.

comment:4 by Ryan J Ollos, 5 years ago

Milestone: next-stable-1.0.x1.0.11

comment:5 by Ryan J Ollos, 5 years ago

Release Notes: modified (diff)

Thanks for the patch. I added tests in log:rjollos.git:t12403.

comment:6 by Ryan J Ollos, 5 years ago

Resolution: fixed
Status: newclosed

Committed to 1.0-stable in [14609], merged to trunk in [14610].

comment:7 by Ryan J Ollos, 5 years ago

Component: plugin/gitweb frontend
Owner: set to Jun Omae

Modify Ticket

Change Properties
Set your email in Preferences
Action
as closed The owner will remain Jun Omae.
The resolution will be deleted. Next status will be 'reopened'.
to The owner will be changed from Jun Omae to the specified user.

Add Comment


E-mail address and name can be saved in the Preferences .
 
Note: See TracTickets for help on using tickets.