Пример #1
0
    def upload_file(self, _file):
        form_params = FormParameters()
        form_params.add_file_input([('name', 'uploadedfile')])
        form_params.add_input([('name', 'MAX_FILE_SIZE'), ('type', 'hidden'),
                               ('value', '10000')])

        mpc = MultipartContainer(form_params)
        mpc['uploadedfile'][0] = _file

        resp = self.opener.POST(self.MOTH_FILE_UP_URL,
                                data=str(mpc),
                                headers=Headers(mpc.get_headers()))

        self.assertIn('was successfully uploaded', resp.get_body())
Пример #2
0
    def upload_file(self, _file):
        form_params = FormParameters()
        form_params.add_field_by_attr_items([('name', 'uploadedfile')])
        form_params.add_field_by_attr_items([('name', 'MAX_FILE_SIZE'),
                               ('type', 'hidden'),
                               ('value', '10000')])

        mpc = MultipartContainer(form_params)
        mpc['uploadedfile'][0] = _file

        resp = self.opener.POST(self.MOTH_FILE_UP_URL, data=str(mpc),
                                headers=Headers(mpc.get_headers()))

        self.assertIn('was successfully uploaded', resp.get_body())
Пример #3
0
    def test_multipart_without_file(self):
        form_params = FormParameters()
        form_params.add_field_by_attr_items([('name', 'uploadedfile')])
        form_params['uploadedfile'][0] = 'this is not a file'
        form_params.add_field_by_attr_items([('name', 'MAX_FILE_SIZE'),
                                             ('type', 'hidden'),
                                             ('value', '10000')])

        mpc = MultipartContainer(form_params)

        resp = self.opener.POST(self.MOTH_FILE_UP_URL,
                                data=str(mpc),
                                headers=Headers(mpc.get_headers()))

        self.assertNotIn('was successfully uploaded', resp.get_body())
Пример #4
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
Пример #5
0
    def test_multipart_3570(self):
        headers = Headers([(u'Content-length', u'557'),
                           (u'Accept-encoding', u'gzip, deflate'),
                           (u'Accept', u'*/*'),
                           (u'User-agent', u'Mozilla/4.0'),
                           (u'Host', u'www.webscantest.com'),
                           (u'Cookie', u'SESSIONID_VULN_SITE=k4no98smgdkun2eqme5k2btgb5'),
                           (u'Referer', u'http://www.webscantest.com/'),
                           (u'Content-type', u'multipart/form-data; boundary=db36a3a8bb45ec40c22301ffcaa98e05')])

        test_dir = os.path.dirname(os.path.realpath(__file__))
        post_data_file = os.path.join(test_dir, 'samples', 'post-data-3570')
        multipart_post_data = file(post_data_file).read()

        self.assertIn('db36a3a8bb45ec40c22301ffcaa98e05', multipart_post_data)
        self.assertEqual(len(multipart_post_data), 557)

        mpc = MultipartContainer.from_postdata(headers, multipart_post_data)

        self.assertIsInstance(mpc, MultipartContainer)
        self.assertIn('MAX_FILE_SIZE', mpc)
        self.assertIn('userfile', mpc)

        self.assertEqual(mpc['MAX_FILE_SIZE'], ['2097152'])
        # We don't store the file content
        self.assertEqual(mpc['userfile'], [''])

        self.assertEqual(mpc.get_file_vars(), ['userfile'])
        self.assertEqual(mpc.get_parameter_type('MAX_FILE_SIZE'), 'text')
        self.assertEqual(mpc.get_parameter_type('userfile'), 'file')
        self.assertEqual(mpc.get_file_name('userfile'), 'aTFiAgn.gif')
