Back to blog

Security in Modern Web Applications

Security in Modern Web Applications

Security is not optional. New vulnerabilities and attack techniques emerge every day. This comprehensive guide covers best practices and tools to protect your web applications in 2024.

OWASP Top 10: Critical Vulnerabilities

1. Broken Access Control

The #1 vulnerability according to OWASP 2021:

  • Users accessing resources without authorization
  • Privilege escalation
  • IDOR (Insecure Direct Object References)
  • Modifying URLs to access other data

Prevention:

  • Deny by default, except public resources
  • Implement centralized access control
  • Validate ownership in every operation
  • Disable directory listing
  • Rate limiting on APIs
  • Invalidate JWT tokens on logout

2. Cryptographic Failures

Failures in protecting sensitive data:

  • Transmitting data in plain text
  • Weak or deprecated cryptographic algorithms
  • Default or weak encryption keys
  • Not using HTTPS correctly

Best Practices:

  • HTTPS everywhere with TLS 1.3
  • Use modern algorithms: AES-256-GCM, ChaCha20-Poly1305
  • Bcrypt or Argon2 for passwords (never MD5 or SHA1)
  • Secrets in environment variables or vaults
  • HSTS header to force HTTPS
  • Perfect Forward Secrecy (PFS)

3. Injection

SQL, NoSQL, OS command injection:

  • Malicious input interpreted as code
  • SQL injection remains prevalent
  • Command injection in shells
  • LDAP, XPath injection

Defense:

  • Prepared statements and parameterized queries ALWAYS
  • Correctly configured ORMs
  • Whitelist input validation (not blacklist)
  • Escape special characters
  • Least privilege in database users
  • WAF for malicious pattern detection

4. Insecure Design

Fundamental flaws in architecture:

  • Not applying threat modeling
  • Lack of security requirements
  • Not validating business logic

Solution:

  • Shift left security - design with security from the start
  • Threat modeling (STRIDE, PASTA)
  • Security stories in every sprint
  • Architecture review by security team

5. Security Misconfiguration

Insecure default configurations:

  • Unnecessary open ports
  • Verbose error messages in production
  • Unused features enabled
  • Default credentials
  • Misconfigured CORS

Hardening:

  • Disable unnecessary features
  • Remove default accounts and passwords
  • Security headers: CSP, X-Frame-Options, X-Content-Type-Options
  • Automated security scanning in CI/CD
  • Principle of least privilege

Modern Authentication and Authorization

JSON Web Tokens (JWT) - Best Practices

  • Use RS256 or ES256 algorithm (not HS256 with weak secrets)
  • Short tokens: 5-15 minutes for access tokens
  • Refresh tokens with rotation
  • Store in httpOnly, secure, SameSite cookies
  • Never in localStorage (vulnerable to XSS)
  • Validate iss, aud, exp claims
  • Implement token revocation list if critical

OAuth 2.0 and OpenID Connect

  • OAuth 2.0 for authorization (not direct authentication)
  • OpenID Connect (OIDC) for authentication
  • Authorization Code Flow with PKCE
  • Never use Implicit Flow (deprecated)
  • State parameter to prevent CSRF

Multi-Factor Authentication (MFA)

Essential for modern security:

  • TOTP (Time-based One-Time Password) with apps like Authy, Google Authenticator
  • WebAuthn for biometrics and security keys
  • SMS as a last resort (vulnerable to SIM swapping)
  • Encrypted recovery codes

Passwordless Authentication

  • Magic links via email
  • WebAuthn/FIDO2 with passkeys
  • Biometrics on devices
  • Reduces phishing attacks

Protection Against XSS (Cross-Site Scripting)

Types of XSS

  • Stored XSS: Malicious script stored in DB
  • Reflected XSS: Script in URL reflected in response
  • DOM-based XSS: Client-side DOM manipulation

Multi-Layer Defense

  • Input validation: Sanitize all user input
  • Output encoding: HTML entity encoding in templates
  • CSP (Content Security Policy): Restrictive header
  • DOMPurify: Library to sanitize HTML
  • Modern Frameworks: React, Vue, Angular escape by default
  • Careful with dangerouslySetInnerHTML: Use only with sanitization

Content Security Policy Example

  • default-src 'self'
  • script-src 'self' 'nonce-{random}'
  • style-src 'self' 'unsafe-inline' (ideally remove unsafe-inline)
  • img-src 'self' data: https:
  • connect-src 'self' https://api.yourapp.com
  • frame-ancestors 'none'

CSRF Protection (Cross-Site Request Forgery)

How CSRF Works

Attacker tricks browser into sending authenticated requests:

  • User authenticated on legitimate site
  • Visits malicious site
  • Malicious site sends request to legitimate site
  • Browser automatically includes cookies

Prevention

  • CSRF Tokens: Unique token per session/request
  • SameSite cookies: SameSite=Strict or Lax
  • Double Submit Cookie: Token in cookie and header
  • Custom headers: X-Requested-With in AJAX
  • Origin/Referer checking: Validate request origin
  • GET requests should never modify state

HTTPS and TLS Configuration

SSL/TLS Certificates

  • Let's Encrypt for free certificates
  • Automatic renewal with certbot
  • Wildcard certificates for subdomains
  • Certificate pinning in mobile apps

