Your login isn’t secure if you store secrets in plain sight
TL;DR: Never store or compare plain-text passwords
Problems 😔
- Data exposure
- Weak security
- User trust loss
- Compliance issues
- Easy exploitation
- Authentication bypass potential
Solutions 😃
- Hash user passwords
- Use strong algorithms
- Salt every hash
- Compare hashes safely
- Secure your database
- Perform regular penetration tests
Context 💬
When you store or compare passwords as plain-text, you expose users to unnecessary risk.
A data breach will instantly reveal every credential.
Attackers can reuse these passwords on other sites. Even internal logs or debugging can leak sensitive data.
You must treat passwords as secrets, not as values to display or compare directly.
Sample Code 📖
Wrong ❌
// Borrowed from "Beyond Vibe Coding"
app.post('/login', async (req, res) => {
const { username, password } = req.body;
const user = await Users.findOne({ username });
if (!user) return res.status(401).send("No such user");
if (user.password === password) {
res.send("Login successful!");
} else {
res.status(401).send("Incorrect password");
}
});
Right 👉
import bcrypt from 'bcrypt';
app.post('/login', async (req, res) => {
const { username, password } = req.body;
const user = await Users.findOne({ username });
if (!user) return res.status(401).send('Invalid credentials');
const valid = await bcrypt.compare(password, user.password);
if (!valid) return res.status(401).send('Invalid credentials');
res.send('Login successful');
});
Detection 🔍
- Semi-Automatic
You can detect this smell when you see passwords handled as raw strings, compared directly with ===, or stored without hashing.
Static analyzers and linters can catch unsafe password handling, but code reviews remain the best defense.
Tags 🏷️
- Security
Level 🔋
- Beginner
Why the Bijection Is Important 🗺️
In the MAPPER, passwords represent sensitive user credentials that must remain confidential.
The bijection breaks when you store passwords as plain-text because real-world security expectations don’t match your system’s actual protection.
Users trust you to protect their credentials.
When you store plain-text passwords, you create a false representation where the system appears secure but actually exposes sensitive data.
This broken mapping between user expectations and system reality leads to security breaches and loss of trust.
When you design your authentication system, you create a mapping between a MAPPER concept — a “user’s identity” — and your program’s data.
Hashing preserves that bijection safely.
When you break it by storing raw passwords, your system represents users incorrectly: it turns their private identity into an exposed string.
That breaks trust and control.
AI Generation 🤖
AI code generators sometimes create login examples comparing plain-text passwords.
The code sample is from the book Beyond Vibe Coding in the chapter about “8. Security, Maintainability, and Reliability”.
These examples look simple, but they spread insecure habits.
You must always validate and adapt AI-generated authentication code.
AI Detection 🧲
AI tools can detect this smell when you provide context about security requirements.
They recognize patterns of plain-text password comparison and can suggest proper hashing implementations.
You need to ask AI to review the authentication code for security vulnerabilities to get comprehensive fixes.
Try Them! 🛠
Remember: AI Assistants make lots of mistakes
Suggested Prompt: Refactor this login code to securely hash and compare passwords
| Without Proper Instructions | With Specific Instructions |
|—-|—-|
| ChatGPT | ChatGPT |
| Claude | Claude |
| Perplexity | Perplexity |
| Copilot | Copilot |
| You | You |
| Gemini | Gemini |
| DeepSeek | DeepSeek |
| Meta AI | Meta AI |
| Grok | Grok |
| Qwen | Qwen |
Conclusion 🏁
Plain text passwords are a trap.
You make your users unsafe and invite catastrophic leaks. You must always hash, salt, and compare securely.
The fix is simple, and the trust you earn is priceless.
Relations 👩❤️💋👨
https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xxxviii
https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xx-we-have-reached-100
https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xliii
https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xxxiv?embedable=true
https://hackernoon.com/code-smell-258-the-dangers-of-hardcoding-secrets
https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xxxiv?embedable=true
https://hackernoon.com/code-smell-284-encrypted-functions?embedable=true
More Information 📕
https://learning.oreilly.com/library/view/beyond-vibe-coding/9798341634749/ch08.html?embedable=true
Disclaimer 📘
Code Smells are my opinion.
If you think technology can solve your security problems, then you don’t understand the problems and you don’t understand the technology.
Bruce Schneier
https://hackernoon.com/400-thought-provoking-software-engineering-quotes?embedable=true
This article is part of the CodeSmell Series.
https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-i-xqz3evd?embedable=true