← Todos los artículos
SEGURIDAD · FUNDAMENTOS

Seguridad en Sistemas: Fundamentos Esenciales para Desarrolladores

Security in Systems: Essential Fundamentals for Developers

NovaFox Labs· 15 de abril de 2026· 10 min · ~2 000 palabras

La seguridad en sistemas no es una capa que se agrega al final del desarrollo. Es una propiedad que debe estar presente desde las decisiones de arquitectura hasta cada línea de código que maneja datos sensibles. Para los desarrolladores, entender los fundamentos de seguridad no es opcional: es parte del oficio.

La mentalidad de seguridad

El primer cambio es de mentalidad: pasar de pensar "¿qué hace este sistema?" a también preguntarse "¿qué podría hacer alguien para abusar de este sistema?". Este modelo mental, conocido como threat modeling, ayuda a identificar superficies de ataque antes de que sean explotadas.

La práctica de Secure by Design propone que las decisiones de arquitectura incorporen seguridad desde el inicio: autenticación robusta, mínimo privilegio, validación de inputs en los bordes del sistema, cifrado de datos sensibles. No como parches posteriores, sino como características fundamentales del diseño.

Principio fundamental: Un atacante solo necesita encontrar un vector de ataque; el defensor necesita proteger todos. Esto hace que la seguridad sea asimétrica por naturaleza y justifica un enfoque proactivo, no reactivo.

Autenticación vs Autorización

La confusión entre autenticación y autorización es una de las fuentes más comunes de vulnerabilidades en sistemas. Son conceptos distintos con controles distintos:

  • Autenticación: verifica quién eres. Proceso de confirmar la identidad de un usuario o sistema mediante credenciales (contraseña, biométrica, certificado, token).
  • Autorización: verifica qué puedes hacer. Una vez autenticado, determina qué recursos puede acceder y qué operaciones puede ejecutar ese usuario.

Un sistema con autenticación fuerte pero autorización débil es vulnerable: un usuario autenticado puede acceder a recursos que no le pertenecen (horizontal privilege escalation) o escalar sus propios permisos (vertical privilege escalation). Ambos defectos aparecen frecuentemente en el OWASP Top 10.

JWT y tokens de acceso

JSON Web Tokens (JWT) son el mecanismo más utilizado para transmitir claims de autenticación en APIs REST. Un JWT consta de tres partes codificadas en Base64: header (algoritmo), payload (claims) y signature (firma que garantiza integridad).

PRÁCTICA 01

Usa algoritmos asimétricos cuando sea posible

RS256 (RSA con SHA-256) o ES256 (ECDSA) son preferibles a HS256 (HMAC): con algoritmos asimétricos, los servicios que solo verifican tokens no necesitan conocer la clave privada con que se firmaron.

PRÁCTICA 02

Tiempos de expiración cortos

Los access tokens deben tener vida corta (15-60 minutos). Los refresh tokens, vida larga pero almacenados de forma segura y con rotación. Un token comprometido con expiración corta limita drásticamente el daño.

PRÁCTICA 03

Valida todos los claims

No solo verifiques la firma; valida iss (emisor), aud (audiencia) y exp (expiración). Aceptar tokens de cualquier emisor o para cualquier audiencia es una vulnerabilidad grave.

Cifrado en tránsito y en reposo

Los datos sensibles deben estar cifrados en dos estados distintos:

  • En tránsito: toda comunicación HTTP debe ocurrir sobre TLS 1.2 o superior (HTTPS). Configura HSTS en el servidor para forzar HTTPS y prevenir downgrades.
  • En reposo: bases de datos, archivos de configuración y backups que contienen datos sensibles deben estar cifrados. En Azure, usa cifrado transparente con claves gestionadas en Key Vault.
  • Contraseñas: nunca almacenes contraseñas en texto plano ni reversiblemente. Usa funciones de hash diseñadas para contraseñas: bcrypt, Argon2id o scrypt, con un factor de costo ajustado al hardware.

