Saltar al contenido principal

Tipos MIME

MIME (Multipurpose Internet Mail Extensions) es un estándar que indica la naturaleza y el formato de un documento, archivo o conjunto de datos. Originalmente diseñado para el correo electrónico, ahora se utiliza ampliamente en protocolos web para identificar el tipo de contenido que se está transmitiendo.

Un tipo MIME tiene la siguiente estructura:

tipo/subtipo

Por ejemplo: image/jpeg, application/pdf, text/html

Importancia en la subida de archivos

Cuando un usuario sube un archivo, el navegador envía el tipo MIME del archivo en el campo $_FILES['archivo']['type']. Sin embargo, este valor no es confiable desde el punto de vista de la seguridad, ya que puede ser manipulado fácilmente por un atacante.

Validación correcta del tipo MIME

Para verificar realmente el tipo de archivo, PHP ofrece la función finfo_file():

<?php
// Método NO seguro (puede ser falsificado)
$tipoReportado = $_FILES['archivo']['type'];

// Método SEGURO (analiza el contenido real del archivo)
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$tipoReal = finfo_file($finfo, $_FILES['archivo']['tmp_name']);
finfo_close($finfo);

echo "Tipo reportado: " . $tipoReportado . "\n";
echo "Tipo real: " . $tipoReal . "\n";

// Validar contra una lista blanca
$tiposPermitidos = ['image/jpeg', 'image/png', 'application/pdf'];
if (!in_array($tipoReal, $tiposPermitidos)) {
die("Tipo de archivo no permitido");
}
?>

Tipos MIME más comunes

Imágenes

Tipo MIMEExtensiónDescripción
image/jpeg.jpg, .jpegImagen JPEG
image/png.pngImagen PNG con soporte de transparencia
image/gif.gifImagen GIF, soporta animación
image/webp.webpFormato moderno de imagen optimizado
image/svg+xml.svgGráfico vectorial escalable
image/bmp.bmpImagen bitmap de Windows
image/tiff.tif, .tiffFormato de imagen de alta calidad
image/x-icon.icoIcono (favicon)

Documentos

Tipo MIMEExtensiónDescripción
application/pdf.pdf Documento PDF
application/msword.docDocumento de Word (versión antigua)
application/vnd.openxmlformats-officedocument.wordprocessingml.document.docxDocumento de Word (formato moderno)
application/vnd.ms-excel.xlsHoja de cálculo Excel (versión antigua)
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.xlsxHoja de cálculo Excel (formato moderno)
application/vnd.ms-powerpoint.pptPresentación PowerPoint (versión antigua)
application/vnd.openxmlformats-officedocument.presentationml.presentation.pptxPresentación PowerPoint (formato moderno)
application/vnd.oasis.opendocument.text.odtDocumento de texto OpenDocument
application/vnd.oasis.opendocument.spreadsheet.odsHoja de cálculo OpenDocument
text/plain.txtArchivo de texto plano
text/csv.csv Valores separados por comas
application/rtf.rtfFormato de texto enriquecido

Audio

Tipo MIMEExtensiónDescripción
audio/mpeg.mp3Audio MP3
audio/wav.wavAudio WAV sin comprimir
audio/ogg.oggAudio Ogg Vorbis
audio/webm.webaAudio WebM
audio/aac.aacAdvanced Audio Coding
audio/flac.flacAudio sin pérdida FLAC
audio/midi.mid, .midiAudio MIDI

Vídeo

Tipo MIMEExtensiónDescripción
video/mp4.mp4Vídeo MP4 (H.264)
video/mpeg.mpeg, .mpgVídeo MPEG
video/webm.webmVídeo WebM
video/ogg.ogvVídeo Ogg
video/x-msvideo.aviVídeo AVI
video/quicktime.movVídeo QuickTime
video/x-matroska.mkvVídeo Matroska

Archivos comprimidos

Tipo MIMEExtensiónDescripción
application/zip.zipArchivo ZIP
application/x-rar-compressed.rarArchivo RAR
application/x-7z-compressed.7zArchivo 7-Zip
application/x-tar.tarArchivo TAR
application/gzip.gzArchivo GZIP

Código y texto

Tipo MIMEExtensiónDescripción
text/html.html, .htmDocumento HTML
text/css.cssHoja de estilos CSS
text/javascript.jsCódigo JavaScript
application/json.jsonDatos JSON
application/xml.xmlDocumento XML
text/xml.xmlDocumento XML (alternativo)
application/x-php.phpScript PHP
text/x-python.pyScript Python

Otros formatos comunes

Tipo MIMEExtensiónDescripción
application/octet-stream*Datos binarios genéricos (sin tipo específico)
font/woff.woffFuente web WOFF
font/woff2.woff2Fuente web WOFF2
font/ttf.ttfFuente TrueType
application/x-font-otf.otfFuente OpenType

Ejemplo completo de validación por categoría

