Cybersecurity Basics Every Developer Must Know
Simple security practices that can protect your apps and your users, most of which take minutes to actually apply once you know they matter.
Most breaches don't come from a genius hacker running some sophisticated exploit you couldn't have predicted. They come from basics that got skipped under deadline pressure, the kind of shortcut that felt harmless at 11pm the night before launch. These are the ones worth never skipping, no matter how tight the timeline gets, and understanding why each one matters makes it far easier to actually remember to do them.
Don't trust the browser
Anything checked client-side can be bypassed by anyone who opens their browser's dev tools, which takes about ten seconds. A form that only validates a required field in JavaScript is not validating anything at all as far as an attacker is concerned. Validate and sanitize every input again on the server, no matter how well-behaved your frontend looks or how careful your form validation seems. Treat every request hitting your backend as if it came from someone who deliberately skipped your frontend entirely, because eventually, someone will.
Keep secrets out of your code
API keys and database credentials belong in environment variables, never in a committed file, and definitely never in a public repository "just for now." A key pushed to a public GitHub repo gets found and abused within minutes, not days, there are automated bots scanning public commits around the clock specifically looking for exactly this pattern. If you've ever accidentally committed a secret, rotating that key immediately matters more than quietly deleting the commit, because the key is already compromised the moment it's pushed, deleted history or not.
Hash passwords properly
Use a hashing algorithm actually built for passwords, like bcrypt or argon2, not a generic hash function borrowed from a tutorial or a quick Stack Overflow answer. Generic hashes like plain SHA-256 are fast, which sounds good until you realize that speed is exactly what makes them easy for an attacker to brute-force at scale. Password hashing algorithms are deliberately slow, on purpose, to make that kind of attack impractical. If your database ever leaks, and eventually most systems do get tested somehow, this single decision is the difference between a manageable incident and a genuine disaster for every user who trusted you with their password.
Turn on HTTPS and basic security headers
Enforce HTTPS everywhere, and add Content-Security-Policy and X-Frame-Options headers while you're at it. Most modern frameworks make this a few lines of configuration, there's rarely a good reason to skip it, and it closes off a surprising number of common attacks for very little effort. Without HTTPS, anyone on the same network as your user, a shared café wifi, a compromised router, can potentially read or alter the traffic between your app and its users. This isn't a theoretical risk in places where public wifi is common and often poorly secured.
Keep your dependencies updated
A large share of real-world breaches trace back to a known, already-patched vulnerability sitting in an outdated package nobody got around to updating. The vulnerability isn't a mystery to attackers, it's usually published publicly the moment a fix ships, which means outdated software is effectively a public list of known weak points. Run your project's dependency audit tool regularly, not just when something already broke and you're scrambling to figure out why.
Rate limit anything that touches authentication
Login forms, password reset endpoints, and OTP verification should all have rate limits. Without one, an attacker can simply try thousands of password guesses per minute against a single account until something works. A basic rate limit, locking an account or slowing responses after a handful of failed attempts, closes this off almost entirely, and it's usually a small addition to code you've already written.
Log enough to actually investigate an incident, but not too much
When something does go wrong, and eventually something will, the difference between a quick fix and a drawn-out crisis is usually whether you have enough logs to understand what actually happened. At the same time, logging sensitive data like full card numbers or plaintext passwords turns your logs themselves into a liability. Log what you'd need to reconstruct an incident, and deliberately keep sensitive fields out of it.
Security isn't a feature you bolt on at the end. It's a habit you keep from the first commit.
Try this today
Run your project's dependency audit command right now and fix whatever it flags as high severity. Don't wait for a reminder from something worse.
Enjoyed this article?
Get practical tech tips and African tech news straight to your inbox. No spam, unsubscribe anytime.
Subscribe to Techmin