Don't trust input
Any data from outside is potentially unsafe. This includes not only forms and HTTP requests, but also files, headers, cookies, command line arguments, and even database content.
• Validate all input: by type, length, value range, and format.
• Use a whitelisting approach - allow only clearly acceptable values.
• When working with JSON, use validators: Ajv, Joi, zod, and similar.
Control the output
(XSS) XSS remains one of the most common vulnerabilities in web applications. Any output of user data in HTML must be safe.
• Escape all user data before displaying.
• Avoid using innerHTML, attributes, and inline scripts to insert data.
• Implement Content Security Policy (CSP) to restrict the execution of unauthorized code.
Errors and Logs
Verbose error messages are useful during development, but can be a source of information leaks for attackers.
• Disable verbose error messages in production.
• Exclude sensitive data from logs: passwords, tokens, access keys.
• Log enough for diagnostics, but nothing that can help an attacker.
Store secrets properly
Secrets are not only passwords, but also API keys, tokens, configuration data, and connections.
• Never store secrets in source code or .env files under version control.
• Use specialized secrets management systems: HashiCorp Vault, AWS Secrets Manager, Doppler, and others.
• Encrypt secrets both at rest and in transit.
Minimize the attack surface
The fewer open entry points, the harder it is to hack the system.
• Remove unused endpoints and dev tools before release.
• Implement access control by roles and privilege levels.
• Hide internal APIs and administrative interfaces behind authentication and network filters.
Update dependencies
Vulnerabilities often penetrate through third-party libraries, even if your own code is written securely.
• Set up automatic updating and monitoring of dependencies.
• Use tools like npm audit, pip-audit, Snyk, Renovate.
• Pay attention to transitive dependencies and the reputation of sources.
Separate authentication and authorization
Authentication answers the question of who you are, and authorization - what you are allowed to do. Both aspects are critical.
• Perform all access rights checks on the server side.
• Do not rely on client logic to restrict access.
• Use access control models: RBAC, ABAC — depending on the complexity of the project.
Avoid homemade cryptography
Cryptography is an area where “writing it yourself” almost always means creating a vulnerability.
• Use proven libraries and protocols.
• Do not generate keys or tokens manually, especially using unreliable generators (Math.random(), rand(), etc.).
• Use standardized solutions for authentication and authorization: OAuth, OpenID Connect, JWT (with proven implementations).
Security is not a brake on development, but rather the protection of your time, budget, and reputation. Typical vulnerabilities rarely arise due to malicious actions — much more often they appear due to haste, habit, or lack of basic code hygiene. Invest in security at the development stage — and this will save you many problems in the future.
