Homework 4 Reflection

1. UI

When adding logins and authorization to the front-end, one of the biggest struggles was managing authentication state properly. Initially, I had issues where the user state was not updating after logging in, and sometimes, after a refresh, the user would be logged out unexpectedly. This was due to missing withCredentials: true in API requests, which prevented cookies from being stored and sent correctly.

Another challenge was properly handling CSRF tokens in requests. I had to modify various components, such as RegisterForm.tsx, LoginForm.tsx, and SearchBooks.tsx, to fetch and include CSRF tokens when making API calls.

2. Login Endpoint

On the back-end, I struggled with session management, as users would be logged out after refreshing the page. The issue was that session data was stored in memory, but the front-end wasn’t properly sending authentication cookies, making it seem like the session was lost. Fixing this required ensuring cookies were included in requests and properly handled on both ends.

I also ran into CSRF errors when implementing protection, as requests were being blocked until I ensured the CSRF token was correctly fetched and included in all modifying requests. Properly configuring withCredentials in Axios and setting the right cookie policies helped resolve this.

3. Security Audit

XSS Mitigation

My app was initially vulnerable to XSS attacks because user input was being rendered directly in the UI without sanitization. To mitigate this, I ensured that all user-generated content was sanitized before rendering, and I used the helmet package to set a strict Content Security Policy (CSP) that prevents inline scripts.

CSRF Mitigation

Before implementing CSRF protection, my app was vulnerable because API requests could be made from unauthorized sources if a user’s session was active. To mitigate this, I used the csurf middleware to generate and validate CSRF tokens. These tokens are now required for all non-GET requests, and they are stored in cookies and included in API requests.

Rate Limiting

I added rate limiting at the application level using the express-rate-limit package. The configuration limits the number of requests a user can make within 15 minutes to prevent brute-force attacks. Below is the code used:

const limiter = rateLimit({
    windowMs: 5 * 60 * 1000, // 5 minutes
    max: 200, // Limit each IP to 200 requests per windowMs
    message: "Too many requests from this IP, please try again later.",
    standardHeaders: true,
    legacyHeaders: false,
});
app.use(limiter);
        

Security Headers

I added security-related HTTP headers using helmet. These headers include:

These headers enhance security by reducing the risk of various web attacks.

Other Security Measures

In addition to the above, I used argon2 for password hashing to ensure stored passwords remain secure. I also ensured that authentication tokens and session cookies are marked as httpOnly and secure in production mode to prevent client-side access.

Back to Home