Prevention of session hijacking
import express from 'express';
const app = express();
app.use(express.json());
let sessionCookie: string;
app.post('/login', (req, res) => {
const { username, password } = req.body;
// Perform authentication logic here...
// Set the session cookie
sessionCookie = 'user-session-cookie';
res.status(200).json({ message: 'Login successful' });
});
app.get('/dashboard', (req, res) => {
// Check if the session cookie is set
if (sessionCookie) {
// Render the dashboard
res.status(200).json({ message: 'Welcome to the dashboard' });
} else {
res.status(401).json({ message: 'Unauthorized' });
}
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
The vulnerability in this code is session fixation. Session fixation occurs when the session cookie remains the same after a successful login, allowing an attacker to hijack the user's session.
In this code, the session cookie is stored in the variable
sessionCookie
. After a successful login, the session cookie is set to a fixed value
'user-session-cookie'
. This means that every user who logs in will have the same session cookie value.
The issue is that the session cookie is not invalidated or changed after a successful login. This allows an attacker to obtain the session cookie value and use it to impersonate the user's session. The attacker can set their own cookie with the known session cookie value and gain unauthorized access to the user's account.
To fix this vulnerability, the code should invalidate the anonymous cookie and create a new one after a successful login. This ensures that the session cookie value is unique for each user and cannot be easily guessed or exploited by an attacker.
import express from 'express';
import { v4 as uuidv4 } from 'uuid';
const app = express();
app.use(express.json());
let sessionCookie: string;
app.post('/login', (req, res) => {
const { username, password } = req.body;
// Perform authentication logic here...
// Generate a new session ID
const sessionId = uuidv4();
// Invalidate the previous session cookie, if any
res.clearCookie('session');
// Create a new session cookie with the new session ID
res.cookie('session', sessionId, { httpOnly: true, secure: true });
// Update the sessionCookie variable to store the new session ID
sessionCookie = sessionId;
res.status(200).json({ message: 'Login successful' });
});
app.get('/dashboard', (req, res) => {
// Check if the session ID is valid
const sessionId = req.cookies.session;
if (sessionId && sessionId === sessionCookie) {
// Render the dashboard
res.status(200).json({ message: 'Welcome to the dashboard' });
} else {
res.status(401).json({ message: 'Unauthorized' });
}
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
The fixed code addresses the vulnerability by implementing session management best practices. Here's an explanation of the changes made:
1. The code imports the necessary modules, including the
uuid
module for generating unique session IDs.
2. The
express
application is created and the
express.json()
middleware is used to parse incoming JSON data.
3. A variable
sessionCookie
is declared to store the current session ID.
4. The
/login
route is defined to handle the login request. It extracts the
username
and
password
from the request body.
5. After performing the authentication logic (not shown in the code), a new session ID is generated using
uuidv4()
.
6. The previous session cookie, if any, is invalidated by calling
res.clearCookie('session')
. This ensures that any existing session cookie is removed from the client's browser.
7. A new session cookie is created using
res.cookie('session', sessionId, { httpOnly: true, secure: true })
. The
httpOnly
flag ensures that the cookie is only accessible via HTTP requests and cannot be accessed by client-side JavaScript. The
secure
flag ensures that the cookie is only sent over HTTPS connections.
8. The
sessionCookie
variable is updated with the new session ID.
9. A JSON response with a status of 200 and a message indicating successful login is sent back to the client.
10. The
/dashboard
route is defined to handle requests to the dashboard. It checks if the session ID stored in the cookie matches the
sessionCookie
variable. If they match, it sends a JSON response with a status of 200 and a welcome message. Otherwise, it sends a JSON response with a status of 401 indicating unauthorized access.
11. The server is set to listen on port 3000, and a message is logged to indicate that the server is running.
By invalidating the previous session cookie and generating a new one after a successful login, the fixed code prevents session fixation attacks.