Example #1
0
    def create_vuln(self):
        v = super(FileUploadTemplate, self).create_vuln()

        form_params = FormParameters()
        for file_var in self.file_vars:
            form_params.add_file_input([("name", file_var), ("type", "file")])

        for token in self.data.iter_tokens():
            if token.get_name() in self.file_vars:
                continue

            form_params.add_input([("name", token.get_value()),
                                   ("type", "text")])

        mpc = MultipartContainer(form_params)

        freq = FuzzableRequest(self.url, method=self.method, post_data=mpc)

        mutant = PostDataMutant(freq)
        mutant.set_dc(mpc)
        mutant.set_token((self.vulnerable_parameter, 0))

        # User configured settings
        v['file_vars'] = self.file_vars
        v['file_dest'] = self.file_dest
        v.set_mutant(mutant)
        return v
Example #2
0
    def test_found_at(self):
        form_params = FormParameters()
        form_params.add_input([("name", "username"), ("value", "")])
        form_params.add_input([("name", "address"), ("value", "")])

        form = URLEncodedForm(form_params)
        freq = FuzzableRequest(URL('http://www.w3af.com/?id=3'), post_data=form,
                               method='PUT')
        m = PostDataMutant(freq)
        m.get_dc().set_token(('username', 0))

        expected = '"http://www.w3af.com/?id=3", using HTTP method PUT. '\
                   'The sent post-data was: "username=&address=" '\
                   'which modifies the "username" parameter.'
        self.assertEqual(m.found_at(), expected)
Example #3
0
    def test_found_at(self):
        form = Form()
        form.add_input([("name", "username"), ("value", "")])
        form.add_input([("name", "address"), ("value", "")])

        freq = HTTPPostDataRequest(URL('http://www.w3af.com/?id=3'),
                                   dc=form,
                                   method='PUT')
        m = PostDataMutant(freq)
        m.set_var('username')

        expected = '"http://www.w3af.com/?id=3", using HTTP method PUT. '\
                   'The sent post-data was: "username=&address=" '\
                   'which modifies the "username" parameter.'
        self.assertEqual(m.found_at(), expected)
    def test_found_at(self):
        form_params = FormParameters()
        form_params.add_field_by_attr_items([("name", "username"), ("value", "")])
        form_params.add_field_by_attr_items([("name", "address"), ("value", "")])

        form = URLEncodedForm(form_params)
        freq = FuzzableRequest(URL('http://www.w3af.com/?id=3'), post_data=form,
                               method='PUT')
        m = PostDataMutant(freq)
        m.get_dc().set_token(('username', 0))

        expected = '"http://www.w3af.com/?id=3", using HTTP method PUT. '\
                   'The sent post-data was: "username=&address=" '\
                   'which modifies the "username" parameter.'
        self.assertEqual(m.found_at(), expected)
Example #5
0
    def test_mutant_creation(self):
        form = Form()
        form.add_input([("name", "username"), ("value", "")])
        form.add_input([("name", "address"), ("value", "")])

        freq = HTTPPostDataRequest(URL('http://www.w3af.com/?id=3'),
                                   dc=form,
                                   method='PUT')

        created_mutants = PostDataMutant.create_mutants(
            freq, self.payloads, [], False, self.fuzzer_config)

        expected_dc_lst = [
            Form([('username', ['abc']), ('address', ['Bonsai Street 123'])]),
            Form([('username', ['def']), ('address', ['Bonsai Street 123'])]),
            Form([('username', ['John8212']), ('address', ['abc'])]),
            Form([('username', ['John8212']), ('address', ['def'])])
        ]

        created_dc_lst = [i.get_dc() for i in created_mutants]

        self.assertEqual(created_dc_lst, expected_dc_lst)

        self.assertEqual(created_mutants[0].get_var(), 'username')
        self.assertEqual(created_mutants[0].get_var_index(), 0)
        self.assertEqual(created_mutants[0].get_original_value(), '')
        self.assertEqual(created_mutants[2].get_var(), 'address')
        self.assertEqual(created_mutants[2].get_var_index(), 0)
        self.assertEqual(created_mutants[2].get_original_value(), '')

        for m in created_mutants:
            self.assertIsInstance(m, PostDataMutant)

        for m in created_mutants:
            self.assertEqual(m.get_method(), 'PUT')
