Estado Actual del Programa - Análisis CWE-699¶
Fecha de análisis: 2025-01-27
Versión analizada: Mayor Update (post-implementación de validación de nombres)
Resumen Ejecutivo¶
El programa ha mejorado significativamente en validación de entrada y manejo de errores estructurado, pero aún presenta algunas debilidades de seguridad que requieren atención, especialmente relacionadas con validación de tipos y headers de seguridad.
Estado Detallado por Categoría¶
1. Type Errors (Errores de Tipo) ⚠️ REQUIERE ATENCIÓN¶
1.1 CWE-1287: Improper Validation of Specified Type of Input¶
Estado: ⚠️ PENDIENTE
Ubicación: app/routes.py líneas 36-39 y 94-97
Problema actual:
# Línea 36-39
try:
height_m = float(data['talla_m'])
except Exception: # ⚠️ Muy genérico
return jsonify({"error": get_error("invalid_height")}), 400
# Línea 94-97
try:
weight_kg = float(data['peso_kg'])
except Exception: # ⚠️ Muy genérico
return jsonify({"error": get_error("invalid_weight")}), 400
Problemas identificados:
❌ Usa
Exceptiongenérico que puede ocultar errores inesperados❌ No valida que el resultado sea un número finito (puede ser NaN o Infinity)
❌ No valida el tipo antes de la conversión
Impacto: Si se envía un valor que no es convertible a float, o si el resultado es NaN/Infinity, puede causar errores en cálculos posteriores.
1.2 CWE-843: Access of Resource Using Incompatible Type (‘Type Confusion’)¶
Estado: ⚠️ PENDIENTE
Ubicación: app/static/js/main.js líneas 139, 207; app/static/js/storage.js línea 84
Problema actual:
// main.js línea 139
const talla_m = parseFloat(document.getElementById('talla_m').value);
// ⚠️ No valida si es NaN o Infinity
// main.js línea 207
const weight_kg = parseFloat(document.getElementById('peso').value);
// ⚠️ No valida si es NaN o Infinity
// storage.js línea 84
peso_kg: parseFloat(weight.peso_kg),
// ⚠️ No valida si es NaN o Infinity
Problemas identificados:
❌
parseFloat()puede retornarNaNsin validación❌ No se verifica
isFinite()después de la conversión❌ Los valores NaN pueden propagarse en cálculos matemáticos
Impacto: Si un usuario introduce un valor inválido, parseFloat() retorna NaN, que luego se usa en cálculos (IMC, validaciones) causando resultados incorrectos o errores.
2. User Interface Security Issues ⚠️ REQUIERE ATENCIÓN¶
2.1 CWE-1021: Improper Restriction of Rendered UI Layers or Frames¶
Estado: ⚠️ PENDIENTE
Ubicación: app/__init__.py
Problema actual:
❌ No hay headers de seguridad configurados
❌ No hay
X-Frame-Optionspara prevenir clickjacking❌ No hay
Content-Security-Policypara restringir frames❌ No hay
X-Content-Type-Optionspara prevenir MIME sniffing
Impacto: La aplicación es vulnerable a ataques de clickjacking y no tiene protección contra inyección de contenido malicioso a través de iframes.
3. Input Validation (Validación de Entrada) ✅ RESUELTO¶
3.1 CWE-20: Improper Input Validation¶
Estado: ✅ IMPLEMENTADO CORRECTAMENTE
Ubicación: app/helpers.py, app/routes.py, app/static/js/config.js, app/static/js/main.js
Implementación actual:
✅ Función
validate_and_sanitize_name()en backend✅ Función
validateAndSanitizeName()en frontend✅ Validación de longitud (1-100 caracteres)
✅ Eliminación de caracteres peligrosos (
< > " ')✅ Normalización de espacios múltiples
✅ Validación de caracteres permitidos (letras Unicode, espacios, guiones, apóstrofes)
✅ Validación en backend y frontend (defensa en profundidad)
Código implementado:
# Backend - routes.py líneas 53-71
nombre_raw = data.get('nombre', '')
is_valid_nombre, nombre_sanitized, error_key_nombre = validate_and_sanitize_name(
nombre_raw,
min_length=VALIDATION_LIMITS["name_min_length"],
max_length=VALIDATION_LIMITS["name_max_length"]
)
if not is_valid_nombre:
return jsonify({"error": get_error(error_key_nombre or "invalid_name")}), 400
// Frontend - main.js líneas 147-167
const nombreValidation = AppConfig.validateAndSanitizeName(nombreInput);
if (!nombreValidation.isValid) {
alert(MESSAGES.errors[nombreValidation.errorKey] || 'El nombre no es válido');
return;
}
Estado: ✅ COMPLETAMENTE IMPLEMENTADO Y FUNCIONAL
4. Error Handling (Manejo de Errores) ⚠️ MEJORADO PARCIALMENTE¶
4.1 CWE-703: Improper Check or Handling of Exceptional Conditions¶
Estado: ⚠️ MEJORADO PARCIALMENTE
Mejoras implementadas:
✅ Validación de nombres usa manejo estructurado de errores (no
Exceptiongenérico)✅ Retorna códigos de error específicos (
name_empty,name_too_long,invalid_name)✅ Manejo proactivo en lugar de reactivo (try/except)
Pendiente:
⚠️ Líneas 38 y 96 en
routes.pyaún usanExceptiongenérico⚠️
sync.jslínea 119 captura cualquier error sin diferenciar tipos
Impacto: El manejo de errores en validación de nombres es robusto, pero otras partes del código aún pueden ocultar errores inesperados.
5. CORS Configuration ⏸️ PENDIENTE¶
5.1 CWE-942: Overly Permissive Cross-domain Whitelist¶
Estado: ⏸️ PENDIENTE
Ubicación: app/__init__.py líneas 13-19
Estado actual:
CORS(app, resources={
r"/api/*": {
"origins": "*", # ⚠️ Permite cualquier origen
"methods": ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
"allow_headers": ["Content-Type"]
}
})
Impacto actual: Cualquier sitio web puede hacer peticiones a la API si el backend se expone fuera de localhost.
6. Data Integrity (Integridad de Datos) ✅ IMPLEMENTADO¶
7.1 Validación Defensiva¶
Estado: ✅ IMPLEMENTADO CORRECTAMENTE
Ubicación: app/routes.py líneas 148-153, app/static/js/main.js líneas 98-114
Implementación actual:
✅ Validación defensiva antes de calcular IMC en backend
✅ Validación defensiva antes de calcular IMC en frontend
✅ Verifica que peso y altura estén dentro de límites antes de usar funciones helper
✅ Protege contra datos antiguos o corruptos
Código implementado:
# Backend - routes.py líneas 148-153
if not (VALIDATION_LIMITS["weight_min"] <= last_weight.weight_kg <= VALIDATION_LIMITS["weight_max"]):
return jsonify({"error": get_error("weight_out_of_range")}), 400
if not (VALIDATION_LIMITS["height_min"] <= user.height_m <= VALIDATION_LIMITS["height_max"]):
return jsonify({"error": get_error("height_out_of_range")}), 400
// Frontend - main.js líneas 100-114
if (!AppConfig.validateWeight(lastWeight.peso_kg)) {
imcValue.textContent = '0';
imcDescription.textContent = MESSAGES.errors.weight_out_of_range ||
`Peso fuera de rango: ${lastWeight.peso_kg} kg`;
return;
}
Estado: ✅ COMPLETAMENTE IMPLEMENTADO Y FUNCIONAL
Resumen de Estado por CWE¶
CWE |
Descripción |
Estado |
Prioridad |
Acción Requerida |
|---|---|---|---|---|
CWE-1287 |
Validación de tipo insuficiente |
⚠️ Pendiente |
Media |
Mejorar validación de tipos en |
CWE-843 |
Confusión de tipos (NaN no validado) |
⚠️ Pendiente |
Media |
Validar |
CWE-1021 |
Falta de protección contra clickjacking |
⚠️ Pendiente |
Media |
Agregar headers de seguridad |
CWE-20 |
Validación de entrada insuficiente (nombres) |
✅ Resuelto |
- |
Ninguna |
CWE-703 |
Manejo de excepciones demasiado genérico |
⚠️ Mejorado parcialmente |
Baja |
Mejorar excepciones en conversiones de |
CWE-942 |
CORS demasiado permisivo |
⏸️ Pendiente |
Media/Alta |
Restringir CORS cuando se exponga el backend |
Puntos Fuertes del Programa ✅¶
Validación de nombres robusta: Implementación completa con sanitización y validación en múltiples capas
Validaciones defensivas: Protección contra datos corruptos antes de cálculos críticos
Manejo estructurado de errores: En validación de nombres, usa códigos de error específicos
Configuración centralizada: Límites de validación en un solo lugar (
app/config.py)Defensa en profundidad: Validaciones tanto en frontend como en backend
Áreas de Mejora Prioritarias 🔴¶
Prioridad Alta (Seguridad Crítica)¶
Validar NaN e Infinity en frontend después de
parseFloat()Ubicación:
app/static/js/main.jslíneas 139, 207Impacto: Puede causar cálculos incorrectos o errores
Agregar headers de seguridad para prevenir clickjacking
Ubicación:
app/__init__.pyImpacto: Vulnerabilidad de seguridad conocida
Prioridad Media (Robustez)¶
Mejorar validación de tipos en conversiones de
float()Ubicación:
app/routes.pylíneas 36-39, 94-97Impacto: Puede ocultar errores inesperados
Validar que números sean finitos después de conversión
Ubicación:
app/routes.py(después defloat())Impacto: Previene cálculos con NaN/Infinity
Prioridad Baja (Mejoras)¶
Mejorar manejo de excepciones en conversiones restantes
Ubicación:
app/routes.pylíneas 38, 96Impacto: Mejor debugging y manejo de errores
Conclusión¶
El programa ha mejorado significativamente en validación de entrada y manejo de errores estructurado. Las áreas principales que requieren atención son:
Validación de tipos numéricos: Especialmente validación de NaN/Infinity en frontend
Headers de seguridad: Implementar protección contra clickjacking
Manejo de excepciones: Especificar excepciones en lugar de
Exceptiongenérico
Las acciones pendientes de CORS y cabeceras se aplicarán cuando el backend salga del entorno local.
Estado general: ⚠️ BUENO CON ÁREAS DE MEJORA IDENTIFICADAS
Última actualización: 2025-01-27