The security failures that hurt business web applications are mostly basic ones: users can reach data that isn't theirs, the server is misconfigured, a dependency is out of date, or a secret has leaked. Fix those first. Check permissions on the server for every request, use a well-maintained login system with multi-factor authentication, keep secrets out of code, update dependencies on a schedule, log security events where an attacker can't delete them, and test restoring your backups. The OWASP Top 10:2025 is the checklist to work from.
The OWASP Top 10:2025, in plain terms
The OWASP Top 10 is a widely used list of web application risks, published by the Open Worldwide Application Security Project. The current edition is 2025. Here is what each item means for a typical business application:
| ID | Risk | What it looks like in practice |
|---|---|---|
| A01 | Broken Access Control | Change /invoices/1041 to /invoices/1042 and see another customer's invoice |
| A02 | Security Misconfiguration | Debug mode in production, default admin passwords, an open storage bucket |
| A03 | Software Supply Chain Failures | A compromised or abandoned package in your dependencies or build pipeline |
| A04 | Cryptographic Failures | Personal data sent or stored unencrypted, weak password hashing |
| A05 | Injection | SQL or script built by joining user input into a string |
| A06 | Insecure Design | A password reset flow that can be abused however carefully it is coded |
| A07 | Authentication Failures | No rate limit on login, no MFA, sessions that never expire |
| A08 | Software or Data Integrity Failures | Unsigned updates, trusting data from the client that should be checked |
| A09 | Security Logging and Alerting Failures | A breach nobody notices for months because nothing was logged or watched |
| A10 | Mishandling of Exceptional Conditions | Errors that leak stack traces, or failures that leave access open instead of closed |
Two changes from the 2021 edition matter to business owners. The old "vulnerable and outdated components" item has widened into software supply chain failures, which reflects how much of any application is third-party code and build tooling. And mishandling of exceptional conditions is new: an application that fails badly can be as risky as one with a bug.
Access control: the one to get right first
Broken access control has stayed at the top of the list since 2021, and custom business software is especially exposed to it. The cause is usually simple: the interface hides a button, but the server never checks whether this user may do this to this record.
- Check permissions on the server, on every request, for the specific record, not only for the page.
- Deny by default. A new endpoint should be closed until someone decides who may use it.
- Put tenant and customer filtering in one shared place in the code, not in each query. Multi-tenant apps need this most; see multi-tenant SaaS architecture basics.
- Write automated tests that log in as user A and try to read user B's data.
Authentication and sessions
Don't write your own login system. Use your framework's built-in authentication or an established identity provider, and configure it well:
- Passwords. Follow NIST SP 800-63B: prefer length over complexity rules, check new passwords against lists of breached passwords, and don't force regular password changes without a reason. Hash with a slow algorithm such as Argon2 or bcrypt.
- Multi-factor authentication. Require it for staff and administrators at least. Offer passkeys where you can; they resist phishing in a way that SMS codes do not.
- Rate limits. Limit login, password reset and OTP attempts per account and per IP address.
- Sessions. Use cookies marked
Secure,HttpOnlyandSameSite. Issue a new session ID at login, expire idle sessions, and let users sign out of all devices. - Tokens for APIs. Keep them short-lived, scoped to what the client needs, and revocable.
If your application is built on or next to Odoo, much of this is already there. In Odoo 19 Community, auth_totp adds two-factor authentication, auth_passkey adds passkeys, and auth_password_policy sets a minimum password length, all available to portal users as well as staff. Switch them on rather than building your own.
Secrets, dependencies and configuration
Secrets
API keys, database passwords and signing keys belong in environment variables or a secrets manager, never in the repository. Give each environment its own secrets, so a leaked staging key doesn't open production. Add a secret scanner to the repository, and when a secret does leak, rotate it at once: deleting the commit is not enough.
Dependencies
Most of your application's code comes from packages. Commit the lock file, turn on automated alerts for vulnerable packages (Dependabot, npm audit, pip-audit or similar), and set a regular time to apply updates rather than waiting for a crisis. Before adding a package, check that it is maintained, and remove packages you no longer use.
npm audit --omit=dev pip-audit -r requirements.txt
Configuration
Serve everything over HTTPS with HSTS. Turn off debug mode and detailed error pages in production. Set security headers, especially a Content Security Policy. Close every port you don't need, keep admin interfaces off the public internet, and remove default accounts.
Logging, monitoring and backups
Log the events that matter for security: logins and failed logins, password and MFA changes, permission changes, data exports and administrator actions. Send the logs to a separate system that the application server cannot delete from, and set alerts for patterns such as many failed logins. Don't log passwords, tokens or full card numbers.
In India, the CERT-In directions of April 2022 require covered organisations to report certain cyber incidents within six hours of noticing them and to keep ICT system logs for a rolling 180 days within India. Personal data also falls under the Digital Personal Data Protection Act, 2023. Check with your legal adviser which duties apply to you, and design your logging to meet them from the start.
Backups only count if you can restore them. Keep copies in a separate account or location from production, keep at least one copy that ransomware on the server cannot change, encrypt them, and test a full restore on a schedule. Know how much data you can afford to lose and how long you can be down, and set backup frequency to match.
A backup you have never restored is a hope, not a backup.
A launch checklist
- Access control. Server-side checks on every endpoint, tested with two users trying to read each other's data.
- Authentication. Established login system, MFA for staff and admins, rate limits, secure session cookies.
- Input and output. Parameterised queries or an ORM everywhere, output escaping by default, file uploads checked and stored outside the web root.
- Secrets. None in the repository, separate secrets per environment, a plan to rotate them.
- Dependencies. Lock file committed, vulnerability alerts on, an owner for updates.
- Configuration. HTTPS and HSTS, debug off, security headers, admin interfaces not public.
- Logging. Security events logged to a separate store with alerts.
- Backups. Encrypted, off-site, one unchangeable copy, and a restore tested.
- Incident plan. Who is called, who decides, and who tells customers and regulators.
None of this needs a large security budget. It needs someone to own it before launch and to check it again after each major release. If you would like us to review an application against this list, or to build one that starts with it, see our web application work or contact us.
Questions we get asked
What is the latest OWASP Top 10?
The current edition is the OWASP Top 10:2025. It lists Broken Access Control, Security Misconfiguration, Software Supply Chain Failures, Cryptographic Failures, Injection, Insecure Design, Authentication Failures, Software or Data Integrity Failures, Security Logging and Alerting Failures, and Mishandling of Exceptional Conditions. Compared with the 2021 edition, supply chain failures replace the narrower outdated components item, and mishandling of exceptional conditions is new.
What is the most common web application vulnerability?
Broken access control, which is A01 in the OWASP Top 10:2025. It happens when the server does not check whether the logged-in user may see or change a particular record, so changing an ID in a URL or API request exposes someone else's data. Checking permissions on the server for every request and testing with two separate users prevents most of it.
Where should a web application store API keys and passwords?
In environment variables or a dedicated secrets manager, never in the source code or repository. Each environment, such as staging and production, should have its own secrets so one leak does not expose everything. Scan the repository for committed secrets, and if a secret leaks, rotate it immediately, because removing it from the code history does not make it safe again.
How often should web application backups be tested?
Test a full restore on a regular schedule and after any major change to the database or hosting, not only when something goes wrong. Base the backup frequency on how much data the business can afford to lose. Keep copies away from the production account, encrypt them, and keep at least one copy that an attacker on the server cannot change or delete.