CSRF Protection in Tempo Labs: Implementation Guide


Introduction

Cross-Site Request Forgery (CSRF) remains one of the most overlooked yet dangerous web application vulnerabilities. In the rapidly evolving landscape of vibe coding, where Tempo Labs has emerged as a powerful platform for creating modern web applications, developers often focus on functionality and speed while inadvertently neglecting security concerns like CSRF.

CSRF attacks occur when a malicious website, email, blog, instant message, or program tricks an authenticated user’s web browser into performing unwanted actions on a trusted site. Since browser requests automatically include all cookies, including session cookies, these attacks can be devastating if proper protections aren’t implemented. According to recent security reports, CSRF vulnerabilities are present in over 40% of applications built with AI-assisted coding tools, making this a critical security concern for Tempo Labs developers.

Common CSRF Vulnerabilities

1. Missing CSRF Tokens in Forms

Tempo Labs often generates form handling code without implementing CSRF protection:

// Example of vulnerable Tempo Labs-generated form handling
function createUserForm() {
  return (
    <form action="/api/users" method="POST">
      <input type="text" name="username" placeholder="Username" />
      <input type="email" name="email" placeholder="Email" />
      <input type="password" name="password" placeholder="Password" />
      <button type="submit">Create User</button>
    </form>
  );
}

This code is vulnerable because:

  • No CSRF token is included in the form
  • The server-side endpoint doesn’t validate any CSRF token
  • An attacker can create a malicious form on their website that submits to your API endpoint
  • If a user is authenticated on your site and visits the attacker’s site, the malicious form submission will succeed

2. Unprotected API Endpoints

Another common issue is when Tempo Labs generates API endpoints without CSRF protection:

// Example of vulnerable API endpoint
app.post('/api/transfer-funds', async (req, res) => {
  const { toAccount, amount } = req.body;
  
  // Assuming user is authenticated via session cookie
  const fromAccount = req.session.userId;
  
  try {
    await transferFunds(fromAccount, toAccount, amount);
    res.json({ success: true });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

3. Relying on HTTP-Only Cookies Without Additional Protection

Tempo Labs often generates authentication systems that rely solely on HTTP-only cookies:

// Example of vulnerable cookie-based authentication
app.post('/api/login', async (req, res) => {
  const { username, password } = req.body;
  
  const user = await authenticateUser(username, password);
  
  if (user) {
    // Set session cookie
    res.cookie('sessionId', generateSessionId(), {
      httpOnly: true,
      secure: true,
      sameSite: 'lax'
    });
    
    res.json({ success: true });
  } else {
    res.status(401).json({ error: 'Invalid credentials' });
  }
});

Implementing Secure CSRF Protection

1. Synchronizer Token Pattern

Here’s how to implement proper CSRF protection using the synchronizer token pattern:

// Server-side code (Node.js/Express example)
const express = require('express');
const crypto = require('crypto');
const app = express();

// Middleware to generate CSRF token if not exists
app.use((req, res, next) => {
  if (!req.session.csrfToken) {
    // Generate a cryptographically secure random token
    req.session.csrfToken = crypto.randomBytes(32).toString('hex');
  }
  next();
});

// Middleware to validate CSRF token
const validateCsrfToken = (req, res, next) => {
  const submittedToken = req.body._csrf;
  const storedToken = req.session.csrfToken;
  
  if (!submittedToken || !storedToken || submittedToken !== storedToken) {
    // Log potential CSRF attack
    console.warn('CSRF token validation failed', {
      ip: req.ip,
      path: req.path,
      timestamp: new Date().toISOString()
    });
    
    return res.status(403).json({
      error: 'Invalid or missing CSRF token. Please try again.'
    });
  }
  
  next();
};

// Protected endpoint with CSRF validation
app.post('/api/users', validateCsrfToken, async (req, res) => {
  // Process user registration
  // ...
});

2. Secure Form Implementation

Here’s a secure React form component with CSRF protection:

// Client-side React component
function SecureUserForm() {
  const [formData, setFormData] = useState({
    username: '',
    email: '',
    password: ''
  });
  
  // Get CSRF token from context
  const { csrfToken } = useContext(SecurityContext);
  
  const handleSubmit = async (e) => {
    e.preventDefault();
    
    try {
      const response = await fetch('/api/users', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'X-CSRF-Token': csrfToken
        },
        body: JSON.stringify(formData),
        credentials: 'include' // Important for cookies
      });
      
      if (!response.ok) {
        throw new Error('Form submission failed');
      }
      
      // Handle success
    } catch (error) {
      // Handle error
      console.error('Form submission error:', error);
    }
  };
  
  return (
    <form onSubmit={handleSubmit}>
      <input type="hidden" name="_csrf" value={csrfToken} />
      
      <div className="form-group">
        <label htmlFor="username">Username</label>
        <input 
          type="text" 
          id="username"
          name="username" 
          value={formData.username}
          onChange={(e) => setFormData({
            ...formData,
            username: e.target.value
          })}
          required 
        />
      </div>
      
      {/* Similar fields for email and password */}
      
      <button type="submit">Create Account</button>
    </form>
  );
}

Implement additional protection for API endpoints:

// CSRF protection middleware with double submit cookie
const csrfProtection = (req, res, next) => {
  const token = req.headers['x-csrf-token'];
  const cookie = req.cookies['csrf-token'];
  
  if (!token || !cookie || token !== cookie) {
    return res.status(403).json({
      error: 'CSRF validation failed'
    });
  }
  
  next();
};

// Apply to all non-GET routes
app.use((req, res, next) => {
  if (!['GET', 'HEAD', 'OPTIONS'].includes(req.method)) {
    return csrfProtection(req, res, next);
  }
  next();
});

// Set CSRF token cookie on initial page load
app.get('*', (req, res, next) => {
  if (!req.cookies['csrf-token']) {
    const token = crypto.randomBytes(32).toString('hex');
    res.cookie('csrf-token', token, {
      httpOnly: true,
      secure: process.env.NODE_ENV === 'production',
      sameSite: 'strict'
    });
  }
  next();
});

Best Practices

  1. Token Management:

    • Use cryptographically secure tokens
    • Regenerate tokens periodically
    • Validate token length and format
    • Implement proper token storage
  2. Form Security:

    • Include CSRF tokens in all forms
    • Use hidden form fields
    • Implement proper validation
    • Handle errors gracefully
  3. API Protection:

    • Protect all state-changing endpoints
    • Implement token validation
    • Use secure headers
    • Monitor for attacks
  4. Cookie Security:

    • Use secure cookie flags
    • Implement SameSite policy
    • Set appropriate expiration
    • Validate cookie integrity

Conclusion

Implementing robust CSRF protection in Tempo Labs applications is crucial for maintaining security. By following these best practices and implementing proper security measures, you can protect your applications from CSRF attacks while maintaining the development efficiency that Tempo Labs provides.

Additional Resources