Example #6
0
    def test_mutant_creation_repeated_parameter_name(self):
        form_params = FormParameters()
        form_params.add_input([("name", "id"), ("value", "")])
        form_params.add_input([("name", "id"), ("value", "")])

        form = URLEncodedForm(form_params)
        freq = FuzzableRequest(URL('http://w3af.com/?foo=3'), post_data=form,
                               method='GET')

        created_mutants = PostDataMutant.create_mutants(freq, self.payloads, [],
                                                        False,
                                                        self.fuzzer_config)

        expected_dcs = ['id=def&id=3419',
                        'id=3419&id=def',
                        'id=3419&id=abc',
                        'id=abc&id=3419']

        created_dcs = [str(i.get_dc()) for i in created_mutants]

        self.assertEqual(set(created_dcs), set(expected_dcs))

        token = created_mutants[0].get_token()
        self.assertEqual(token.get_name(), 'id')
        self.assertEqual(token.get_original_value(), '')

        token = created_mutants[2].get_token()
        self.assertEqual(token.get_name(), 'id')
        self.assertEqual(token.get_original_value(), '')

        for m in created_mutants:
            self.assertIsInstance(m, PostDataMutant)

        for m in created_mutants:
            self.assertEqual(m.get_method(), 'GET')
Example #7
0
    def GET2POST(self, vuln):
        """
        This method changes a vulnerability mutant, so all the data that was
        sent in the query string, is now sent in the postData; of course, the
        HTTP method is also changed from GET to POST.
        """
        vuln_copy = copy.deepcopy(vuln)
        mutant = vuln_copy.get_mutant()

        #    Sometimes there is no mutant (php_sca).
        if mutant is None:
            return vuln_copy

        if mutant.get_method() == 'POST':
            # No need to work !
            return vuln_copy

        else:
            # Need to create a new PostDataMutant, to be able to easily change
            # the values which we want to send in the HTTP post-data
            fre = FuzzableRequest(mutant.get_url(),
                                  headers=mutant.get_headers(),
                                  method='POST',
                                  cookie=mutant.get_cookie(),
                                  post_data=mutant.get_uri().querystring)
            pdm = PostDataMutant(fre)
            vuln_copy.set_mutant(pdm)

            return vuln_copy
Example #8
0
    def test_mutant_creation_qs_and_postdata(self):
        form_params = FormParameters()
        form_params.add_field_by_attr_items([("name", "username"),
                                             ("value", "")])
        form_params.add_field_by_attr_items([("name", "password"),
                                             ("value", "")])

        url = URL('http://moth/foo.bar?action=login')

        form = URLEncodedForm(form_params)
        freq = FuzzableRequest(url, post_data=form)

        created_mutants = PostDataMutant.create_mutants(
            freq, self.payloads, [], False, self.fuzzer_config)
        created_dcs = [str(i.get_dc()) for i in created_mutants]

        expected_dcs = [
            'username=abc&password=FrAmE30.', 'username=John8212&password=abc',
            'username=def&password=FrAmE30.', 'username=John8212&password=def'
        ]

        self.assertEqual(created_dcs, expected_dcs)

        for m in created_mutants:
            self.assertEqual(m.get_uri(), url)
Example #9
0
    def test_mutant_creation_repeated_parameter_name(self):
        form_params = FormParameters()
        form_params.add_field_by_attr_items([("name", "id"), ("value", "")])
        form_params.add_field_by_attr_items([("name", "id"), ("value", "")])

        form = URLEncodedForm(form_params)
        freq = FuzzableRequest(URL('http://w3af.com/?foo=3'),
                               post_data=form,
                               method='GET')

        created_mutants = PostDataMutant.create_mutants(
            freq, self.payloads, [], False, self.fuzzer_config)

        expected_dcs = [
            'id=def&id=3419', 'id=3419&id=def', 'id=3419&id=abc',
            'id=abc&id=3419'
        ]

        created_dcs = [str(i.get_dc()) for i in created_mutants]

        self.assertEqual(set(created_dcs), set(expected_dcs))

        token = created_mutants[0].get_token()
        self.assertEqual(token.get_name(), 'id')
        self.assertEqual(token.get_original_value(), '')

        token = created_mutants[2].get_token()
        self.assertEqual(token.get_name(), 'id')
        self.assertEqual(token.get_original_value(), '')

        for m in created_mutants:
            self.assertIsInstance(m, PostDataMutant)

        for m in created_mutants:
            self.assertEqual(m.get_method(), 'GET')
