Skip to content
intermediatePhase 41 · Frontend Security

Authentication Security

Implement secure authentication with password hashing and MFA.

45m
0 problems
Topic Progress0%

Password Security

Password Security

Hashing

// Use bcrypt for password hashing
const bcrypt = require('bcrypt');

// Hash password
async function hashPassword(password) {
  const saltRounds = 12;
  return await bcrypt.hash(password, saltRounds);
}

// Verify password
async function verifyPassword(password, hash) {
  return await bcrypt.compare(password, hash);
}

// Never store plain text passwords
// Never use MD5 or SHA for passwords

Password Policies

// Minimum requirements
const passwordSchema = z.string()
  .min(8, 'Password must be at least 8 characters')
  .max(100, 'Password must be less than 100 characters')
  .regex(/[A-Z]/, 'Password must contain at least one uppercase letter')
  .regex(/[a-z]/, 'Password must contain at least one lowercase letter')
  .regex(/[0-9]/, 'Password must contain at least one number')
  .regex(/[^A-Za-z0-9]/, 'Password must contain at least one special character');

// Check against common passwords
const commonPasswords = ['password', '123456', 'qwerty'];
function isCommonPassword(password) {
  return commonPasswords.includes(password.toLowerCase());
}

Brute Force Protection

// Rate limiting
const rateLimit = require('express-rate-limit');

const loginLimiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 5, // 5 attempts
  message: 'Too many login attempts',
  skipSuccessfulRequests: true,
});

app.post('/login', loginLimiter, async (req, res) => {
  // Login logic
});

// Account lockout
const attempts = new Map();

function checkAttempts(email) {
  const userAttempts = attempts.get(email) || { count: 0, lockUntil: 0 };
  
  if (Date.now() < userAttempts.lockUntil) {
    return { locked: true, remaining: userAttempts.lockUntil - Date.now() };
  }
  
  return { locked: false };
}

function recordAttempt(email, success) {
  const userAttempts = attempts.get(email) || { count: 0, lockUntil: 0 };
  
  if (success) {
    attempts.delete(email);
  } else {
    userAttempts.count++;
    if (userAttempts.count >= 5) {
      userAttempts.lockUntil = Date.now() + 15 * 60 * 1000; // 15 minutes
    }
    attempts.set(email, userAttempts);
  }
}

Session Security

Session Security

Secure Session Configuration

const session = require('express-session');
const RedisStore = require('connect-redis').default;

app.use(session({
  store: new RedisStore({ client: redisClient }),
  secret: process.env.SESSION_SECRET,
  resave: false,
  saveUninitialized: false,
  cookie: {
    secure: process.env.NODE_ENV === 'production',
    httpOnly: true,
    maxAge: 24 * 60 * 60 * 1000, // 24 hours
    sameSite: 'strict',
  },
}));

Session Management

// Regenerate session ID on login
app.post('/login', async (req, res) => {
  const user = await authenticate(req.body);
  
  if (user) {
    req.session.regenerate((err) => {
      req.session.userId = user.id;
      res.json({ success: true });
    });
  }
});

// Destroy session on logout
app.post('/logout', (req, res) => {
  req.session.destroy((err) => {
    res.clearCookie('connect.sid');
    res.json({ success: true });
  });
});

// Session fixation prevention
app.use((req, res, next) => {
  if (req.session.userId && !req.session.initialized) {
    req.session.regenerate(() => {
      req.session.initialized = true;
      next();
    });
  } else {
    next();
  }
});

Session Security Headers

app.use((req, res, next) => {
  // Prevent session fixation
  res.setHeader('X-Content-Type-Options', 'nosniff');
  res.setHeader('X-Frame-Options', 'DENY');
  res.setHeader('X-XSS-Protection', '1; mode=block');
  
  // Content Security Policy
  res.setHeader(
    'Content-Security-Policy',
    "default-src 'self'; script-src 'self';"
  );
  
  next();
});

OAuth and MFA

OAuth and MFA

OAuth 2.0 Flow

// Frontend: Redirect to OAuth provider
const authUrl = new URL('https://provider.com/oauth/authorize');
authUrl.searchParams.set('client_id', clientId);
authUrl.searchParams.set('redirect_uri', redirectUri);
authUrl.searchParams.set('response_type', 'code');
authUrl.searchParams.set('scope', 'profile email');
authUrl.searchParams.set('state', generateState());

window.location.href = authUrl.toString();