Пример #6
0
    def test_store_in_disk_set(self):
        boundary, post_data = multipart_encode([
            ('a', 'bcd'),
        ], [])
        multipart_boundary = MultipartContainer.MULTIPART_HEADER

        headers = Headers([('content-length', str(len(post_data))),
                           ('content-type', multipart_boundary % boundary)])

        dc = MultipartContainer.from_postdata(headers, post_data)

        dc.set_token(('a', 0))

        disk_set = DiskSet()
        disk_set.add(dc)

        dc_read = disk_set[0]

        # These are different objects
        self.assertIsNot(dc_read, dc)

        # But they hold the same data
        self.assertEqual(dc.get_token(), dc_read.get_token())
        self.assertIsNotNone(dc.get_token())
        self.assertIsNotNone(dc_read.get_token())
        self.assertEqual(dc_read.get_token().get_name(), 'a')
    def test_multipart_post(self):
        boundary, post_data = multipart_encode([
            ('a', 'bcd'),
        ], [])
        multipart_boundary = 'multipart/form-data; boundary=%s'

        headers = Headers([('content-length', str(len(post_data))),
                           ('content-type', multipart_boundary % boundary)])

        fr = FuzzableRequest.from_parts(self.url,
                                        headers=headers,
                                        post_data=post_data,
                                        method='POST')

        form_params = FormParameters()
        form_params.add_field_by_attr_items([('name', 'a'), ('type', 'text'),
                                             ('value', 'bcd')])

        expected_container = MultipartContainer(form_params)
        expected_headers = Headers([('content-type',
                                     multipart_boundary % boundary)])

        self.assertEqual(fr.get_url(), self.url)
        self.assertEqual(fr.get_headers(), expected_headers)
        self.assertIn('multipart/form-data', fr.get_headers()['content-type'])
        self.assertEqual(fr.get_method(), 'POST')
        self.assertIsInstance(fr.get_raw_data(), MultipartContainer)
        self.assertEqual(fr.get_raw_data(), expected_container)
Пример #8
0
    def test_multipart_from_form_params(self):
        form_params = FormParameters()

        form_params.add_field_by_attr_items([('name', 'b'), ('type', 'file')])
        form_params.add_field_by_attr_items([('name', 'a'), ('type', 'text'),
                                             ('value', 'bcd')])
        form_params.set_file_name('b', 'hello.txt')

        mpc = MultipartContainer(form_params)

        self.assertIsInstance(mpc, MultipartContainer)
        self.assertEqual(mpc['a'], ['bcd'])
        self.assertEqual(mpc.get_file_vars(), ['b'])
        self.assertEqual(mpc.get_parameter_type('a'), 'text')
        self.assertEqual(mpc.get_parameter_type('b'), 'file')
        self.assertEqual(mpc.get_file_name('b'), 'hello.txt')
Пример #9
0
    def test_multipart_3570(self):
        headers = Headers([
            (u'Content-length', u'557'),
            (u'Accept-encoding', u'gzip, deflate'), (u'Accept', u'*/*'),
            (u'User-agent', u'Mozilla/4.0'), (u'Host', u'www.webscantest.com'),
            (u'Cookie', u'SESSIONID_VULN_SITE=k4no98smgdkun2eqme5k2btgb5'),
            (u'Referer', u'http://www.webscantest.com/'),
            (u'Content-type',
             u'multipart/form-data; boundary=db36a3a8bb45ec40c22301ffcaa98e05')
        ])

        test_dir = os.path.dirname(os.path.realpath(__file__))
        post_data_file = os.path.join(test_dir, 'samples', 'post-data-3570')
        multipart_post_data = file(post_data_file).read()

        self.assertIn('db36a3a8bb45ec40c22301ffcaa98e05', multipart_post_data)
        self.assertEqual(len(multipart_post_data), 557)

        mpc = MultipartContainer.from_postdata(headers, multipart_post_data)

        self.assertIsInstance(mpc, MultipartContainer)
        self.assertIn('MAX_FILE_SIZE', mpc)
        self.assertIn('userfile', mpc)

        self.assertEqual(mpc['MAX_FILE_SIZE'], ['2097152'])
        self.assertTrue(mpc['userfile'][0].startswith('GIF89'))

        self.assertEqual(mpc.get_file_vars(), ['userfile'])
        self.assertEqual(mpc.get_parameter_type('MAX_FILE_SIZE'), 'text')
        self.assertEqual(mpc.get_parameter_type('userfile'), 'file')
        self.assertEqual(mpc.get_file_name('userfile'), 'aTFiAgn.gif')
Пример #10
0
    def test_multipart_from_form_params(self):
        form_params = FormParameters()

        form_params.set_file_name('b', 'hello.txt')
        form_params.add_file_input([('name', 'b')])
        form_params.add_input([('name', 'a'),
                               ('type', 'text'),
                               ('value', 'bcd')])

        mpc = MultipartContainer(form_params)

        self.assertIsInstance(mpc, MultipartContainer)
        self.assertEqual(mpc['a'], ['bcd'])
        self.assertEqual(mpc.get_file_vars(), ['b'])
        self.assertEqual(mpc.get_parameter_type('a'), 'text')
        self.assertEqual(mpc.get_parameter_type('b'), 'file')
        self.assertEqual(mpc.get_file_name('b'), 'hello.txt')
