What are best practices for handling sensitive data?
SecurityThe short answer
Never store sensitive data in client-side code (JavaScript, localStorage, or HTML). Use HTTPS for all communication. Store secrets in environment variables on the server. Use httpOnly cookies for auth tokens. Mask sensitive fields in the UI. Follow the principle of least exposure — only send data the client actually needs.
Never expose secrets in frontend code
// Bad — API key is visible to anyone who opens DevToolsconst API_KEY = 'sk_live_abc123';fetch(`/api?key=${API_KEY}`);// Good — proxy through your backendfetch('/api/data'); // your server adds the API keyAnything in your JavaScript bundle is public. Environment variables prefixed with NEXT_PUBLIC_ or VITE_ are embedded in the client bundle — never put secrets there.
Use HTTPS everywhere
Without HTTPS, data travels in plain text over the network. Anyone on the same WiFi can read passwords, tokens, and personal data.
- Enable HTTPS on your server
- Use HSTS headers to force HTTPS
- Never send forms over HTTP
Store auth tokens securely
// Good — httpOnly cookie (JavaScript cannot access it)// Server sets: Set-Cookie: token=abc123; HttpOnly; Secure; SameSite=Strict// Bad — localStorage (any script can read it)localStorage.setItem('token', 'abc123');httpOnly cookies are invisible to JavaScript, which protects them from XSS attacks.
Environment variables
Store secrets in server-side environment variables, not in code:
# .env file (never commit to git)DATABASE_URL=postgres://user:pass@host/dbAPI_SECRET=sk_live_abc123Add .env to your .gitignore. Use your hosting provider's environment variable settings for production.
Minimize data exposure
// Bad — sends all user data to the frontendapp.get('/api/user', async (req, res) => { const user = await db.getUser(req.userId); res.json(user); // includes password hash, SSN, etc.});// Good — only send what the frontend needsapp.get('/api/user', async (req, res) => { const user = await db.getUser(req.userId); res.json({ name: user.name, email: user.email, avatar: user.avatar, });});Mask sensitive data in the UI
function CreditCard({ number }) { const masked = `**** **** **** ${number.slice(-4)}`; return <p>{masked}</p>;}Only show the last 4 digits. Never display full card numbers, SSNs, or passwords.
Interview Tip
Cover: no secrets in frontend code, HTTPS, httpOnly cookies for auth, environment variables for server secrets, and minimal data exposure. These are the five most important points. Give a quick code example for each.
Why interviewers ask this
Data breaches are expensive and damaging. Interviewers want to see if you handle sensitive data responsibly and know the common mistakes (like putting API keys in frontend code or storing tokens in localStorage).