<?php
function validarArchivoPorCategoria($archivo, $categoria) {
// Obtener el tipo MIME real
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$tipoMime = finfo_file($finfo, $archivo['tmp_name']);
finfo_close($finfo);

// Definir tipos permitidos por categoría
$categorias = [
'imagen' => [
'image/jpeg',
'image/png',
'image/gif',
'image/webp'
],
'documento' => [
'application/pdf',
'application/msword',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'application/vnd.ms-excel',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'text/plain'
],
'audio' => [
'audio/mpeg',
'audio/wav',
'audio/ogg',
'audio/webm'
],
'video' => [
'video/mp4',
'video/webm',
'video/ogg'
],
'comprimido' => [
'application/zip',
'application/x-rar-compressed',
'application/x-7z-compressed'
]
];

// Verificar si la categoría existe
if (!isset($categorias[$categoria])) {
return [
'valido' => false,
'mensaje' => 'Categoría no reconocida'
];
}

// Validar el tipo MIME
if (in_array($tipoMime, $categorias[$categoria])) {
return [
'valido' => true,
'tipo' => $tipoMime,
'mensaje' => 'Archivo válido'
];
} else {
return [
'valido' => false,
'tipo' => $tipoMime,
'mensaje' => "Tipo de archivo no permitido para la categoría '{$categoria}'"
];
}
}

// Uso
if (isset($_FILES['archivo']) && $_FILES['archivo']['error'] === UPLOAD_ERR_OK) {
$resultado = validarArchivoPorCategoria($_FILES['archivo'], 'imagen');

if ($resultado['valido']) {
echo "Archivo válido: " . $resultado['tipo'];
// Proceder con la subida
} else {
echo "Error: " . $resultado['mensaje'];
if (isset($resultado['tipo'])) {
echo " (Tipo detectado: " . $resultado['tipo'] . ")";
}
}
}
?>

Validación avanzada: combinando MIME y extensión

Para una seguridad óptima, se recomienda validar tanto el tipo MIME como la extensión del archivo:

<?php
function validarArchivoCompleto($archivo) {
// Tipos MIME y extensiones permitidas
$tiposPermitidos = [
'image/jpeg' => ['jpg', 'jpeg'],
'image/png' => ['png'],
'image/gif' => ['gif'],
'application/pdf' => ['pdf'],
'application/msword' => ['doc'],
'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => ['docx']
];

// Obtener tipo MIME real
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$tipoMime = finfo_file($finfo, $archivo['tmp_name']);
finfo_close($finfo);

// Obtener extensión
$extension = strtolower(pathinfo($archivo['name'], PATHINFO_EXTENSION));

// Validar que el tipo MIME esté permitido
if (!array_key_exists($tipoMime, $tiposPermitidos)) {
return [
'valido' => false,
'mensaje' => 'Tipo de archivo no permitido'
];
}

// Validar que la extensión coincida con el tipo MIME
if (!in_array($extension, $tiposPermitidos[$tipoMime])) {
return [
'valido' => false,
'mensaje' => 'La extensión del archivo no coincide con su contenido real'
];
}

return [
'valido' => true,
'tipo' => $tipoMime,
'extension' => $extension
];
}

// Ejemplo de uso
if (isset($_FILES['archivo']) && $_FILES['archivo']['error'] === UPLOAD_ERR_OK) {
$validacion = validarArchivoCompleto($_FILES['archivo']);

if ($validacion['valido']) {
echo "Archivo válido: {$validacion['tipo']} (.{$validacion['extension']})";
// Continuar con el procesamiento
} else {
die("Error: " . $validacion['mensaje']);
}
}
?>

Consideraciones especiales

application/octet-stream

Este tipo MIME genérico se utiliza cuando el servidor no puede determinar el tipo específico del archivo. Es conveniente rechazar archivos con este tipo MIME en aplicaciones que requieren alta seguridad.

Archivos peligrosos

Algunos tipos MIME deben ser bloqueados por razones de seguridad:

  • application/x-php: Archivos PHP ejecutables
  • application/x-httpd-php: Scripts PHP
  • application/x-sh: Scripts de shell
  • application/x-executable: Ejecutables
<?php
// Lista negra de tipos peligrosos
$tiposPeligrosos = [
'application/x-php',
'application/x-httpd-php',
'application/x-sh',
'application/x-executable',
'application/x-msdownload',
'text/x-php'
];

$finfo = finfo_open(FILEINFO_MIME_TYPE);
$tipoMime = finfo_file($finfo, $_FILES['archivo']['tmp_name']);
finfo_close($finfo);

if (in_array($tipoMime, $tiposPeligrosos)) {
die("Este tipo de archivo está prohibido por razones de seguridad");
}
?>

Validar el tipo con finfo_file()

La validación correcta de tipos MIME es fundamental para la seguridad de cualquier aplicación que permita subida de archivos. Nunca confíes únicamente en la extensión del archivo o en el tipo MIME reportado por el navegador. Utiliza siempre funciones como finfo_file() para analizar el contenido real del archivo y valida contra una lista blanca de tipos permitidos específicos para tu aplicación.