Optimal TLS Configuration

  • TLS 1.3 only (disable 1.0, 1.1, 1.2 if possible)
  • Secure cipher suites: ECDHE+AESGCM, ChaCha20-Poly1305
  • Perfect Forward Secrecy (PFS)
  • HSTS with includeSubDomains and preload
  • OCSP stapling for better performance

Essential Security Headers

  • Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
  • X-Frame-Options: DENY (prevent clickjacking)
  • X-Content-Type-Options: nosniff
  • Referrer-Policy: strict-origin-when-cross-origin
  • Permissions-Policy: Control browser features

Dependencies and Supply Chain Security

The Problem

  • Modern projects have hundreds of dependencies
  • Transitive dependencies multiplied
  • Vulnerabilities discovered constantly
  • Attacks on npm packages (typosquatting, compromised packages)

Scanning Tools

  • npm audit / yarn audit: Built-in scanning
  • Snyk: Continuous monitoring, automatic fix PRs
  • Dependabot (GitHub): Automatic PRs for updates
  • OWASP Dependency-Check: Open source scanner
  • Socket.dev: Detects malware in packages

Best Practices

  • Keep dependencies updated
  • Review package-lock.json in code reviews
  • Use package.json with specific versions or ~
  • Avoid ^ which can bring breaking changes
  • Audit new dependencies before adding
  • Consider bundle size and security when choosing libs
  • Use subresource integrity (SRI) for CDNs

API Security

Rate Limiting and Throttling

  • Prevent DoS and brute force attacks
  • By IP, by user, by API key
  • Token bucket or leaky bucket algorithms
  • Headers: X-RateLimit-Limit, X-RateLimit-Remaining
  • 429 Too Many Requests with Retry-After

API Keys and Secrets

  • Never in source code or repositories
  • Environment variables
  • Secrets managers: AWS Secrets Manager, Azure Key Vault, HashiCorp Vault
  • Regular key rotation
  • Minimum necessary scope

Input Validation

  • Validate in backend ALWAYS (don't trust frontend)
  • Schema validation: Joi, Yup, Zod
  • Type checking in APIs (TypeScript, GraphQL)
  • Reject unknown fields
  • Validate data types, formats, ranges

API Versioning and Deprecation

  • Versioning in URL: /api/v1/users
  • Deprecation warnings in responses
  • Sunset header to announce end of support
  • Maintain old versions temporarily

Container Security

Docker Security

  • Use official and verified images
  • Distroless images for minimal attack surface
  • Multi-stage builds for small images
  • Do not run as root: USER directive
  • Scan vulnerabilities: Trivy, Clair, Snyk
  • Read-only filesystems when possible
  • .dockerignore to not include secrets

Kubernetes Security

  • Strict RBAC (Role-Based Access Control)
  • Network policies to segment traffic
  • Pod Security Standards/Admission
  • Secrets in etcd encrypted
  • Service mesh (Istio, Linkerd) for mTLS
  • Falco for runtime threat detection

Security Logging and Monitoring

What to Log

  • Authentication attempts (successful and failed)
  • Authorization failures
  • Input validation failures
  • API abuse (rate limiting triggers)
  • Changes in permissions/roles
  • Administrative actions

What NOT to Log

  • Passwords
  • Tokens or API keys
  • Full credit cards
  • Sensitive PII without masking

SIEM and Alerting

  • SIEM: Splunk, Elastic Security, Sumo Logic
  • Real-time alerts for critical events
  • Event correlation
  • Security dashboards

Security Testing

SAST (Static Application Security Testing)

  • Source code analysis
  • Tools: SonarQube, Checkmarx, Semgrep
  • Integrate in IDE and CI/CD
  • False positives require tuning

DAST (Dynamic Application Security Testing)

  • Runtime application testing
  • Black box testing
  • Tools: OWASP ZAP, Burp Suite, Acunetix
  • Automated scanning in staging

Penetration Testing

  • Manual testing by experts
  • At least annually
  • After major architectural changes
  • Bug bounty programs for continuous testing

Compliance and Regulations

GDPR (Europe)

  • Right to be forgotten
  • Data portability
  • Privacy by design
  • Breach notification within 72 hours

PCI DSS (Payment Card Industry)

  • Required if processing credit cards
  • Better to use Stripe/PayPal to avoid PCI scope
  • Never store CVV
  • Card tokenization

Security Checklist for Launch

Pre-deployment

  • HTTPS configured correctly
  • Security headers implemented
  • Secrets in vaults, not in code
  • Dependencies updated, no critical vulnerabilities
  • SAST and DAST executed
  • Penetration testing completed
  • Rate limiting on APIs
  • Logging and monitoring configured
  • Backup and disaster recovery plan

Post-deployment

  • Active log monitoring
  • Alerts configured
  • Incident response plan documented
  • Continuous security scanning
  • Regular security updates

Conclusion

Security is an ongoing process, not a state. Threats evolve constantly and require permanent vigilance.

Implementing all these measures may seem overwhelming, but the key is to prioritize: start with the fundamentals (HTTPS, robust authentication, input validation) and build upon that foundation.

At Brixato, security is a priority from design. Every feature includes security considerations, we run automated testing on every commit, and maintain a continuous update program. Security is not just the responsibility of the security team - it is everyone's responsibility.