Verifica las subidas web con Magika y una API de Python
Las extensiones de archivo y los tipos MIME que envía el cliente se pueden falsificar. Magika, de código abierto y creado por Google, clasifica los archivos por sus bytes. Este tutorial ejecuta Magika en un servidor Python: el navegador sube el archivo completo a un endpoint de Flask y muestra su resultado. El procesamiento no se queda en el dispositivo del usuario, e identificar un formato no demuestra que un archivo sea inofensivo.
Desafíos de la verificación tradicional de tipos de archivo
Las técnicas de identificación más comunes inspeccionan los metadatos o las firmas de archivo:
- Las extensiones de archivo se pueden renombrar en segundos.
- Los tipos MIME vienen del cliente y con frecuencia son incorrectos.
- Los números mágicos funcionan con formatos comunes, pero tienen dificultades con archivos propietarios o poliglotas.
Estos puntos débiles habilitan subidas maliciosas, por ejemplo evil.exe que se hace pasar por
holiday.jpg, y crean una superficie de ataque real para las aplicaciones web.
Presentamos Magika: identificación de archivos con IA
Magika usa un modelo de aprendizaje profundo para identificar
formatos binarios y de texto. Devuelve un único tipo predicho y una puntuación de confianza. No
valida todas las estructuras internas de un archivo, ni detecta todos los poliglotas, ni busca
malware. Este ejemplo usa la API de Python de magika==0.6.1, con Python 3.9 o posterior.
Cómo funciona Magika
- Extrae características de partes seleccionadas del archivo. La API de abajo primero lee en memoria el archivo subido, por lo que aplica un límite de tamaño antes de la clasificación.
- Pasa esos datos a una red neuronal ligera. Ofrece distintos modos de identificación, con
HIGH_CONFIDENCEcomo predeterminado. - Devuelve una etiqueta, un tipo MIME y una puntuación de confianza. Mide la latencia en tu despliegue, incluidos el arranque del modelo y el tiempo de subida.
Integra Magika en una aplicación de navegador
1. Instala Magika
python -m pip install magika==0.6.1 flask==3.1.0
2. Crea una API de verificación mínima (Flask)
from flask import Flask, request, jsonify
from magika import Magika
from werkzeug.exceptions import RequestEntityTooLarge
app = Flask(__name__)
MAX_FILE_BYTES = 5 * 1024 * 1024
app.config['MAX_CONTENT_LENGTH'] = 6 * 1024 * 1024 # Includes multipart overhead
ALLOWED_TYPES = {'pdf', 'jpeg', 'png'}
magika = Magika() # Load the model once at startup
@app.errorhandler(RequestEntityTooLarge)
def request_too_large(error):
return jsonify({'error': 'Upload is too large'}), 413
@app.route('/verify', methods=['POST'])
def verify_file():
if 'file' not in request.files:
return jsonify({'error': 'No file provided'}), 400
content = request.files['file'].read(MAX_FILE_BYTES + 1)
if not content:
return jsonify({'error': 'File is empty'}), 400
if len(content) > MAX_FILE_BYTES:
return jsonify({'error': 'Upload is too large'}), 413
result = magika.identify_bytes(content)
if not result.ok:
return jsonify({'error': 'File analysis failed'}), 500
if result.output.label not in ALLOWED_TYPES:
return jsonify({'error': 'Only PDF, JPEG, and PNG files are allowed'}), 415
return jsonify({
'file_type': result.output.label,
'mime_type': result.output.mime_type,
'description': result.output.description,
'score': result.score,
})
if __name__ == '__main__': # dev only—use Gunicorn in production
app.run()
Guarda el ejemplo como app.py y ejecuta python app.py para el desarrollo local. Sirve el frontend
desde el mismo origen que /verify (o configura un proxy de desarrollo). Para producción, usa un
servidor WSGI junto con tiempos de espera de las solicitudes, autenticación y límites de tasa. Este
endpoint solo analiza los bytes enviados; un endpoint de subida o de almacenamiento aparte debe
aplicar por sí mismo las mismas comprobaciones.
3. Conecta el frontend
Añade un input de archivo con id="fileInput" y un elemento de resultado con id="result", y luego ejecuta
este código cuando esos elementos ya existan:
async function verifyFile(file) {
const formData = new FormData()
formData.append('file', file)
try {
const response = await fetch('/verify', {
method: 'POST',
body: formData,
})
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`)
}
const result = await response.json()
return result
} catch (error) {
console.error('File verification request failed:', error)
throw error
}
}
document.getElementById('fileInput').addEventListener('change', async (event) => {
const file = event.target.files[0]
if (!file) {
return // No file selected
}
try {
const analysisResult = await verifyFile(file)
document.getElementById('result').textContent =
`Detected: ${analysisResult.file_type} (${(analysisResult.score * 100).toFixed(1)}% confidence)`
} catch (error) {
document.getElementById('result').textContent = 'Verification failed. See console for details.'
}
})
4. Compara los resultados con una lista de permitidos
La API ya aplica su lista de permitidos. Una comprobación equivalente en el cliente puede mejorar la retroalimentación, pero nunca debe autorizar por sí sola una subida posterior.
// Assuming 'analysisResult' is available from the previous step
const allowedFileTypes = ['pdf', 'jpeg', 'png'] // Using Magika's labels
if (!allowedFileTypes.includes(analysisResult.file_type)) {
alert(
`File type "${analysisResult.file_type}" is not allowed. Allowed types are: ${allowedFileTypes.join(', ')}.`,
)
// Or throw new Error(`File type ${analysisResult.file_type} is not permitted.`);
}
Magika frente a los métodos tradicionales
| Característica | Extensión de archivo / MIME | Números mágicos | Magika |
|---|---|---|---|
| Detecta extensiones falsificadas | ❌ | ✅/Parcial | ✅ |
| Velocidad (milisegundos por archivo) | ✅ | ✅ | ✅ |
| Código abierto y con mantenimiento | N/A | Algunos | ✅ |
Casos de uso prácticos
Formularios de subida seguros
Valida las subidas antes de guardarlas o de pasarlas a un procesamiento posterior. Esta comprobación debería ocurrir principalmente en tu servidor, después de recibir el archivo y el análisis de Magika.
// Example client-side feedback based on server verification result
// const analysisResult = await verifyFile(file); // from server
if (!['jpeg', 'png', 'pdf'].includes(analysisResult.file_type)) {
// Display error to user: Only images and PDFs allowed
throw new Error('Only images and PDFs allowed')
}
Moderación de contenido
Enruta los archivos a pipelines especializados según la etiqueta de Magika: imágenes a un servicio de moderación con IA, videos a FFmpeg, documentos a OCR, y así sucesivamente.
Análisis previo de malware
Las etiquetas de archivo pueden derivar ejecutables o scripts a una revisión adicional. Una lista de bloqueados por sí sola no basta: incluso una imagen o un PDF permitidos pueden necesitar análisis de malware y validación de formato.
# Within a server-side classification workflow, after checking result.ok:
risky_file_types = {'pebin', 'elf', 'macho', 'batch', 'shell'}
requires_additional_review = result.output.label in risky_file_types
Manejo de errores y buenas prácticas
- Verifica en el servidor. Las comprobaciones en el cliente son una comodidad, no una defensa robusta.
- Configura tiempos de espera para las solicitudes. Los archivos grandes o los contenedores con arranque en frío siguen necesitando límites en tu endpoint de API.
- Registra las puntuaciones de confianza. Ayudan a rastrear casos límite cuando Magika no tiene certeza, o a efectos de auditoría.
- Actualiza con regularidad. Cada versión de Magika añade formatos y mejora la precisión.
- Combina capas de defensa. Usa Magika junto con software antivirus, lógica de lista de bloqueados basada en otros criterios y limitación de tasa en tu endpoint de subida.
Alternativa de Transloadit
¿Prefieres un SaaS listo para usar? Nuestro Robot 🤖 /file/verify realiza en la nube comprobaciones similares basadas en el contenido. Un Step mínimo se ve así:
{
"robot": "/file/verify",
"use": ":original",
"verify_to_be": "pdf",
"error_on_decline": true,
"error_msg": "File type verification failed"
}
Combínalo con Uppy para obtener un pipeline de subida completo de principio a fin.
Conclusión
Magika mejora notablemente la verificación de tipos de archivo al inspeccionar el contenido del archivo en lugar de confiar en los metadatos. Tanto si alojas Magika por tu cuenta como si usas el Robot de Transloadit, las comprobaciones basadas en el contenido pueden rechazar formatos inesperados. Combínalas con análisis de malware y un manejo seguro de los archivos aceptados; la clasificación por sí sola no es un veredicto sobre malware.
