I have an API that accepts base64 encoded image data, and will need to decode the data, save the image file, then create a thumbnail from that image.
I am concerned that malicious code could get executed if I do not properly validate the contents of the POST payload before attempting to create a thumbnail.
The basic workflow I have thus far is below. Is there enough validation that I do not need to be concerned about security? I guess I am worried about someone encoding something bad, then when one of the image functions below is called, the internet explodes.
<?php
$decodedImage = base64_decode($_POST["canvas"]);
if ($decodedImage === false) {
// Error out
}
$imageSizeValidation = getimagesizefromstring($decodedImage);
if ($imageSizeValidation[0] < 1 || $imageSizeValidation[1] < 1 || !$imageSizeValidation['mime']) {
// Error out
}
$tempFilePath = "/tmp/" . microtime(true) . "-canvas-web.jpg";
file_put_contents($tempFilePath, $decodedImage);
$originalWidth = $imageSizeValidation[0];
$originalHeight = $imageSizeValidation[1];
$newWidth = 49;
$newHeight = 49;
$scaleWidth = $newWidth / $originalWidth;
$scaleHeight = $newHeight / $originalHeight;
$scale = min($scaleWidth, $scaleHeight);
$width = (int)($originalWidth * $scale);
$height = (int)($originalHeight * $scale);
$xpos = (int)(($newWidth - $width) / 2);
$ypos = (int)(($newHeight - $height) / 2);
$oldImage = imagecreatefromjpeg($tempFilePath);
$newImage = imagecreatetruecolor($width, $height);
$background = imagecolorallocate($oldImage, 255, 255, 255);
imagefilledrectangle($newImage, 0, 0, $width, $height, $background);
imagecopyresampled($newImage, $oldImage, $xpos, $ypos, 0, 0, $width, $height, $originalWidth, $originalHeight);
imagedestroy($oldImage);
imagejpeg($newImage, "/path/to/new.jpg", 90);
imagedestroy($newImage);
Base64 is an encoding scheme originally designed to allow binary data to be represented as ASCII text. Widespread in its use, base64 seems to provide a level of security by making sensitive information difficult to decipher.
While base64 is fine for transport, do not store your images base64 encoded. Base64 provides no checksum or anything of any value for storage. Base64 encoding increases the storage requirement by 33% over a raw binary format.
7 Answers. Show activity on this post. Base64 is not encryption -- it's an encoding. It's a way of representing binary data using only printable (text) characters.
base64 data is just text. it can't do anything. and whatever you decode from it can be safe as well, if you use that data properly.
Didn't end up getting any answers, so for those that are interested in what I ultimately did:
After investigating this a bit more, I found that one of my biggest concerns was valid image files encoded with inline PHP, Ruby, etc. EG: An image with the following at the end:
<?php phpinfo();
I ended up taking the decoded image data, and giving it to imagecreatefromstring()
, then saving the image to a temp directory via imagejpeg()
.
This seemed to remove any encoded PHP from the original image data. At that point I validated the image size data of the saved image using getimagesize()
. Assuming that everything was valid at that point, I moved the image to a permanent location.
Another thing I changed, was instead of using a filename based on a static string and microtime()
, I used a hash.
Regarding the concern of images with code injected, I found this link to be helpful: https://www.owasp.org/index.php/Unrestricted_File_Upload
I also found this other SO post useful, as far as overall ideas go: Validating base64 encoded images
Finally, the following book brought the concern of images with code to my attention in the first place: http://www.apress.com/9781430233183
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With