// Backend: Exchange code for token
app.get('/callback', async (req, res) => {
  const { code, state } = req.query;
  
  // Verify state
  if (state !== req.session.oauthState) {
    return res.status(403).json({ error: 'Invalid state' });
  }
  
  // Exchange code for token
  const tokenResponse = await fetch('https://provider.com/oauth/token', {
    method: 'POST',
    body: JSON.stringify({
      grant_type: 'authorization_code',
      code,
      client_id: clientId,
      client_secret: clientSecret,
      redirect_uri: redirectUri,
    }),
  });
  
  const { access_token } = await tokenResponse.json();
  
  // Get user info
  const userResponse = await fetch('https://provider.com/userinfo', {
    headers: { Authorization: `Bearer ${access_token}` },
  });
  
  const user = await userResponse.json();
  
  // Create or login user
  req.session.userId = user.id;
  res.redirect('/dashboard');
});

Multi-Factor Authentication

// TOTP (Time-based One-Time Password)
const speakeasy = require('speakeasy');

// Generate secret
const secret = speakeasy.generateSecret({
  name: `MyApp:${user.email}`,
});

// Store secret securely
await updateUser(user.id, { totpSecret: secret.base32 });

// Verify token
function verifyTOTP(token, secret) {
  return speakeasy.totp.verify({
    secret,
    encoding: 'base32',
    token,
    window: 1, // Allow 30 seconds window
  });
}

// Login with MFA
app.post('/login', async (req, res) => {
  const user = await authenticate(req.body);
  
  if (user.totpSecret) {
    // Require MFA token
    if (!req.body.totpToken) {
      return res.json({ requiresMFA: true });
    }
    
    const valid = verifyTOTP(req.body.totpToken, user.totpSecret);
    if (!valid) {
      return res.status(401).json({ error: 'Invalid MFA token' });
    }
  }
  
  // Login successful
  req.session.userId = user.id;
  res.json({ success: true });
});

Security Best Practices

  1. Use HTTPS everywhere
  2. Implement rate limiting
  3. Use secure session configuration
  4. Regenerate session IDs on login
  5. Implement MFA for sensitive accounts
  6. Use OAuth for third-party login
  7. Hash passwords with bcrypt
  8. Implement account lockout
  9. Log authentication events
  10. Use Content Security Policy

Practice Problems

0/3solved
Build Authentication Security Component

Create a reusable React component implementing Authentication Security. Include proper state management and accessibility.

Solution
// Production-ready component with:
// - Proper TypeScript types
// - Accessibility (ARIA)
// - Error boundaries
// - Loading states
// - Memoization where needed
Authentication Security Testing

Write unit and integration tests for Authentication Security using React Testing Library.

Solution
// Test coverage:
// 1. Rendering tests
// 2. Interaction tests
// 3. Edge case tests
// 4. Accessibility tests
Authentication Security Performance

Optimize Authentication Security for performance. Consider memoization, code splitting, and bundle size.

Solution
// Optimization techniques:
// 1. React.memo / useMemo / useCallback
// 2. Code splitting with lazy()
// 3. Virtual scrolling for lists
// 4. Image lazy loading
// 5. Bundle analysis

Quiz

1. Why use bcrypt for password hashing?

Question 1 options

2. What is session fixation?

Question 2 options

3. What is the primary purpose of Authentication Security?

Question 3 options

4. What is a common mistake when implementing Authentication Security?

Question 4 options

Flashcards

Question

Why hash passwords?

Answer

To protect them if the database is compromised - hashes are irreversible.

Question

What is rate limiting?

Answer

Limiting the number of requests to prevent brute force attacks.

Question

What is MFA?

Answer

Multi-Factor Authentication - requiring multiple forms of verification.

Question

What is OAuth?

Answer

An open standard for token-based authentication and authorization.

Question

What is Authentication Security?

Answer

Authentication Security is a key concept in frontend development.

Revision Notes

Key Takeaways

  • 1.Hash passwords with bcrypt, never plain text
  • 2.Implement rate limiting and account lockout
  • 3.Regenerate session IDs on login
  • 4.Use MFA for sensitive accounts
  • 5.Use secure session configuration

Interview Tips

  • Explain password hashing and why bcrypt is used
  • Discuss session fixation and how to prevent it
  • Know OAuth flow and MFA implementation

Cheat Sheet

Auth Security Cheat Sheet

Password Security

  • Hash with bcrypt (salt rounds 12+)
  • Never store plain text
  • Implement rate limiting
  • Use account lockout

Session Security

  • Use secure, httpOnly cookies
  • Regenerate session ID on login
  • Set reasonable expiration
  • Use Redis for session store

MFA

  • TOTP (Time-based One-Time Password)
  • Require for sensitive operations
  • Store secrets securely

OAuth

  • Use for third-party login
  • Verify state parameter
  • Exchange code for token server-side

Headers

  • X-Frame-Options: DENY
  • X-Content-Type-Options: nosniff
  • Content-Security-Policy