I want to use ffmpeg to recreate an image file that is uploaded. I know that in PHP you can use imagecreatefromjpeg, imagecreatefrompng and imagejpeg etc. to recreate images. That way, if there is any hidden malware in the original images, it will 'break' / be mangled.
But I want to use this ffmpeg command to recreate image files:
ffmpeg -i in.jpg out.jpg
I have tested converting an image file that has PHP code stored in its EXIF field, and after converting it, the PHP code is no longer executed in the converted file..
Also, the converted file is smaller in size: from 45.9 KB to 11 KB..
Is that a safe way?
EDIT
Btw, I am also checking the MIME type etc, but MIME can be forged, hence recreating image files is recommended.. I want to convert files on another server where there is no PHP installed. That way I can also avoid any potential PHP memory issues.
Related
Using a simple firefox addon, a hacker can change the mime type of any file they want to upload, bypassing your file type checker.
Hackers can then use a program like GIMP to embed a php script inside the binary data of an image, audio or any other file.
How can I check for this, and prevent it?
You can use mime_content_type() to get the actual mime type of the file instead of the value transmitted by the client browser.
Then you can use a library such as php-ClamAV that allows to perform virus-scans in PHP.
You can discard any file extension except those you expect (eg .png, .jpg, etc if you're expecting images).
In the specific case of images, you could also neutralize images by modifying them (eg slightly resize them, modify the compression rate, something that would modify the data and neutralize any executable).
Finally of course, take of not giving the execution right to the file. But contrary to what is said in the comments, this will not really protect you. If the hacker finds a way to run php file though an injection for instance, he'll be able to chmod the file and get the execution right (and even run it).
A good practice is also to always rename the file in an unpredictable way. If it is not meant to be accessed by clients after upload, send the files in a folder where directory browsing is disabled.
Is it "good" to change an image file extension?
For instance, I have a jpg file inputed, and I change it to a png. Is this OK or should I leave it as a jpg?
I use the rename() to change the name and the file extension.
It is related to PHP, because I do my renaming with PHP with a upload script.
Another question is: Is it safe to do it e.g can the files become corrupt?
Changing an image file extension from .jpg to .png does not change it to a PNG file. It just changes the name of the file. This does not change the contents of the file at all, so it does not become corrupt. It only changes the name of it.
Leave file names with the appropriate extension, or you will confuse everyone, including yourself.
No, the file cannot become corrupt... a file name is just the name.
Never allow users to dictate the names of files on your system. No matter what they upload, rename it to something with no extension, and store the files outside of the web server's doc root. You don't want them uploading .php scripts and what not.
Changing the extension of file is just renaming it. The extension serves the purpose of merely defining the data type that the file contains.
Renaming a JPEG file into a PNG is therefore a very bad idea. Although some image viewers may still be able to figure out that your PNG is actually JPEG and view it correctly, others will not.
Use ImageMagick or GD 2 to do any image conversions in PHP.
I am wandering if anybody has a reliable way of determine whether a PDF document is actually a PDF document, and that it isn't corrupted.
I generate reports on my system and I want to be certain that the data returned by another system contains an openable PDF document (and that the data is not corrupt).
At the moment, I am basically looking at string length (the PDF gets stored into a variable, not a physical file).
Any recommendations to do this in PHP would be great.
If you just want to make sure the file is a PDF file, without checking that it is a completely intact pdf file with no issues, you can read the first 5 bytes of the file and for a PDF file they will be exactly equal to the string "%PDF-"
This is how the file program in linux identifies PDF files.
But if you want to make absolutely sure there are no errors anywhere in the file, you can run a program that processes the entire file, and see if that program returns success.
In linux you can use ghostscript ("gs") to render the PDF document to any format.
Or you can install acrobat reader, and run acroread as a command line program to convert it to postscript:
acroread -print -toPostScript [your_file.pdf]
To do either of these you will need to use the system PHP function. To check of the program ran successfully, you need to pass a variable in the second parameter to system that will receive the return status.
You can use pdfinfo, centos installation command:
yum install poppler-utils
... and use pdfinfo command. The PHP code is as follows:
if(!exec("pdfinfo test.pdf")){
echo "file is corrupted"
}
I'm using gzip with PHP to zip up some log files. My development machine is windows, and as you all know, a windows the path are sometimes separated by a space which makes it difficult because I have to wrap everything in quotes to get to the logs.
I'd like to keep my code as clean as I can and was wondering if there is a compression utility that will take the same file to be compressed and zip that file instead of creating a new, compressed file. This way, I wouldn't have to run a separate command to delete the uncompressed file afterwards.
Just for clarification, I'm not using shell_exec to zip these, but instead, PHPs internal functions. "gzwrite" etc.
If the log files are not larger than the allocated php memory you could read in the whole log file then use gzcompress/gzencode to compress the file in memory then write the data back out to the file. You might then need to rename the file to append .gz to the end. Hopefully this helps.
If windows, why not create a little utility that does that for you? It could just be two lines ... perform the gzip then rename the file to the original.
BTW - doesn't gzip by default delete the original after creating original_file.gz?
zip that file 99,99999% of the time means just this:
read data from that file, compress it and write to that file.zip
remove that file.
That's what winzip does. That's what gzip does. Why would you want different? to save one line of code?
I hope you realize, that overwriting any bit of the file before the compression finished with success, is plain wrong.
I'm using PHPs imagecreatefromjpeg to load a jpeg from disk and imagejpeg to output that image to the browser. For some reason though, this function is only outputting the image when the server is running on a Windows development box. On our Linux server, its not outputting any data (ie. Content-Length: 0, nothing is displayed).
Are there any workarounds that make this work on a Linux box? I've confirmed that the GD library is installed with jpeg support.
There are two notes on http://php.net/imagejpeg which may be relevant:
Notes
Note: JPEG support is only available
if PHP was compiled against GD-1.8 or
later.
Note: If you want to output
Progressive JPEGs, you need to set
interlacing on with imageinterlace().
Also some actual code would be useful in attempting to help.
Make sure you have the correct file permissions set. Does your web service own the file? Does it have permission to read or write the file?