Web app security basics for small businesses: a practical checklist
By Lal Chand, founder of Codic Systems
Published Last updated 6 min read
Small businesses often assume security is for banks. Then a customer list leaks, a form is used to send spam, or someone finds an admin page that anyone can open.
You don't need a security team to avoid most of that. You need to get the basics right and keep them right. The best map I know is the OWASP Top 10, a list of the most critical web application risks. The 2025 edition has these ten, in this order:
- 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
- Mishandling of Exceptional Conditions
I've built systems for healthcare, government and certificate verification, where these matter a lot. Here is how I'd translate the list into a checklist you can use.
1. Check access on the server, every time
Broken access control is first on the list. It means people can see or do things they shouldn't: reading someone else's record, opening an admin page or changing a price.
The classic mistake is hiding a button. If a regular user can't see "Delete", that doesn't stop them sending the delete request directly. The server has to ask, on every request: who is this, and are they allowed to do this to this record?
Checklist:
- Every request checks the user's role on the server.
- Users can only open their own records unless there's a reason.
- Admin pages require an admin login. An unlisted URL is not protection.
- Test it: log in as an ordinary user and try the admin addresses.
2. Get the configuration right
Security misconfiguration is second. It's the unglamorous category: debug mode left on, default passwords, a directory listing open, a test page nobody deleted.
Checklist:
- Debug and error details are off in production.
- Default accounts are removed or have new passwords.
- The server sends sensible security headers.
- Unused features, pages and sample files are deleted.
- Only the ports and services you need are reachable.
3. Know what your software depends on
Software supply chain failures cover the code you didn't write: libraries, plugins, build tools. If one is compromised or out of date, your site is too.
Composer's documentation explains the lock file well: with composer.lock committed, everyone who installs the project gets the exact same dependency versions. That makes your build repeatable, and makes a surprise change visible.
Checklist:
- Commit your lock files.
- Remove plugins and packages you don't use.
- Update dependencies on a schedule, not only when something breaks.
- Use the runtime versions that still receive security fixes.
4. Protect data in storage and transit
Cryptographic failures include sending data without encryption and storing things like passwords badly.
Checklist:
- The whole site runs over HTTPS.
- Passwords are stored as slow, salted hashes, never in plain text.
- Collect only the personal data you need.
- Backups are encrypted and you've tested restoring them.
5. Never build queries from user input
Injection is when user input is treated as instructions. The best-known case is SQL injection: someone types a piece of database command into a form field, and your app runs it.
The fix is old and reliable. Use prepared statements, also called parameterised queries, so input is always treated as data and never as part of the command. The same principle applies to shell commands and to anything that builds code from text.
Checklist:
- Database queries use parameters.
- Input is validated for type, length and format.
- Output shown on a page is escaped.
6. Think about abuse before you build
Insecure design is about problems no amount of careful coding fixes, because the design allowed them. A certificate lookup that accepts sequential numbers lets anyone walk through the whole register. A password reset that reveals whether an email exists helps attackers.
Ask early: how could someone misuse this? Then limit it. Rate limits, unguessable identifiers and clear rules about who may do what are design decisions.
7. Make logins hard to attack
Authentication failures cover weak passwords, missing lockouts and poor session handling.
Checklist:
- Limit repeated login attempts.
- Offer or require two-step verification for admin accounts.
- Sessions end after sensible periods and on logout.
- Reset links expire and work once.
8. Trust, but verify what you install and deploy
Software and data integrity failures include accepting updates or data without checking they're genuine. For a small business, the practical version is about your deployment pipeline.
If a deploy key leaks, someone else can ship code to your live site. GitHub's guidance on secrets in Actions is a good start: store them as encrypted secrets, scope them narrowly, pass them as environment variables and never print them, since GitHub doesn't redact secrets that appear in logs.
Checklist:
- Deployment credentials only have access to what they need.
- Secrets live in the secrets store, not in the repository.
- Only trusted people can change the deployment setup.
9. Keep logs, and look at them
Logging and alerting failures mean something went wrong and nobody knew. Failed logins, unexpected errors and changes to sensitive records should leave a trace, and someone should see it.
Checklist:
- Log logins, failed logins and important changes, with time and user.
- Keep personal data and secrets out of logs.
- Send serious errors to a person, by email or chat.
- Check that alerts still fire. A silent alert system looks identical to a healthy one.
10. Fail safely
Mishandling of exceptional conditions is the newest entry in the list. It's about what happens when things go wrong: an external service is down, an input is odd, a file is missing. Systems that crash into an open state, or leak details in an error page, help attackers.
Checklist:
- When a check can't be completed, the answer is no, not yes.
- Error pages say something helpful to users without exposing internals.
- External calls have timeouts and a plan for failure.
How to use this
Don't try to fix everything at once. Pick the top three for your app, probably access control, configuration and dependencies, and do those properly. Then schedule a review every few months.
If you'd like a second pair of eyes, a short audit of an existing system is something I do through Codic Systems. And if you do it yourself, the OWASP page is a good place to go deeper.
Security isn't a feature you add at the end. It's a set of small habits applied consistently, and most of them cost little.
Questions this article answers
What is the OWASP Top 10?
A widely used list of the most critical web application security risks, published by the Open Worldwide Application Security Project. The current edition is OWASP Top 10:2025.
What is the number one web security risk?
In the 2025 edition it is broken access control: users being able to do or see things they should not.
Is hiding a button the same as restricting access?
No. Hiding a button only changes what the screen shows. Access has to be checked on the server for every request.
How do you prevent SQL injection?
Use prepared statements, also called parameterised queries, so user input is never treated as part of the query itself.
Where should API keys and passwords be stored?
In environment variables or a secrets manager, never in the repository, and never printed to logs.