laminas/laminas-validator

Error ATTACK from FileUploadFile

diegobittencourt opened this issue · 3 comments

Bug Report

My upload file validator is configured as below:

[
    'type'     => FileInput::class,
    'name'     => 'image_2',
    'required' => false,
    'validators' => [
        [
            'name'    => 'FileUploadFile',
        ],
        [
            'name'    => 'FileMimeType',                        
            'options' => [                            
                'mimeType'  => [
                    'image/jpeg', 
                    'image/png'
                ]
            ]
        ],
        [
            'name'    => 'FileIsImage'
        ],                          
        [
            'name'    => 'FileImageSize',                        
            'options' => [                            
                'minWidth'  => 128,
                'minHeight' => 128,
                'maxWidth'  => 4096,
                'maxHeight' => 4096
            ]
        ],                    
    ],
    'filters'  => [                    
        [
            'name' => 'FileRenameUpload',
            'options' => [  
                'target'             => './public/img',
                'useUploadName'      => false,
                'useUploadExtension' => true,
                'overwrite'          => true,
                'randomize'          => true,
            ]
        ]
    ],     
],

Error ATTACK is send from validador FileUploadFile:
ATTACK => "File '%value%' was illegally uploaded. This could be a possible attack"

The error comes from:

if (! is_uploaded_file($content['tmp_name'])) {
    $this->throwError($content, self::ATTACK);
}

The function is_uploaded_file returns false always after call move_upload_file.

The function move_upload_file is call from Filter FileRenameUpload.

I believe the ATTACK error is correct, but if I call FileUploadRename the ATTACK error will be called inconveniently.

This is unexpected behavior in the development of features, or is there a way to disable ATTACK error so that this does not occur.

Once the file is moved, any kind of upload validation will obviously fail.

In practice, the "is uploaded file" validation can only be performed when validating unfiltered input.

@diegobittencourt
Unfortunately, I cannot reproduce the problem.

This is my short test:

include_once __DIR__ . '/vendor/autoload.php';

if (count($_FILES)) {
    $config = [
        [
            'type'       => Laminas\InputFilter\FileInput::class,
            'name'       => 'image',
            'validators' => [
                [
                    'name' => Laminas\Validator\File\UploadFile::class,
                ],
                [
                    'name'    => Laminas\Validator\File\MimeType::class,
                    'options' => [
                        'mimeType' => [
                            'image/jpeg',
                            'image/png',
                        ],
                    ],
                ],
                [
                    'name' => Laminas\Validator\File\IsImage::class,
                ],
                [
                    'name'    => Laminas\Validator\File\ImageSize::class,
                    'options' => [
                        'minWidth'  => 128,
                        'minHeight' => 128,
                        'maxWidth'  => 4096,
                        'maxHeight' => 4096,
                    ],
                ],
            ],
            'filters'    => [
                [
                    'name'    => Laminas\Filter\File\RenameUpload::class,
                    'options' => [
                        'target'               => './docs',
                        'use_upload_name'      => false,
                        'use_upload_extension' => true,
                        'overwrite'            => true,
                        'randomize'            => true,
                    ],
                ],
            ],
        ],
    ];

    $inputFilter = (new Laminas\InputFilter\Factory())
        ->createInputFilter($config)
        ->setData($_FILES);

    var_dump($_FILES);
    var_dump($inputFilter->isValid());
    var_dump($inputFilter->getMessages());

    // Execute rename filter
    $inputFilter->getValues();
}
?>
<form method="post" enctype="multipart/form-data">
    <input type="file" name="image">
    <input type="submit">
</form>

@Ocramius

Once the file is moved, any kind of upload validation will obviously fail.

The input Laminas\InputFilter\FileInput::class of laminas-inputfilter runs the validators before the filters (the opposite behaviour of Laminas\InputFilter\Input::class). So everything works as expected.