Пример #11
0
def dc_from_form_params(form_parameters):
    """
    :param form_parameters: The form parameters is the result of parsing HTML,
                            and contains information such as the parameter names
                            and types.

    :return: An instance of URLEncodedForm or MultipartContainer
    """
    if form_parameters.get_file_vars():
        # If it has files, I don't care if the form encoding wasn't specified
        # we must send it as multipart.
        return MultipartContainer(form_parameters)

    if 'multipart' in form_parameters.get_form_encoding().lower():
        # If there are no files but the web developer specified the multipart
        # form encoding, then we'll use multipart also
        return MultipartContainer(form_parameters)

    return URLEncodedForm(form_parameters)
Пример #12
0
    def upload_file(self, _file):
        form_params = FormParameters()
        form_params.add_file_input([("name", "uploadedfile")])
        form_params.add_input([("name", "MAX_FILE_SIZE"), ("type", "hidden"), ("value", "10000")])

        mpc = MultipartContainer(form_params)
        mpc["uploadedfile"][0] = _file

        resp = self.opener.POST(self.MOTH_FILE_UP_URL, data=str(mpc), headers=Headers(mpc.get_headers()))

        self.assertIn("was successfully uploaded", resp.get_body())
Пример #13
0
    def test_multipart_post_empty_value(self):
        boundary, post_data = multipart_encode([('a', ''), ], [])
        multipart_boundary = MultipartContainer.MULTIPART_HEADER

        headers = Headers([('content-length', str(len(post_data))),
                           ('content-type', multipart_boundary % boundary)])

        mpc = MultipartContainer.from_postdata(headers, post_data)

        self.assertIsInstance(mpc, MultipartContainer)
        self.assertIn('a', mpc)
        self.assertEqual(mpc['a'], [''])
        self.assertEqual(mpc.get_file_vars(), [])
        self.assertEqual(mpc.get_parameter_type('a'), 'text')
Пример #14
0
    def test_multipart_post_empty_value(self):
        boundary, post_data = multipart_encode([('a', ''), ], [])
        multipart_boundary = MultipartContainer.MULTIPART_HEADER

        headers = Headers([('content-length', str(len(post_data))),
                           ('content-type', multipart_boundary % boundary)])

        mpc = MultipartContainer.from_postdata(headers, post_data)

        self.assertIsInstance(mpc, MultipartContainer)
        self.assertIn('a', mpc)
        self.assertEqual(mpc['a'], [''])
        self.assertEqual(mpc.get_file_vars(), [])
        self.assertEqual(mpc.get_parameter_type('a'), 'text')
Пример #15
0
    def test_copy_with_token(self):
        boundary, post_data = multipart_encode([('a', 'bcd'), ], [])
        multipart_boundary = MultipartContainer.MULTIPART_HEADER

        headers = Headers([('content-length', str(len(post_data))),
                           ('content-type', multipart_boundary % boundary)])

        dc = MultipartContainer.from_postdata(headers, post_data)

        dc.set_token(('a', 0))
        dc_copy = copy.deepcopy(dc)

        self.assertEqual(dc.get_token(), dc_copy.get_token())
        self.assertIsNotNone(dc.get_token())
        self.assertIsNotNone(dc_copy.get_token())
        self.assertEqual(dc_copy.get_token().get_name(), 'a')
Пример #16
0
    def test_copy_with_token(self):
        boundary, post_data = multipart_encode([('a', 'bcd'), ], [])
        multipart_boundary = MultipartContainer.MULTIPART_HEADER

        headers = Headers([('content-length', str(len(post_data))),
                           ('content-type', multipart_boundary % boundary)])

        dc = MultipartContainer.from_postdata(headers, post_data)

        dc.set_token(('a', 0))
        dc_copy = copy.deepcopy(dc)

        self.assertEqual(dc.get_token(), dc_copy.get_token())
        self.assertIsNotNone(dc.get_token())
        self.assertIsNotNone(dc_copy.get_token())
        self.assertEqual(dc_copy.get_token().get_name(), 'a')