Example #10
0
    def test_mutant_creation_repeated_parameter_name(self):
        form = Form()
        form.add_input([("name", "id"), ("value", "")])
        form.add_input([("name", "id"), ("value", "")])

        freq = HTTPPostDataRequest(URL('http://w3af.com/?foo=3'),
                                   dc=form,
                                   method='GET')

        created_mutants = PostDataMutant.create_mutants(
            freq, self.payloads, [], False, self.fuzzer_config)

        expected_dc_lst = [
            Form([('id', ['abc', '3419'])]),
            Form([('id', ['def', '3419'])]),
            Form([('id', ['3419', 'abc'])]),
            Form([('id', ['3419', 'def'])])
        ]

        created_dc_lst = [i.get_dc() for i in created_mutants]

        self.assertEqual(created_dc_lst, expected_dc_lst)

        self.assertEqual(created_mutants[0].get_var(), 'id')
        self.assertEqual(created_mutants[0].get_var_index(), 0)
        self.assertEqual(created_mutants[0].get_original_value(), '')
        self.assertEqual(created_mutants[2].get_var(), 'id')
        self.assertEqual(created_mutants[2].get_var_index(), 1)
        self.assertEqual(created_mutants[2].get_original_value(), '')

        for m in created_mutants:
            self.assertIsInstance(m, PostDataMutant)

        for m in created_mutants:
            self.assertEqual(m.get_method(), 'GET')
Example #11
0
    def create_vuln(self):
        v = super(FileUploadTemplate, self).create_vuln()

        form_params = FormParameters()
        for file_var in self.file_vars:
            form_params.add_file_input([("name", file_var), ("type", "file")])

        for token in self.data.iter_tokens():
            if token.get_name() in self.file_vars:
                continue

            form_params.add_input([("name", token.get_name()),
                                   ("type", "text"),
                                   ("value", token.get_value())])

        mpc = MultipartContainer(form_params)

        freq = FuzzableRequest(self.url, method=self.method, post_data=mpc)

        mutant = PostDataMutant(freq)
        mutant.set_dc(mpc)
        mutant.set_token((self.vulnerable_parameter, 0))

        # User configured settings
        v['file_vars'] = self.file_vars
        v['file_dest'] = self.file_dest
        v.set_mutant(mutant)
        return v
Example #12
0
    def test_mutant_creation(self):
        form_params = FormParameters()
        form_params.add_field_by_attr_items([("name", "username"),
                                             ("value", "")])
        form_params.add_field_by_attr_items([("name", "address"),
                                             ("value", "")])

        form = URLEncodedForm(form_params)
        freq = FuzzableRequest(URL('http://www.w3af.com/?id=3'),
                               post_data=form,
                               method='PUT')

        created_mutants = PostDataMutant.create_mutants(
            freq, self.payloads, [], False, self.fuzzer_config)

        expected_dcs = [
            'username=def&address=Bonsai%20Street%20123',
            'username=abc&address=Bonsai%20Street%20123',
            'username=John8212&address=def', 'username=John8212&address=abc'
        ]

        created_dcs = [str(i.get_dc()) for i in created_mutants]

        self.assertEqual(set(created_dcs), set(expected_dcs))

        token = created_mutants[0].get_token()
        self.assertEqual(token.get_name(), 'username')
        self.assertEqual(token.get_original_value(), '')
        self.assertEqual(token.get_value(), 'abc')

        token = created_mutants[1].get_token()
        self.assertEqual(token.get_name(), 'address')
        self.assertEqual(token.get_original_value(), '')
        self.assertEqual(token.get_value(), 'abc')

        token = created_mutants[2].get_token()
        self.assertEqual(token.get_name(), 'username')
        self.assertEqual(token.get_original_value(), '')
        self.assertEqual(token.get_value(), 'def')

        token = created_mutants[3].get_token()
        self.assertEqual(token.get_name(), 'address')
        self.assertEqual(token.get_original_value(), '')
        self.assertEqual(token.get_value(), 'def')

        for m in created_mutants:
            self.assertIsInstance(m, PostDataMutant)

        for m in created_mutants:
            self.assertEqual(m.get_method(), 'PUT')