Nunca cifres contraseñas: cifrar una contraseña implica que puede descifrarse. Las contraseñas deben aplicárseles hash unidireccional. Si alguien con acceso a tu base de datos puede recuperar una contraseña, tu sistema tiene un defecto de diseño fundamental.

Principio de mínimo privilegio

El principio de mínimo privilegio establece que cada componente del sistema, ya sea un usuario, un proceso o un servicio, debe tener únicamente los permisos estrictamente necesarios para realizar su función. No más.

En la práctica:

  • La cuenta de base de datos usada por la aplicación no necesita permisos de DROP TABLE ni CREATE; solo SELECT, INSERT, UPDATE y DELETE en las tablas requeridas.
  • Los service accounts en Kubernetes o cloud no necesitan acceso a todos los recursos del namespace o la suscripción.
  • Los roles de usuario en la aplicación deben ser granulares: un usuario con rol de "lector" no debe poder escribir aunque encuentre un endpoint de escritura.

Manejo seguro de secretos

Uno de los problemas más comunes en proyectos es encontrar API keys, connection strings y contraseñas en el código fuente o en el historial de Git. Esto convierte el repositorio en una superficie de ataque permanente.

  • Nunca hagas commit de secretos en el repositorio. Usa .gitignore para archivos .env locales y audita el historial con herramientas como git-secrets o truffleHog.
  • En desarrollo: usa .env local o user-secrets en .NET para mantener secretos fuera del código.
  • En producción: usa un servicio de gestión de secretos como Azure Key Vault, AWS Secrets Manager o HashiCorp Vault. Los secretos se inyectan en tiempo de ejecución, nunca en el código ni en las variables de entorno del pipeline de forma permanente.

Logging seguro

El logging es indispensable para detectar y responder a incidentes de seguridad. Pero un log mal diseñado puede convertirse en un vector de ataque o en una filtración de datos sensibles.

  • Nunca logarithmizes datos sensibles directamente: contraseñas, tokens, números de tarjeta, datos personales. Si necesitas traza de una operación, loguea IDs anonimizados o hashes.
  • Registra eventos de seguridad relevantes: intentos de autenticación fallidos, cambios de permisos, accesos a recursos privilegiados, errores de autorización.
  • Protege los logs del acceso no autorizado: un atacante que puede modificar los logs puede borrar sus huellas.

Conclusión

La seguridad en sistemas es una disciplina extensa, pero sus fundamentos son accesibles para cualquier desarrollador. Autenticación robusta, autorización correctamente implementada, cifrado de datos sensibles, mínimo privilegio, gestión segura de secretos y logging apropiado constituyen la base que protege la mayoría de las superficies de ataque comunes.

Construir con seguridad desde el inicio no es significativamente más costoso que construir sin ella. Lo que sí es costoso —en tiempo, dinero y reputación— es remediar una brecha de seguridad después de que ocurre.

Security in systems is not a layer added at the end of development. It's a property that must be present from architectural decisions to every line of code that handles sensitive data. For developers, understanding security fundamentals is not optional: it's part of the craft.

The security mindset

The first change is in mindset: moving from thinking "what does this system do?" to also asking "what could someone do to abuse this system?" This mental model, known as threat modeling, helps identify attack surfaces before they're exploited.

The practice of Secure by Design proposes that architectural decisions incorporate security from the start: robust authentication, least privilege, input validation at system boundaries, encryption of sensitive data. Not as later patches, but as fundamental characteristics of the design.

Fundamental principle: An attacker only needs to find one attack vector; the defender needs to protect all of them. This makes security inherently asymmetric and justifies a proactive, not reactive, approach.

Authentication vs Authorization

The confusion between authentication and authorization is one of the most common sources of vulnerabilities in systems. They're distinct concepts with distinct controls:

  • Authentication: verifies who you are. The process of confirming the identity of a user or system through credentials (password, biometric, certificate, token).
  • Authorization: verifies what you can do. Once authenticated, determines what resources that user can access and what operations they can perform.

