Contenido verificado · 20 unidades

Ejercicios y práctica · Programación de Servicios y Procesos · DAM

Convierte los RA y errores frecuentes del módulo en práctica adaptativa. Esta página se construye únicamente con contenido verificado y con los RA del módulo.

Practicar este módulo con José

Qué deberías ser capaz de hacer

RA1

Desarrolla aplicaciones compuestas por varios procesos reconociendo y aplicando principios de programación paralela.

RA2

Desarrolla aplicaciones compuestas por varios hilos de ejecución analizando y aplicando librerías específicas del lenguaje de programación.

RA3

Programa mecanismos de comunicación en red empleando sockets y analizando el escenario de ejecución.

RA4

Desarrolla aplicaciones que ofrecen servicios en red, utilizando librerías de clases y aplicando criterios de eficiencia y disponibilidad.

RA5

Protege las aplicaciones y los datos definiendo y aplicando criterios de seguridad en el acceso, almacenamiento y transmisión de la información.

Errores frecuentes que la práctica debería detectar

  • Asignar permisos excesivos: Causa: Facilidad de desarrollo o desconocimiento del principio de mínimo privilegio. Corrección: Auditar y restringir permisos a lo estrictamente necesario para cada componente o usuario.
  • Confiar solo en la validación del lado del cliente: Causa: Creencia errónea de que es suficiente o desconocimiento de cómo un atacante puede eludirla. Corrección: Implementar siempre validación robusta en el lado del servidor para todas las entradas.
  • Revelar información sensible en mensajes de error: Causa: Facilidad para la depuración durante el desarrollo. Corrección: Configurar la aplicación para mostrar mensajes de error genéricos al usuario final y registrar los detalles internamente.
  • Almacenar claves de cifrado junto con los datos cifrados: Causa: Simplificación del diseño o desconocimiento de la importancia de la separación de responsabilidades. Corrección: Utilizar un KMS o un almacén de secretos dedicado y seguro para las claves.
  • Usar algoritmos de hash débiles para contraseñas: Causa: Desconocimiento de las vulnerabilidades de MD5/SHA-1 o uso de librerías obsoletas. Corrección: Migrar a algoritmos modernos como bcrypt, scrypt o Argon2, que son más resistentes a ataques de fuerza bruta.
  • No usar 'salt' con los hashes de contraseñas: Causa: Desconocimiento del ataque de tablas arcoíris. Corrección: Generar un 'salt' aleatorio y único para cada contraseña y almacenarlo junto con el hash.
  • Hardcodear permisos por ID de usuario: Causa: Solución rápida y no escalable. Corrección: Implementar RBAC para gestionar permisos de forma flexible y escalable.
  • No separar autenticación de autorización: Causa: Confusión entre verificar quién es el usuario y qué puede hacer. Corrección: Asegurarse de que la autenticación se complete antes de que se evalúen las reglas de autorización.
  • Permisos demasiado amplios para roles: Causa: Simplificación excesiva. Corrección: Definir roles con el principio de mínimo privilegio, asignando solo los permisos estrictamente necesarios para la función del rol.
  • Desactivar la verificación de certificados o el chequeo de hostname: causa habitual, evitar fallos con certificados autofirmados en desarrollo; corrección, validar siempre en producción y usar certificados de desarrollo correctamente confiados (OpenSSL/mkcert).
  • Permitir TLS 1.0/1.1 en la configuración del socket: causa, compatibilidad heredada o falta de actualización; corrección, exigir como mínimo TLS 1.2 y preferir TLS 1.3.
  • Usar ssl.wrap_socket() en Python en lugar de SSLContext: causa, seguir ejemplos desactualizados; corrección, emplear SSLContext.wrap_socket(), que permite mayor control y sigue mantenido.
  • No capturar ni tratar las excepciones del handshake TLS: causa, no prever fallos de certificado o negociación; corrección, implementar manejo específico de estas excepciones y registrar el incidente sin exponer datos sensibles.
  • {"error":"Bloquear el hilo principal (UI) con operaciones de red.","causa":"Las operaciones de red son lentas y bloqueantes. Ejecutarlas en el hilo de la interfaz de usuario (por ejemplo, en Android o una aplicación de escritorio) congela la aplicación hasta que se completa la respuesta, generando una mala experiencia de usuario y posibles errores de 'Aplicación no responde'.","correccion":"Realizar siempre las operaciones de red en un hilo de trabajo separado (background thread). Utilizar mecanismos como `AsyncTask` (en Android clásico), `Executors` o `CompletableFuture` en Java para gestionar la concurrencia y actualizar la UI de forma segura una vez obtenidos los resultados."}
  • {"error":"No cerrar las conexiones o los streams.","causa":"Olvidar invocar `disconnect()` en la conexión o `close()` en los streams (`InputStream`, `OutputStream`, etc.). Esto provoca una fuga de recursos (resource leak), agotando los descriptores de fichero del sistema operativo y pudiendo impedir que la aplicación o el sistema abran nuevas conexiones.","correccion":"Utilizar siempre un bloque `finally` o, preferiblemente, la construcción `try-with-resources` de Java para garantizar que todos los recursos (conexiones, streams) se cierren automáticamente, incluso si se produce una excepción."}
  • {"error":"Usar un puerto privilegiado (<1024) sin permisos de administrador.","causa":"Los sistemas operativos tipo Unix (Linux, macOS) reservan los puertos del 0 al 1023 para servicios del sistema. Intentar que un `ServerSocket` escuche en uno de estos puertos (ej. 80 para HTTP) desde una cuenta de usuario normal lanzará una `BindException` por permisos denegados.","correccion":"Para el desarrollo y pruebas, utilizar siempre puertos no privilegiados (superiores a 1023, típicamente >49151). En un entorno de producción, la aplicación se ejecutaría con los permisos necesarios o se configuraría un proxy inverso (como Nginx) que escuche en el puerto 80/443 y redirija el tráfico al puerto no privilegiado de la aplicación."}
  • {"error":"No gestionar correctamente el fin de la comunicación por parte del cliente.","causa":"Si un cliente cierra la conexión abruptamente, el método `readLine()` en el servidor puede devolver `null`. Si el código no comprueba esta condición, intentará procesar un valor nulo, resultando en una `NullPointerException` que puede hacer caer el hilo que atiende a ese cliente o incluso el servidor si no está bien estructurado.","correccion":"El bucle de lectura del servidor debe comprobar explícitamente si la línea leída es `null` y, en ese caso, interpretar que el cliente ha cerrado la conexión, procediendo a cerrar los recursos de ese lado de forma ordenada."}
  • {"error":"Modificar datos compartidos desde múltiples hilos sin sincronización.","causa":"Varios hilos `ClientHandler` intentan leer y escribir en una misma estructura de datos (ej. un `HashMap` que guarda el estado de los usuarios) sin ningún mecanismo de bloqueo. Esto lleva a condiciones de carrera, donde el resultado final depende del orden impredecible en que los hilos son ejecutados por el planificador del SO, causando datos corruptos, inconsistentes o excepciones como `ConcurrentModificationException`.","correccion":"Utilizar estructuras de datos seguras para la concurrencia (ej. `ConcurrentHashMap` en lugar de `HashMap`) o proteger el acceso a las secciones críticas del código (donde se modifican los datos compartidos) usando bloques `synchronized` o `ReentrantLock` para asegurar que solo un hilo puede modificar el recurso a la vez."}

Del contenido SEO a tu estado real

Esta página explica el módulo. José, dentro del workspace, utiliza tu dominio, autonomía, confianza y evidencias para decidir si necesitas diagnóstico, práctica, reenseñanza o repaso.

Practicar este módulo con José
Canal Estudios es un servicio de Skillback S.L. · NIF B2481724 · Barcelona, España
Aviso legal · Privacidad · Cookies · Términos