Example #13
0
    def test_mutant_creation(self):
        form_params = FormParameters()
        form_params.add_input([("name", "username"), ("value", "")])
        form_params.add_input([("name", "address"), ("value", "")])

        form = URLEncodedForm(form_params)
        freq = FuzzableRequest(URL('http://www.w3af.com/?id=3'), post_data=form,
                               method='PUT')

        created_mutants = PostDataMutant.create_mutants(freq, self.payloads, [],
                                                        False,
                                                        self.fuzzer_config)

        expected_dcs = ['username=def&address=Bonsai%20Street%20123',
                        'username=abc&address=Bonsai%20Street%20123',
                        'username=John8212&address=def',
                        'username=John8212&address=abc']

        created_dcs = [str(i.get_dc()) for i in created_mutants]

        self.assertEqual(set(created_dcs), set(expected_dcs))

        token = created_mutants[0].get_token()
        self.assertEqual(token.get_name(), 'username')
        self.assertEqual(token.get_original_value(), '')
        self.assertEqual(token.get_value(), 'abc')

        token = created_mutants[1].get_token()
        self.assertEqual(token.get_name(), 'address')
        self.assertEqual(token.get_original_value(), '')
        self.assertEqual(token.get_value(), 'abc')

        token = created_mutants[2].get_token()
        self.assertEqual(token.get_name(), 'username')
        self.assertEqual(token.get_original_value(), '')
        self.assertEqual(token.get_value(), 'def')

        token = created_mutants[3].get_token()
        self.assertEqual(token.get_name(), 'address')
        self.assertEqual(token.get_original_value(), '')
        self.assertEqual(token.get_value(), 'def')

        for m in created_mutants:
            self.assertIsInstance(m, PostDataMutant)

        for m in created_mutants:
            self.assertEqual(m.get_method(), 'PUT')
    def test_mutant_creation_file(self):
        form_params = FormParameters()
        form_params.add_field_by_attr_items([("name", "username"), ("value", "default")])
        form_params.add_field_by_attr_items([("name", "file_upload"), ("type", "file")])

        form = MultipartContainer(form_params)
        freq = FuzzableRequest(URL('http://www.w3af.com/upload'),
                               post_data=form, method='POST')

        payloads = [file(__file__)]
        created_mutants = PostDataMutant.create_mutants(freq, payloads,
                                                        ['file_upload', ],
                                                        False,
                                                        self.fuzzer_config)

        self.assertEqual(len(created_mutants), 1, created_mutants)
        
        mutant = created_mutants[0]
        
        self.assertIsInstance(mutant.get_token().get_value(), file)
        self.assertEqual(mutant.get_dc()['username'][0], 'default')
Example #15
0
    def test_mutant_creation_file(self):
        form_params = FormParameters()
        form_params.add_input([("name", "username"), ("value", "default")])
        form_params.add_file_input([("name", "file_upload")])

        form = MultipartContainer(form_params)
        freq = FuzzableRequest(URL('http://www.w3af.com/upload'),
                               post_data=form, method='POST')

        payloads = [file(__file__)]
        created_mutants = PostDataMutant.create_mutants(freq, payloads,
                                                        ['file_upload', ],
                                                        False,
                                                        self.fuzzer_config)

        self.assertEqual(len(created_mutants), 1, created_mutants)
        
        mutant = created_mutants[0]
        
        self.assertIsInstance(mutant.get_token().get_value(), file)
        self.assertEqual(mutant.get_dc()['username'][0], 'default')
Example #16
0
    def test_mutant_creation_file(self):
        form = Form()
        form.add_input([("name", "username"), ("value", "default")])
        form.add_file_input([("name", "file_upload")])

        freq = HTTPPostDataRequest(URL('http://www.w3af.com/upload'),
                                   dc=form,
                                   method='POST')

        payloads = [
            file(__file__),
        ]
        created_mutants = PostDataMutant.create_mutants(
            freq, payloads, [
                'file_upload',
            ], False, self.fuzzer_config)

        self.assertEqual(len(created_mutants), 1, created_mutants)

        mutant = created_mutants[0]

        self.assertIsInstance(mutant.get_dc()['file_upload'][0], file)
        self.assertEqual(mutant.get_dc()['username'][0], 'default')
