Security work begins by asking what must be protected and who can influence it. A browser, API gateway, application server, database, worker, and third-party service have different trust assumptions. Data crosses those boundaries; authority crosses them too.
Model the path before choosing controls
List assets such as credentials, personal data, payment state, and signing keys. Identify entry points and trust boundaries. Ask what an attacker can control, what the attacker wants, and which action would cause harm. A threat model is a working set of assumptions, not a guarantee that every attack has been found.
Authentication answers who is making a request; authorization answers whether that identity may perform this action on this resource. Check authorization at the server boundary for every protected operation. Hiding a button in the interface is not access control.
Handle secrets and untrusted input correctly
Passwords should not be stored as plaintext or protected with a fast general-purpose hash. Use a password-hashing function designed to slow guessing, with a unique salt and parameters appropriate to the system. TLS protects data between connection endpoints but does not protect data after it reaches an application or a terminating proxy.
Input validation helps ensure data matches the expected shape, but output encoding or context-appropriate sanitization is still needed to prevent injection vulnerabilities. For web output, encode according to whether data is placed in HTML text, an attribute, a URL, CSS, or JavaScript. Avoid treating a web application firewall as a substitute for fixing unsafe output handling.
Design for containment
Use least privilege for users and services, rotate and scope secrets, log security-relevant events without logging credentials, and limit the blast radius of a compromised component. Test controls at the boundary where the system enforces them.
The OWASP Password Storage Cheat Sheet and XSS Prevention Cheat Sheet give practical, maintained implementation guidance.