php - imagen - Validando imágenes codificadas en base64
file_get_contents base64 php (6)
Como no tengo suficientes puntos para comentar, estoy publicando una versión actualizada del código de thewebguy. Esto es para personas que alojan en servicios como Heroku donde no puedes almacenar imágenes.
El crédito por señalar la envoltura de la transmisión a Pekka ( respuesta de Pekka )
Este código asume que implementa la clase y la envoltura de flujo desde: Ejemplo de PHP en la envoltura de flujo
<?
$base64 = "[insert base64 code here]";
if (check_base64_image($base64)) {
print ''Image!'';
} else {
print ''Not an image!'';
}
function check_base64_image($base64) {
$img = imagecreatefromstring(base64_decode($base64));
if (!$img) {
return false;
}
ob_start();
if(!imagepng($img)) {
return false;
}
$imageTemp = ob_get_contents();
ob_end_clean();
// Set a temporary global variable so it can be used as placeholder
global $myImage; $myImage = "";
$fp = fopen("var://myImage", "w");
fwrite($fp, $imageTemp);
fclose($fp);
$info = getimagesize("var://myImage");
unset($myvar);
unset($imageTemp);
if ($info[0] > 0 && $info[1] > 0 && $info[''mime'']) {
return true;
}
return false;
}
?>
Espero que esto ayude a alguien.
Estoy creando una aplicación que permite al usuario POSTAR datos de lienzo HTML5 que luego se codifican en base64 y se muestran a todos los usuarios. Estoy considerando analizar los datos en un archivo .png real y almacenarlo en el servidor, pero la ruta base64 me permite almacenar las imágenes en una base de datos y minimizar las solicitudes. Las imágenes son únicas, pocas, y la página no se actualizará a menudo.
Un poco de jQuery tomará los datos del lienzo, data:image/png;base64,iVBORw...
y los pasará a un script PHP que lo envuelve así: <img src="$data"></img>
Sin embargo, la seguridad es la piedra angular y es necesario validar los datos del lienzo de base64 para evitar la transmisión de datos maliciosos en la solicitud POST
. Mi principal preocupación es evitar que las URL externas se inyecten en la etiqueta <img>
y se soliciten en la carga de la página.
Actualmente tengo una configuración como esta:
$data = (isset($_POST[''canvas'']) && is_string($_POST[''canvas''])) ? $_POST[''canvas''] : null;
$base = str_replace(''data:image/png;base64,'', '''', $data);
$regx = ''~^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$~''
if ((substr($data, 0, 22)) !== ''data:image/png;base64,'')
{
// Obviously fake, doesn''t contain the expected first 22 characters.
return false;
}
if ((base64_encode(base64_decode($base64, true))) !== $base64)
{
// Decoding and re-encoding the data fails, something is wrong
return false;
}
if ((preg_match($regx, $base64)) !== 1)
{
// The data doesn''t match the regular expression, discard
return false;
}
return true;
Quiero asegurarme de que mi configuración actual sea lo suficientemente segura para evitar que se inserten direcciones URL externas en la etiqueta <img>
y, de no ser así, ¿qué se puede hacer para validar más los datos de la imagen?
Si estás usando php 5.4+, he revisado lo anterior para que sea un poco más conciso.
function check_base64_image($data, $valid_mime) {
$img = imagecreatefromstring($data);
if (!$img) {
return false;
}
$size = getimagesizefromstring($data);
if (!$size || $size[0] == 0 || $size[1] == 0 || !$size[''mime'']) {
return false;
}
return true;
}
Una forma de hacerlo sería crear un archivo de imagen a partir de los datos de base64 y luego verificar la imagen con PHP. Puede haber una forma más sencilla de hacer esto, pero esta manera debería funcionar.
Tenga en cuenta que esto solo funciona para PNG, tendrá que agregar un poco de lógica si está planeando permitir más tipos de archivos (GIF, JPG).
<?
$base64 = "[insert base64 code here]";
if (check_base64_image($base64)) {
print ''Image!'';
} else {
print ''Not an image!'';
}
function check_base64_image($base64) {
$img = imagecreatefromstring(base64_decode($base64));
if (!$img) {
return false;
}
imagepng($img, ''tmp.png'');
$info = getimagesize(''tmp.png'');
unlink(''tmp.png'');
if ($info[0] > 0 && $info[1] > 0 && $info[''mime'']) {
return true;
}
return false;
}
?>
hola chicos, pueden validar el código de imagen codificado en base64 usando la función getimagesize (), solo use el siguiente código:
<?php
$array=getimagesize("data:image/gif; base64 , ''.base64_encode(''any file'').''");
$e=explode("/",$array[''mime'']);
if($e[0]=="image")
{
echo "file is image file" ;
}
?>
* reemplaza cualquier archivo con cualquier fuente de archivo que desees con código de código de base64
function RetrieveExtension($data){
$imageContents = base64_decode($data);
// If its not base64 end processing and return false
if ($imageContents === false) {
return false;
}
$validExtensions = [''png'', ''jpeg'', ''jpg'', ''gif''];
$tempFile = tmpfile();
fwrite($tempFile, $imageContents);
$contentType = finfo_file(finfo_open(FILEINFO_MIME_TYPE), $tempFile);
fclose($tempFile);
if (substr($contentType, 0, 5) !== ''image'') {
return false;
}
$extension = ltrim($contentType, ''image/'');
if (!in_array(strtolower($extension), $validExtensions)) {
return false;
}
return $extension;
}
$str = ''your base64 code'' ;
if (base64_encode(base64_decode($str, true)) === $str && imagecreatefromstring(base64_decode($img))) {
echo ''Success! The String entered match base64_decode and is Image'';
}