Example #17
0
    def test_should_inject_form_hidden(self):
        form_params = FormParameters()
        form_params.add_field_by_attr_items([("name", "username"),
                                             ("type", "text")])
        form_params.add_field_by_attr_items([("name", "csrf_token"),
                                             ("type", "hidden")])

        form = URLEncodedForm(form_params)
        freq = FuzzableRequest(URL('http://www.w3af.com/'),
                               post_data=form,
                               method='PUT')
        m = PostDataMutant(freq)
        m.get_dc().set_token(('username', 0))

        self.assertFalse(self.plugin._should_inject(m, 'python'))

        m.get_dc().set_token(('csrf_token', 0))
        self.assertTrue(self.plugin._should_inject(m, 'python'))
Example #18
0
    def test_mutant_creation_qs_and_postdata(self):
        form_params = FormParameters()
        form_params.add_field_by_attr_items([("name", "username"), ("value", "")])
        form_params.add_field_by_attr_items([("name", "password"), ("value", "")])

        url = URL('http://moth/foo.bar?action=login')

        form = URLEncodedForm(form_params)
        freq = FuzzableRequest(url, post_data=form)

        created_mutants = PostDataMutant.create_mutants(freq, self.payloads, [],
                                                        False,
                                                        self.fuzzer_config)
        created_dcs = [str(i.get_dc()) for i in created_mutants]

        expected_dcs = ['username=abc&password=FrAmE30.',
                        'username=John8212&password=abc',
                        'username=def&password=FrAmE30.',
                        'username=John8212&password=def']

        self.assertEqual(created_dcs, expected_dcs)

        for m in created_mutants:
            self.assertEqual(m.get_uri(), url)
Example #19
0
def form_pointer_factory(freq):

    if isinstance(freq.get_uri().querystring, Form):
        return QSMutant(freq)

    return PostDataMutant(freq)
Example #20
0
 def __init__(self, freq):
     PostDataMutant.__init__(self, freq)
Example #21
0
 def __init__(self, freq):
     PostDataMutant.__init__(self, freq)
Example #22
0
    def test_mutant_creation_post_data(self):
        form_params = FormParameters()
        form_params.add_field_by_attr_items([("name", "username"), ("value", "")])
        form_params.add_field_by_attr_items([("name", "address"), ("value", "")])
        form_params.add_field_by_attr_items([("name", "image"), ("type", "file")])

        form = MultipartContainer(form_params)
        freq = FuzzableRequest(self.url, post_data=form)

        ph = 'w3af.core.data.constants.file_templates.file_templates.rand_alpha'

        with patch(ph) as mock_rand_alpha:
            mock_rand_alpha.return_value = 'upload'
            generated_mutants = PostDataMutant.create_mutants(freq,
                                                              self.payloads, [],
                                                              False,
                                                              self.fuzzer_config)

        self.assertEqual(len(generated_mutants), 6, generated_mutants)

        _, gif_file_content, _ = get_file_from_template('gif')
        gif_named_stringio = NamedStringIO(gif_file_content, 'upload.gif')

        expected_forms = []

        form = MultipartContainer(copy.deepcopy(form_params))
        form['image'] = [gif_named_stringio]
        form['username'] = ['def']
        form['address'] = ['Bonsai Street 123']
        expected_forms.append(form)

        form = MultipartContainer(copy.deepcopy(form_params))
        form['image'] = [gif_named_stringio]
        form['username'] = ['abc']
        form['address'] = ['Bonsai Street 123']
        expected_forms.append(form)

        # TODO: Please note that these two multipart forms are a bug, since
        #       they should never be created by PostDataMutant.create_mutants
        #       (they are not setting the image as a file, just as a string)
        form = MultipartContainer(copy.deepcopy(form_params))
        form['image'] = ['def']
        form['username'] = ['John8212']
        form['address'] = ['Bonsai Street 123']
        expected_forms.append(form)

        form = MultipartContainer(copy.deepcopy(form_params))
        form['image'] = ['abc']
        form['username'] = ['John8212']
        form['address'] = ['Bonsai Street 123']
        expected_forms.append(form)
        #
        # TODO: /end
        #

        form = MultipartContainer(copy.deepcopy(form_params))
        form['image'] = [gif_named_stringio]
        form['username'] = ['John8212']
        form['address'] = ['abc']
        expected_forms.append(form)

        form = MultipartContainer(copy.deepcopy(form_params))
        form['image'] = [gif_named_stringio]
        form['username'] = ['John8212']
        form['address'] = ['def']
        expected_forms.append(form)

        boundary = get_boundary()
        noop = '1' * len(boundary)

        expected_data = [encode_as_multipart(f, boundary) for f in expected_forms]
        expected_data = set([s.replace(boundary, noop) for s in expected_data])

        generated_forms = [m.get_dc() for m in generated_mutants]
        generated_data = [str(f).replace(f.boundary, noop) for f in generated_forms]

        self.assertEqual(expected_data, set(generated_data))

        str_file = generated_forms[0]['image'][0]
        self.assertIsInstance(str_file, NamedStringIO)
        self.assertEqual(str_file.name[-4:], '.gif')
        self.assertEqual(gif_file_content, str_file)

        str_file = generated_forms[1]['image'][0]
        self.assertIsInstance(str_file, NamedStringIO)
        self.assertEqual(str_file.name[-4:], '.gif')
        self.assertEqual(gif_file_content, str_file)

        self.assertIn('name="image"; filename="upload.gif"', generated_data[0])
