If you run any product that touches personal information, you need a real plan to keep user data safe from hackers, not just a checkbox compliance policy. The threat landscape has shifted fast: breach costs, attacker sophistication, and the sheer number of incidents have all climbed in the last two years, and the organizations getting hit hardest are usually the ones that treated security as an afterthought rather than a design requirement.
The numbers make the stakes clear. The global average cost of a data breach now sits around $4.44 million, and in the United States that figure climbs past $10 million per incident. Breaches that take longer than 200 days to contain cost noticeably more than those caught early, which means detection speed is not a nice-to-have; it is one of the biggest levers you have over your own exposure. Meanwhile, more than a third of breaches now originate through a vendor or third-party integration rather than a direct attack on the core product, and AI-assisted phishing is expected to account for a large share of intrusions by the end of the year. None of this is meant to scare you into paralysis. It is meant to explain why the practices below matter more now than they did five years ago.
Encrypt Data at Rest and in Transit
Encryption is the baseline, not the finish line. Data in transit should run over TLS 1.2 or higher everywhere, including internal service-to-service calls that teams often skip because "it's just internal traffic." Data at rest deserves the same discipline: database-level encryption, encrypted backups, and encrypted object storage buckets close off an entire category of attacks where a leaked credential or misconfigured storage bucket would otherwise hand over plaintext records.
A common mistake is treating encryption as something you can bolt on later. Retrofitting encryption into a schema that already has millions of plaintext rows is painful and error-prone, so it is worth building this in from day one, even for an early-stage product with a small user base. Cloud providers like AWS, Google Cloud, and Azure now offer encryption at rest by default for most managed services, but default settings are not the same as verified settings. Audit them.
Hash and Salt Passwords Properly
Storing passwords is one of the few places where getting the implementation detail wrong can single-handedly turn a minor breach into a catastrophic one. Plaintext and even simple MD5 or SHA-1 hashes are not acceptable for password storage; both can be reversed at scale using modern hardware. The standard today is a slow, memory-hard hashing algorithm such as bcrypt, scrypt, or Argon2, combined with a unique salt per user so that identical passwords do not produce identical hashes.
Here is a minimal example using bcrypt in Node.js, which handles salting automatically:
const bcrypt = require('bcrypt');
const saltRounds = 12;
async function hashPassword(plainTextPassword) {
const hash = await bcrypt.hash(plainTextPassword, saltRounds);
return hash;
}
async function verifyPassword(plainTextPassword, storedHash) {
const isMatch = await bcrypt.compare(plainTextPassword, storedHash);
return isMatch;
}
The saltRounds value controls how computationally expensive each hash operation is. Raising it slows down both legitimate logins and brute-force attempts, so it should be tuned against your server's actual hardware rather than copied blindly from a tutorial. If you are building in Python, argon2-cffi offers similar protection with Argon2, which won the Password Hashing Competition and is generally recommended for new systems over bcrypt where the library ecosystem supports it.
Enforce Multi-Factor Authentication
Passwords alone are no longer a sufficient gate, even well-hashed ones, because credential stuffing and phishing continue to be the most common way attackers get in. Security researchers have found that the overwhelming majority of breaches, often cited between 77% and 95%, still trace back to human error or manipulation rather than a novel technical exploit. Multi-factor authentication directly addresses this by requiring a second proof of identity, whether that's a time-based one-time code, a push notification, or a hardware security key.
Rolling out MFA does not have to mean forcing it on every user immediately. A staged approach works well: require it for admin and privileged accounts first, since those carry the most damage potential if compromised, then extend it to all users with a grace period and clear in-product messaging about why it matters. Support for FIDO2 and WebAuthn has matured enough that passkeys are now a realistic option for consumer products, and they remove the phishing risk entirely since there is no shared secret for an attacker to steal.
Apply the Principle of Least Privilege
Every account, service, and API key in your system should have exactly the permissions it needs and nothing more. This sounds obvious, but in practice, permissions creep over time as teams grant broad access to move faster and never revisit it. A support engineer who needs to view account status does not need write access to the billing database. A microservice that reads inventory data does not need permission to delete user records.
Role-based access control (RBAC) and, for more complex systems, attribute-based access control (ABAC) give you a structured way to enforce this instead of relying on ad hoc decisions made under deadline pressure. Regular access reviews, ideally automated and run quarterly at minimum, catch the accounts that accumulated permissions they no longer need, including former employees and deprecated service accounts that were never fully decommissioned.
Patch and Update Continuously
Unpatched software remains one of the most exploited entry points, largely because attackers automate the search for known vulnerabilities in outdated dependencies, and that automation moves faster than most manual patch cycles. A dependency scanning tool integrated into your CI pipeline, such as Dependabot, Snyk, or Renovate, flags vulnerable packages before they ship rather than after an incident response team finds them during a post-mortem.
Patch management extends beyond application code to the infrastructure layer: operating systems, container base images, and third-party libraries baked into your build all need a defined update cadence. Teams that treat patching as a monthly maintenance chore instead of a continuous process tend to be the ones still running vulnerable versions six months after a CVE was published and publicly disclosed.
Monitor, Log, and Have an Incident Response Plan
You cannot respond to what you cannot see. Centralized logging across application servers, databases, and authentication systems, paired with anomaly detection, is what turns a breach from a months-long undetected compromise into a same-day catch. The data backs this up directly: incident response plans are consistently cited as one of the single largest cost reducers in breach economics, saving organizations millions per incident simply because the team already knows who does what in the first hour.
A workable incident response plan does not need to be a hundred-page document. It needs clear ownership of who declares an incident, a communication chain that does not depend on one person being reachable, and a tested process for isolating affected systems without destroying forensic evidence. Run a tabletop exercise at least once a year. Teams that have practiced a breach scenario respond meaningfully faster than teams encountering the process for the first time during a real one.
Vet Third-Party Vendors and Integrations
Supply chain risk has grown into one of the most significant blind spots in modern security programs, with vendor and third-party compromises now behind a substantial share of all breaches. Every SaaS tool, API integration, and outsourced service that touches user data extends your attack surface, whether or not your own code changes at all.
Before integrating a new vendor, ask for their SOC 2 report or equivalent attestation, review what data they actually need versus what they're requesting, and scope API keys and permissions as narrowly as the integration allows. This vetting process should not stop after signing the contract. Vendors get breached too, and your incident response plan should account for the scenario where the compromise originates outside your own infrastructure entirely.
Building Security Into the Culture, Not Just the Stack
Tools and configurations matter, but they only work if the people building and operating the product treat security as part of the job rather than a separate team's problem. That means code review that actually checks for security issues, not just style, and it means giving engineers the context to understand why a control exists instead of just enforcing it as a rule handed down from above.
Keeping user data safe from hackers is not a project with an end date. It is an ongoing practice that adjusts as attackers change tactics and as your own product surface grows. The organizations that handle this well are rarely the ones with the biggest security budgets; they are the ones that built encryption, access control, and monitoring into their default way of shipping software, so that protecting user data is simply what building the product looks like.
Top comments (1)
Security can never be overemphasized. True, and “do not be ignorant of the devices of the enemy.” This is a different ball game, not just for backend developers but even for frontend engineers. I enjoyed reading.