Getimagesize () in a stream instead of a string

I am using Valum file uploader to upload images using AJAX. This script sends the file to my server in a way that I don’t quite understand, so it’s best to explain by showing your server side code:

$pathToFile = $path . $filename; //Here I get a file not found error, because the file is not yet at this address getimagesize($pathToFile); $input = fopen('php://input', 'r'); $temp = tmpfile(); $realSize = stream_copy_to_stream($input, $temp); //Here I get a string expected, resource given error getimagesize($input); fclose($input); $target = fopen($pathToFile, 'w'); fseek($temp, 0, SEEK_SET); //Here I get a file not found error, because the image is not at the $target yet getimagesize($pathToFile); stream_copy_to_stream($temp, $target); fclose($target); //Here it works, because the image is at the desired location so I'm able to access it with $pathToFile. However, the (potentially) malicious file is already in my server. getimagesize($pathToFile); 

The problem is that I want to do some file checking here using getimagesize (). getimagesize only supports a string, and I only have available resources that lead to an error: getimagesize expects a string specified by a resource.

It works when I execute getimagesize ($ pathTofile) at the end of the script, but then the image is already loaded and the damage has already been done. Doing this and checking later, and then possibly deleting the te file seems like bad practice to me.

The only thing in $ _REQUEST is the file name that I use for var $ pathToFile. $ _FILES is empty.

How to check files in streams?

EDIT: The solution is to first put the file in a temporary directory and do a check in the temporary file before copying it to the target directory.

 // Store the file in tmp dir, to validate it before storing it in destination dir $input = fopen('php://input', 'r'); $tmpPath = tempnam(sys_get_temp_dir(), 'upl'); // upl is 3-letter prefix for upload $tmpStream = fopen($tmpPath, 'w'); // For writing it to tmp dir stream_copy_to_stream($input, $tmpStream); fclose($input); fclose($tmpStream); // Store the file in destination dir, after validation $pathToFile = $path . $filename; $destination = fopen($pathToFile, 'w'); $tmpStream = fopen($tmpPath, 'r'); // For reading it from tmp dir stream_copy_to_stream($tmpStream, $destination); fclose($destination); fclose($tmpStream); 
+4
source share
2 answers

Instead of tmpfile() you can use tempnam() and sys_get_temp_dir() to create a temporary path.

Then use fopen() to get the handle to it, copy the stream.

Then you have a line and a handle to the operations you need to perform.

 //Copy PHP input stream data into a temporary file $inputStream = fopen('php://input', 'r'); $tempDir = sys_get_temp_dir(); $tempExtension = '.upload'; $tempFile = tempnam($tempDir, $tempExtension); $tempStream = fopen($tempFile, "w"); $realSize = stream_copy_to_stream($inputStream, $tempStream); fclose($tempStream); getimagesize($tempFile); 
+2
source

PHP 5.4 now supports getimagesizefromstring

See docs: http://php.net/manual/pt_BR/function.getimagesizefromstring.php

You can try:

 $input = fopen('php://input', 'r'); $string = stream_get_contents($input); fclose($input); getimagesizefromstring($string); 
+5
source

Source: https://habr.com/ru/post/1382239/


All Articles