Пример #17
0
    def test_upload_file_using_fuzzable_request(self):
        form_params = FormParameters()
        form_params.add_file_input([('name', 'uploadedfile')])
        form_params['uploadedfile'][0] = NamedStringIO('file content',
                                                       name='test.txt')
        form_params.add_input([('name', 'MAX_FILE_SIZE'), ('type', 'hidden'),
                               ('value', '10000')])

        mpc = MultipartContainer(form_params)

        freq = FuzzableRequest(self.MOTH_FILE_UP_URL,
                               post_data=mpc,
                               method='POST')

        resp = self.opener.send_mutant(freq)

        self.assertIn('was successfully uploaded', resp.get_body())
Пример #18
0
    def test_multipart_post_with_filename(self):
        fake_file = NamedStringIO('def', name='hello.txt')
        vars = [('a', 'bcd'), ]
        files = [('b', fake_file)]
        boundary, post_data = multipart_encode(vars, files)
        multipart_boundary = MultipartContainer.MULTIPART_HEADER

        headers = Headers([('content-length', str(len(post_data))),
                           ('content-type', multipart_boundary % boundary)])

        mpc = MultipartContainer.from_postdata(headers, post_data)

        self.assertIsInstance(mpc, MultipartContainer)
        self.assertIn('a', mpc)
        self.assertEqual(mpc['a'], ['bcd'])
        self.assertEqual(mpc.get_file_vars(), ['b'])
        self.assertEqual(mpc.get_parameter_type('a'), 'text')
        self.assertEqual(mpc.get_parameter_type('b'), 'file')
        self.assertEqual(mpc.get_file_name('b'), 'hello.txt')
Пример #19
0
    def test_multipart_post_with_filename(self):
        fake_file = NamedStringIO('def', name='hello.txt')
        vars = [('a', 'bcd'), ]
        files = [('b', fake_file)]
        boundary, post_data = multipart_encode(vars, files)
        multipart_boundary = MultipartContainer.MULTIPART_HEADER

        headers = Headers([('content-length', str(len(post_data))),
                           ('content-type', multipart_boundary % boundary)])

        mpc = MultipartContainer.from_postdata(headers, post_data)

        self.assertIsInstance(mpc, MultipartContainer)
        self.assertIn('a', mpc)
        self.assertEqual(mpc['a'], ['bcd'])
        self.assertEqual(mpc.get_file_vars(), ['b'])
        self.assertEqual(mpc.get_parameter_type('a'), 'text')
        self.assertEqual(mpc.get_parameter_type('b'), 'file')
        self.assertEqual(mpc.get_file_name('b'), 'hello.txt')
Пример #20
0
    def test_multipart_test_from_string(self):
        multipart_boundary = MultipartContainer.MULTIPART_HEADER
        boundary = '4266ff2e00ac63588a571483e5727142'

        headers = Headers([('content-length', str(len(MULTIPART_TEST))),
                           ('content-type', multipart_boundary % boundary)])

        mpc = MultipartContainer.from_postdata(headers, MULTIPART_TEST)

        self.assertIsInstance(mpc, MultipartContainer)
        self.assertIn('MAX_FILE_SIZE', mpc)
        self.assertIn('file', mpc)

        self.assertEqual(mpc['MAX_FILE_SIZE'], ['2097152'])
        self.assertTrue(mpc['file'][0].startswith('GIF89'))

        self.assertEqual(mpc.get_file_vars(), ['file'])
        self.assertEqual(mpc.get_parameter_type('MAX_FILE_SIZE'), 'text')
        self.assertEqual(mpc.get_parameter_type('file'), 'file')
        self.assertEqual(mpc.get_file_name('file'), 'rsXiwMY.gif')
Пример #21
0
    def test_multipart_test_from_string(self):
        multipart_boundary = MultipartContainer.MULTIPART_HEADER
        boundary = '4266ff2e00ac63588a571483e5727142'

        headers = Headers([('content-length', str(len(MULTIPART_TEST))),
                           ('content-type', multipart_boundary % boundary)])

        mpc = MultipartContainer.from_postdata(headers, MULTIPART_TEST)

        self.assertIsInstance(mpc, MultipartContainer)
        self.assertIn('MAX_FILE_SIZE', mpc)
        self.assertIn('file', mpc)

        self.assertEqual(mpc['MAX_FILE_SIZE'], ['2097152'])
        self.assertTrue(mpc['file'][0].startswith('GIF89'))

        self.assertEqual(mpc.get_file_vars(), ['file'])
        self.assertEqual(mpc.get_parameter_type('MAX_FILE_SIZE'), 'text')
        self.assertEqual(mpc.get_parameter_type('file'), 'file')
        self.assertEqual(mpc.get_file_name('file'), 'rsXiwMY.gif')
