Creo que lo más importante de esta pregunta es romper el paradigma:
"Las imágenes son inocentes".
Las imágenes no son inocentes y son muy peligrosas, eche un vistazo a este artículo: "Stegosploit oculta el código malicioso en las imágenes, este es el futuro de los ataques en línea ".
La respuesta corta es:
Crear un nuevo archivo de imagen y almacenarlo en un entorno estático, sin permisos de ejecución es una forma segura de mostrar imágenes eternas. Pero me gustaría ir un poco más profundo.
El método descrito anteriormente es usado por Facebook y otros sitios con Twitter y Google plus.
Cuando compartes un enlace de imagen, crean un tipo de "proxy" para proteger tu página de la intervención externa. Tenga en cuenta que el código malicioso puede ser un javascript que envía todos los eventos de pulsación clave a un host para capturar información como los números de su tarjeta de crédito con un código seguro, su contraseña o cualquier otra cosa.
Por ejemplo, Google plus crea un nuevo enlace para acceder a este archivo:
Este método es más caro porque necesita la infraestructura adecuada para almacenar esta imagen.
Los servicios como Imgur pueden proporcionar una API segura para cargar archivos con seguridad a bajo costo. Esta imagen a continuación es la misma imagen utilizada en mi ejemplo (al final de esta respuesta), Imgur crea una nueva imagen eliminando todo el contenido desechable.
Haceunosmesestuveunproblema,tengounsitiowebconunservicioquepermitealaspersonaspublicarsuimagenyponerlasoloparausarsusenlacesexternos.Undía,descubrímuchasimágenesutilizadasparacrearunaespeciedeataquesDDOS,cadavisitanteredirigeelaccesoaundominio,esedominiotienemuchosotros"iframes" que redirigen sus vistas.
Compartiré una parte de este código, si puedes contribuir, hazlo ..
$filename = "http://s13.postimg.org/f7728bnqv/php_logo_virus.jpg"; //Unsafe image in a external hosting(this file executes a php_info();)
/* Remove path information and dots around the filename, to prevent uploading
* into different directories or replacing hidden system files.
* Also remove control characters and spaces (\x00..\x20) around the filename:
*
*/
$safefilename = trim(basename(stripslashes($filename)), ".\x00..\x20");
/Try to get possible reall extention by imagem type
$tempSafeFile = tempnam(sys_get_temp_dir(), "JLC"); //Create a Temp File to store content in a static env.
//Must have PHP GD lib do execute Details: http://php.net/manual/en/book.image.php
switch (exif_imagetype($safefilename)) {
case IMAGETYPE_JPEG:
$safefilecontent = imagejpeg(imagecreatefromjpeg($safefilename), $tempSafeFile, 100); //Get only file content created a new image and storeing it on my tempfile
$extensions = array('jpg', 'jpeg');
$mime = "image/jpeg";
break;
case IMAGETYPE_PNG:
$safefilecontent = imagepng(imagecreatefrompng($safefilename), $tempSafeFile, 100);
$extensions = array('png');
$mime = "image/png";
break;
case IMAGETYPE_GIF:
$safefilecontent = imagegif(imagecreatefromgif($safefilename), $tempSafeFile, 100);
$extensions = array('gif');
$mime = "image/gif";
break;
case IMAGETYPE_BMP:
$safefilecontent = image2wbmp(imagecreatefromwbmp($safefilename), $tempSafeFile, 100);
$extensions = array('bmp');
$mime = "image/x-MS-bmp";
break;
//There is a lot of other image types... I use this 4 just for a example
default :
throw new Exception("May its a unsafe image file!",500,null);
break;
}
// Adjust incorrect image file extensions:
if (!empty($extensions)) {
$parts = explode('.', $safefilename);
$extIndex = count($parts) - 1;
$ext = strtolower(@$parts[$extIndex]);
if (!in_array($ext, $extensions)) {
$parts[$extIndex] = $extensions[0];
$safefilename = implode('.', $parts);
}
}
//Now you can save, move, store this file in a safe place or just display it:
header("Pragma: public");
header("Expires: -1");
header("Cache-Control: public, must-revalidate, post-check=0, pre-check=0");
//header("Content-Disposition: attachment; filename=\"$safefilename\""); //Download instead
header("Content-Type: " . $mime);
echo file_get_contents($tempSafeFile);
exit;
Código completo aquí: enlace
Sabemos que no hay curas milagrosas, pero puede impedir el descubrimiento de la brecha.
Con mi experiencia negativa, pude observar los siguientes puntos positivos para hacer que la imagen externa sea más segura:
- Crea un nuevo archivo de imagen basado anteriormente
- Almacene el archivo en un entorno seguro y estático, separado del entorno de la aplicación.
- Use servicios externos para almacenar una nueva imagen.
- Limitar el tamaño de la imagen. Los códigos grandes inyectados pueden crear un "archivo grande"
- Eliminar los metadatos de la imagen y Usar algún recurso de compresión de imagen
- verifica el tipo mime
- Use un servicio de proxy (aquí 2 buenos proyectos: enlace & enlace )