UnboundLocalError: local variable 'fuzzables' referenced before assignment

1.5k views Asked by At

I have problem with python script. When I try to run it with some parameters, I get following error:

  print json.dumps(filter(lambda x: x.get('url'), [x.as_dict() for x in fuzzables]), indent=4)
UnboundLocalError: local variable 'fuzzables' referenced before assignment

I am not a python guy; can someone help me?

The code:

def main():
    form_stack = []
    parser = argparse.ArgumentParser('crawl')
    parser.add_argument('url', type=str, help='Target URL')
    parser.add_argument('-s', '--strict', action='store_true', help='Strict Mode')
    args = parser.parse_args()

    target = get_final_url(args.url)
    ltarget = [target]

    if args.strict:
        br = Browser(qapp=qapp, scope=ltarget, strict_match=target)
    else:
        br = Browser(qapp=qapp, scope=ltarget)

    br.load(target)

    dom_urls = br.get_history(clear=True, verify=True)
    static_urls = br.urls(verify=True)
    static_urls.extend(dom_urls)
    static_urls = list(set(static_urls))

    already = 0

    for url in static_urls:
        already += 1
        if len(static_urls) >= 128:
            break

        try:
            br.load(url, retries=2)
        except BrowserTimeout, e:
            continue

        form_stack.extend(br.forms())
        temporaries = br.urls(verify=True)

        map(lambda x: static_urls.append(x), temporaries)
        dom_urls = br.get_history(clear=True, verify=True)
        s_urls = br.urls(verify=True)
        s_urls.extend(dom_urls)
        s_urls = list(set(s_urls))
        static_urls.extend(s_urls)
        static_urls = list(set(static_urls))
        static_urls = map(make_dummy_url, static_urls)
        fuzzables, hashsums = [], []

        for form in form_stack:
            if form['hashsum'] in hashsums:
                continue
            else:
                hashsums.append(form['hashsum'])

            method = form.get('method', 'POST')
            action = form.get('action', '')
            headers = form.get('headers')
            cookies = form.get('cookies')
            data = unquote(urlencode(form.get('fields', {})))
            action = action.toString() if type(action) != str else action

            if type(data) == str and "__PAYLOAD__" not in data:
                data = parse_qsl(data)
                [data.update(set_payload(x)) for x in data.keys()]
                data = unquote(urlencode(data))

            method = method.upper()
            vhost = urlparse(action).hostname
            fuzzable = Fuzzable(method, action, data, cookies, headers, vhost)
            fuzzables.append(fuzzable)

        for url in static_urls:
            url = url.toString() if type(url) != str else url
            uu = urlparse(url)
            qsl = urlparse(url)
            qsl = parse_qsl(uu.query)

            [qsl.update(set_payload(x)) for x in qsl.keys()]
            qsl = urlencode(qsl)

            qq = "?%s" %qsl
            qq = "" if qq == "?" else qq
            url = "%s://%s%s%s" %(uu.scheme, uu.netloc, uu.path, qq)

            if "__PAYLOAD__" not in url:
                continue

            cookies = br.get_plain_cookies()
            vhost = urlparse(url).hostname
            fields = ""
            headers = {}
            fuzzable = Fuzzable("GET", url, fields, cookies, headers, vhost)
            fuzzables.append(fuzzable)

    """
    fu = urlparse(target)
    path = fu.path
    query = parse_qsl(fu.query)
    [query.update(set_payload(x)) for x in query.keys()]
    query = unquote(urlencode(query))
    rqury = "?%s" %query
    rqury = "" if rqury == "?" else rqury
    temporary_url = "%s://%s%s%s" %(fu.scheme, fu.netloc, path, rqury)
    fields = ""
    cookies = br.get_plain_cookies()
    vhost = urlparse(target).hostname
    headers = {'host': fu.hostname}
    fuzzable = Fuzzable("GET", temporary_url, fields, cookies, headers, vhost)
    fuzzables.append(fuzzable)
    """

    br.close()
    del br

    print json.dumps(filter(lambda x: x.get('url'), [x.as_dict() for x in fuzzables]), indent=4)
3

There are 3 answers

1
recursive On

The error message seems to indicate the problem. You need to assign something to fuzzables before you use it.

For example:

fuzzables = #something
0
Martijn Pieters On

fuzzables is only assigned to in a loop:

for url in static_urls:
    # ...
    if len(static_urls) >= 128:
        break

    # ...

    fuzzables, hashsums = [], []

If static_urls is empty or contains more than 128 items, the assignment line is never reached, and fuzzables remains unbound.

Assign something to fuzzables outside of that loop if you want to guarantee it is bound.

Glancing over that code, you probably do not want to create a new, empty fuzzables for each static_urls entry either.

0
astex On

Given the script linked in the comments, if static_urls is an empty list, then no assignment is ever made to fuzzables, so the variable is undefined when referenced.

You could move the fuzzables = [] assignment outside of the static_urls loop.