A system with strong authentication but weak authorization is vulnerable: an authenticated user can access resources that don't belong to them (horizontal privilege escalation) or escalate their own permissions (vertical privilege escalation). Both defects frequently appear in the OWASP Top 10.

JWT and access tokens

JSON Web Tokens (JWT) are the most widely used mechanism for transmitting authentication claims in REST APIs. A JWT consists of three Base64-encoded parts: header (algorithm), payload (claims), and signature (ensuring integrity).

PRACTICE 01

Use asymmetric algorithms when possible

RS256 (RSA with SHA-256) or ES256 (ECDSA) are preferable to HS256 (HMAC): with asymmetric algorithms, services that only verify tokens don't need to know the private key they were signed with.

PRACTICE 02

Short expiration times

Access tokens should have short lifetimes (15-60 minutes). Refresh tokens, long lifetimes but stored securely and with rotation. A compromised token with short expiration dramatically limits the damage.

PRACTICE 03

Validate all claims

Don't just verify the signature; validate iss (issuer), aud (audience), and exp (expiration). Accepting tokens from any issuer or for any audience is a serious vulnerability.

Encryption in transit and at rest

Sensitive data must be encrypted in two distinct states:

  • In transit: all HTTP communication must occur over TLS 1.2 or higher (HTTPS). Configure HSTS on the server to enforce HTTPS and prevent downgrades.
  • At rest: databases, configuration files, and backups containing sensitive data must be encrypted. In Azure, use transparent encryption with keys managed in Key Vault.
  • Passwords: never store passwords in plain text or reversibly. Use hash functions designed for passwords: bcrypt, Argon2id, or scrypt, with a cost factor adjusted to the hardware.

Never encrypt passwords: encrypting a password implies it can be decrypted. Passwords should be hashed one-way. If someone with access to your database can recover a password, your system has a fundamental design flaw.

Principle of least privilege

The principle of least privilege establishes that each system component—whether a user, process, or service—should have only the permissions strictly necessary to perform its function. No more.

In practice:

  • The database account used by the application doesn't need DROP TABLE or CREATE permissions; only SELECT, INSERT, UPDATE, and DELETE on the required tables.
  • Service accounts in Kubernetes or cloud don't need access to all resources in the namespace or subscription.
  • User roles in the application should be granular: a user with a "reader" role shouldn't be able to write even if they find a write endpoint.

Secure secrets management

One of the most common problems in projects is finding API keys, connection strings, and passwords in source code or in the Git history. This turns the repository into a permanent attack surface.

  • Never commit secrets to the repository. Use .gitignore for local .env files and audit the history with tools like git-secrets or truffleHog.
  • In development: use local .env or user-secrets in .NET to keep secrets out of the code.
  • In production: use a secrets management service like Azure Key Vault, AWS Secrets Manager, or HashiCorp Vault. Secrets are injected at runtime, never in the code or in pipeline environment variables permanently.

Secure logging

Logging is indispensable for detecting and responding to security incidents. But a poorly designed log can become an attack vector or a sensitive data leak.

  • Never log sensitive data directly: passwords, tokens, card numbers, personal data. If you need a trace of an operation, log anonymized IDs or hashes.
  • Record relevant security events: failed authentication attempts, permission changes, access to privileged resources, authorization errors.
  • Protect logs from unauthorized access: an attacker who can modify logs can erase their tracks.

Conclusion

Security in systems is an extensive discipline, but its fundamentals are accessible to any developer. Robust authentication, correctly implemented authorization, encryption of sensitive data, least privilege, secure secrets management, and appropriate logging form the foundation that protects most common attack surfaces.

Building with security from the start is not significantly more expensive than building without it. What is expensive—in time, money, and reputation—is remediating a security breach after it occurs.

¿Necesitas una solución como esta?

Contrátame