Security Best Practices for Web and Mobile Applications

10/8/2025Forgeora Team
Security Best Practices for Web and Mobile Applications

Protecting user data and preventing common vulnerabilities—OWASP Top 10, authentication hardening, and secure API design.

Security is not a feature to add at the end—it is a property that must be designed into every layer of an application. Security failures erode user trust irreparably, carry regulatory penalties, and can be existential for early-stage products. This guide covers the most impactful security practices for web and mobile applications, anchored in the OWASP Top 10 vulnerabilities and modern authentication standards. ## Authentication Hardening Authentication is the front door. Mistakes here are catastrophic. **Never store plaintext passwords**: Use bcrypt, Argon2id, or scrypt for password hashing. Argon2id is the current OWASP recommendation. Configure memory, iteration, and parallelism parameters to make brute force impractical on modern hardware (target >100ms hash time on your server). **Implement Multi-Factor Authentication (MFA)**: TOTP-based MFA (Google Authenticator, Authy) is the baseline. For higher-security contexts, hardware security keys (WebAuthn/FIDO2) are phishing-resistant and increasingly user-friendly. **Passkeys (WebAuthn)**: Passkeys replace passwords with cryptographic key pairs stored in the user's device or password manager. They are phishing-resistant by design (the key is bound to the website origin), can't be leaked in a database breach (only the public key is stored server-side), and provide a better UX than passwords. Passkeys should be your target authentication architecture for new products. **Session Management**: Use cryptographically random, high-entropy session tokens (128+ bits). Set `HttpOnly` and `Secure` cookie flags. Implement session expiration (idle timeout + absolute lifetime). Provide users with a mechanism to view and terminate active sessions. **Rate Limiting**: Protect authentication endpoints from credential stuffing and brute force. Implement progressive lockout (increasing delays after failed attempts) at the account level, not just IP level. Use Cloudflare Turnstile or hCaptcha for bot detection on login/signup forms. ## Injection Prevention **SQL Injection**: Use parameterized queries or an ORM that handles parameterization automatically. Never concatenate user input into SQL strings. Validate and whitelist input types. Principle of least privilege on database users—the application's DB user should not have DROP or DDL privileges. **XSS (Cross-Site Scripting)**: React and Vue escape output by default—don't use `dangerouslySetInnerHTML` (React) or `v-html` (Vue) with untrusted content. Implement a strict Content Security Policy (CSP) that prevents inline scripts and restricts script sources to known origins. Use the Trusted Types API for DOM XSS prevention. **CSRF (Cross-Site Request Forgery)**: For cookie-based sessions, implement CSRF tokens for state-changing requests. For API-based authentication with JWT in Authorization headers (not cookies), CSRF is not applicable—the browser won't automatically send the header cross-origin. ## API Security **Authentication**: Every API endpoint that accesses user data or performs actions must require authentication. JWTs should be validated server-side: verify the signature (never use the `none` algorithm), check expiration, and validate the `aud` and `iss` claims. **Authorization**: Authentication confirms identity; authorization confirms permission. Implement row-level security to prevent users from accessing other users' data. Never trust client-provided resource IDs without verifying the authenticated user has permission to access that resource. **Input Validation**: Validate all inputs server-side. Define allowed types, formats, lengths, and ranges. Reject requests that don't conform. Client-side validation improves UX but provides no security guarantee. **Rate Limiting and Throttling**: Protect all API endpoints, not just authentication. Implement per-user and per-IP rate limiting. Use response codes consistently: 429 Too Many Requests with a `Retry-After` header. ## HTTPS and Transport Security **Enforce HTTPS**: Use HSTS (HTTP Strict Transport Security) with a long max-age (at least 1 year) and `includeSubDomains`. Submit your domain to the HSTS preload list for the strongest protection. **TLS Configuration**: Use TLS 1.2+. Disable TLS 1.0 and 1.1. Use strong cipher suites. Regularly test your TLS configuration with SSL Labs' server test. **Certificate Pinning (Mobile)**: On mobile, certificate pinning rejects connections to servers that don't present the expected certificate, preventing man-in-the-middle attacks even when the device's CA store is compromised. Implement with care—pinning failures prevent your app from connecting if the certificate changes unexpectedly. Use backup pins and a fallback mechanism. ## Dependency Security **Software Composition Analysis (SCA)**: Run `npm audit`, Snyk, or Dependabot on every dependency update. Third-party packages are a major attack vector (supply chain attacks). Review critical dependency updates manually. **Minimize Dependencies**: Every dependency you add is an attack surface. Evaluate whether a package provides enough value to justify its security risk. Prefer packages with active maintenance, broad adoption, and security audits. ## Mobile-Specific Security **Data Storage**: Never store sensitive data (passwords, tokens, PII) in plaintext on the device. Use the iOS Keychain and Android Keystore for cryptographic keys and tokens. Use file-level encryption for locally stored user data. **Certificate Pinning and Anti-Tampering**: Verify app integrity to detect modified APKs or rooted/jailbroken devices. Tools like Google's SafetyNet/Play Integrity and Apple's DeviceCheck provide attestation signals. **Obfuscation**: Obfuscate mobile code (ProGuard for Android, SwiftShield for iOS) to raise the cost of reverse engineering your app's logic and API communication.