tests/get-with-headers.py
author Mateusz Kwapich <mitrandir@fb.com>
Tue, 22 Mar 2016 17:27:27 -0700
branchstable
changeset 28663 ae279d4a19e9
parent 27296 8e86679d8acd
child 28726 f4b31fcd5e72
permissions -rwxr-xr-x
convert: test for shell injection in git calls (SEC) CVE-2016-3069 (5/5) Before recent refactoring we were not escaping calls to git at all which made such injections possible. Let's have a test for that to avoid this problem in the future. Reported by Blake Burkhart.

#!/usr/bin/env python

"""This does HTTP GET requests given a host:port and path and returns
a subset of the headers plus the body of the result."""

from __future__ import absolute_import

import httplib
import json
import os
import sys

try:
    import msvcrt
    msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
    msvcrt.setmode(sys.stderr.fileno(), os.O_BINARY)
except ImportError:
    pass

twice = False
if '--twice' in sys.argv:
    sys.argv.remove('--twice')
    twice = True
headeronly = False
if '--headeronly' in sys.argv:
    sys.argv.remove('--headeronly')
    headeronly = True
formatjson = False
if '--json' in sys.argv:
    sys.argv.remove('--json')
    formatjson = True

tag = None
def request(host, path, show):
    assert not path.startswith('/'), path
    global tag
    headers = {}
    if tag:
        headers['If-None-Match'] = tag

    conn = httplib.HTTPConnection(host)
    conn.request("GET", '/' + path, None, headers)
    response = conn.getresponse()
    print response.status, response.reason
    if show[:1] == ['-']:
        show = sorted(h for h, v in response.getheaders()
                      if h.lower() not in show)
    for h in [h.lower() for h in show]:
        if response.getheader(h, None) is not None:
            print "%s: %s" % (h, response.getheader(h))
    if not headeronly:
        print
        data = response.read()

        # Pretty print JSON. This also has the beneficial side-effect
        # of verifying emitted JSON is well-formed.
        if formatjson:
            # json.dumps() will print trailing newlines. Eliminate them
            # to make tests easier to write.
            data = json.loads(data)
            lines = json.dumps(data, sort_keys=True, indent=2).splitlines()
            for line in lines:
                print line.rstrip()
        else:
            sys.stdout.write(data)

        if twice and response.getheader('ETag', None):
            tag = response.getheader('ETag')

    return response.status

status = request(sys.argv[1], sys.argv[2], sys.argv[3:])
if twice:
    status = request(sys.argv[1], sys.argv[2], sys.argv[3:])

if 200 <= status <= 305:
    sys.exit(0)
sys.exit(1)