Example #23
0
    def test_mutant_creation_post_data(self):
        form_params = FormParameters()
        form_params.add_field_by_attr_items([("name", "username"), ("value", "")])
        form_params.add_field_by_attr_items([("name", "address"), ("value", "")])
        form_params.add_field_by_attr_items([("name", "image"), ("type", "file")])

        form = MultipartContainer(form_params)
        freq = FuzzableRequest(self.url, post_data=form)

        ph = 'w3af.core.data.constants.file_templates.file_templates.rand_alpha'

        with patch(ph) as mock_rand_alpha:
            mock_rand_alpha.return_value = 'upload'
            generated_mutants = PostDataMutant.create_mutants(freq,
                                                              self.payloads, [],
                                                              False,
                                                              self.fuzzer_config)

        self.assertEqual(len(generated_mutants), 6, generated_mutants)

        _, gif_file_content, _ = get_file_from_template('gif')
        gif_named_stringio = NamedStringIO(gif_file_content, 'upload.gif')

        expected_forms = []

        form = MultipartContainer(copy.deepcopy(form_params))
        form['image'] = [gif_named_stringio]
        form['username'] = ['def']
        form['address'] = ['Bonsai Street 123']
        expected_forms.append(form)

        form = MultipartContainer(copy.deepcopy(form_params))
        form['image'] = [gif_named_stringio]
        form['username'] = ['abc']
        form['address'] = ['Bonsai Street 123']
        expected_forms.append(form)

        # TODO: Please note that these two multipart forms are a bug, since
        #       they should never be created by PostDataMutant.create_mutants
        #       (they are not setting the image as a file, just as a string)
        form = MultipartContainer(copy.deepcopy(form_params))
        form['image'] = ['def']
        form['username'] = ['John8212']
        form['address'] = ['Bonsai Street 123']
        expected_forms.append(form)

        form = MultipartContainer(copy.deepcopy(form_params))
        form['image'] = ['abc']
        form['username'] = ['John8212']
        form['address'] = ['Bonsai Street 123']
        expected_forms.append(form)
        #
        # TODO: /end
        #

        form = MultipartContainer(copy.deepcopy(form_params))
        form['image'] = [gif_named_stringio]
        form['username'] = ['John8212']
        form['address'] = ['abc']
        expected_forms.append(form)

        form = MultipartContainer(copy.deepcopy(form_params))
        form['image'] = [gif_named_stringio]
        form['username'] = ['John8212']
        form['address'] = ['def']
        expected_forms.append(form)

        boundary = get_boundary()
        noop = '1' * len(boundary)

        expected_data = [encode_as_multipart(f, boundary) for f in expected_forms]
        expected_data = set([s.replace(boundary, noop) for s in expected_data])

        generated_forms = [m.get_dc() for m in generated_mutants]
        generated_data = [str(f).replace(f.boundary, noop) for f in generated_forms]

        self.assertEqual(expected_data, set(generated_data))

        str_file = generated_forms[0]['image'][0]
        self.assertIsInstance(str_file, NamedStringIO)
        self.assertEqual(str_file.name[-4:], '.gif')
        self.assertEqual(gif_file_content, str_file)

        str_file = generated_forms[1]['image'][0]
        self.assertIsInstance(str_file, NamedStringIO)
        self.assertEqual(str_file.name[-4:], '.gif')
        self.assertEqual(gif_file_content, str_file)

        self.assertIn('name="image"; filename="upload.gif"', generated_data[0])