Пример #22
0
    def test_multipart_fuzzable_request_store(self):
        boundary, post_data = multipart_encode([('a', 'bcd'), ], [])
        multipart_boundary = MultipartContainer.MULTIPART_HEADER

        headers = Headers([('content-length', str(len(post_data))),
                           ('content-type', multipart_boundary % boundary)])

        dc = MultipartContainer.from_postdata(headers, post_data)
        post_data = str(dc)

        fr = FuzzableRequest.from_parts(URL('http://www.w3af.com/'),
                                        method='POST', post_data=post_data,
                                        headers=headers)
        
        disk_set = DiskSet()
        disk_set.add(fr)

        fr_read = disk_set[0]

        self.assertIsInstance(fr_read.get_raw_data(), MultipartContainer)
        self.assertIn('a', fr_read.get_raw_data())
Пример #23
0
    def test_multipart_fuzzable_request_store(self):
        boundary, post_data = multipart_encode([('a', 'bcd'), ], [])
        multipart_boundary = MultipartContainer.MULTIPART_HEADER

        headers = Headers([('content-length', str(len(post_data))),
                           ('content-type', multipart_boundary % boundary)])

        dc = MultipartContainer.from_postdata(headers, post_data)
        post_data = str(dc)

        fr = FuzzableRequest.from_parts(URL('http://www.w3af.com/'),
                                        method='POST', post_data=post_data,
                                        headers=headers)
        
        disk_set = DiskSet()
        disk_set.add(fr)

        fr_read = disk_set[0]

        self.assertIsInstance(fr_read.get_raw_data(), MultipartContainer)
        self.assertIn('a', fr_read.get_raw_data())
Пример #24
0
    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')
Пример #25
0
    def test_store_in_disk_set(self):
        boundary, post_data = multipart_encode([('a', 'bcd'), ], [])
        multipart_boundary = MultipartContainer.MULTIPART_HEADER

        headers = Headers([('content-length', str(len(post_data))),
                           ('content-type', multipart_boundary % boundary)])

        dc = MultipartContainer.from_postdata(headers, post_data)

        dc.set_token(('a', 0))

        disk_set = DiskSet()
        disk_set.add(dc)

        dc_read = disk_set[0]

        # These are different objects
        self.assertIsNot(dc_read, dc)

        # But they hold the same data
        self.assertEqual(dc.get_token(), dc_read.get_token())
        self.assertIsNotNone(dc.get_token())
        self.assertIsNotNone(dc_read.get_token())
        self.assertEqual(dc_read.get_token().get_name(), 'a')
Пример #26
0
    def test_generate_all(self):
        fuzzer_config = {
            'fuzz_form_files': True,
            'fuzzed_files_extension': 'gif'
        }

        form_params = FormParameters()
        form_params.set_method('POST')
        form_params.set_action(self.url)
        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.from_form(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 = FileContentMutant.create_mutants(
                freq, self.payloads, [], False, fuzzer_config)

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

        _, file_payload_abc, _ = get_template_with_payload('gif', 'abc')
        _, file_payload_def, _ = get_template_with_payload('gif', 'def')

        file_abc = NamedStringIO(file_payload_abc, 'upload.gif')
        file_def = NamedStringIO(file_payload_def, 'upload.gif')

        form_1 = MultipartContainer(copy.deepcopy(form_params))
        form_2 = MultipartContainer(copy.deepcopy(form_params))

        form_1['image'] = [file_abc]
        form_1['username'] = ['John8212']
        form_1['address'] = ['Bonsai Street 123']

        form_2['image'] = [file_def]
        form_2['username'] = ['John8212']
        form_2['address'] = ['Bonsai Street 123']

        expected_forms = [form_1, form_2]

        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].get_value()
        self.assertIsInstance(str_file, NamedStringIO)
        self.assertEqual(str_file.name[-4:], '.gif')
        self.assertEqual(file_payload_abc, str_file)

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

        self.assertIn('name="image"; filename="upload.gif"', generated_data[0])
Пример #27
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])