CWE-613 in APIs
- CWE ID
- CWE-613
- Category
- Authentication
- Severity
- MEDIUM
- Short Name
- Session Expiry
What is CWE-613?
CWE-613: Insufficient Session Expiration occurs when an application fails to properly invalidate or expire user sessions after logout, timeout, or privilege change. This weakness allows attackers to reuse valid session tokens even after the legitimate user has ended their session, potentially gaining unauthorized access to sensitive functionality or data.
The core issue is that session identifiers remain active beyond their intended lifespan. When a user logs out, their session should be immediately terminated on both client and server sides. Similarly, after a period of inactivity, sessions should automatically expire. Without these controls, session tokens can be intercepted, stolen, or reused by malicious actors.
CWE-613 in API Contexts
APIs are particularly vulnerable to insufficient session expiration because they often rely on stateless authentication mechanisms like JWT tokens or API keys that may not have proper expiration controls. In RESTful APIs, developers might implement token-based authentication without adequate session lifecycle management.
Common API manifestations include:
- API endpoints that accept JWT tokens without validating expiration claims (exp field)
- Refresh token mechanisms that don't properly invalidate old tokens
- API keys that remain valid indefinitely without rotation policies
- WebSocket connections that maintain authentication state without proper cleanup
- GraphQL subscriptions that keep user contexts alive after logout
Consider this vulnerable API endpoint:
app.post('/api/logout', (req, res) => {
// BUG: Only removes token from client, doesn't invalidate server-side
res.clearCookie('authToken');
res.json({ success: true });
});This implementation only clears the cookie on the client side but doesn't actually terminate the session on the server. An attacker who has intercepted the token can continue using it until it naturally expires.
Detection
Detecting insufficient session expiration requires both static code analysis and dynamic testing. For APIs, the most effective approach combines automated scanning with manual penetration testing.
Static analysis should look for:
- Missing token expiration validation in middleware
- Logout handlers that don't invalidate server-side sessions
- Hardcoded or overly long token expiration times
- Missing session timeout configurations
Dynamic testing involves:
- Logging out and immediately attempting to use the same token
- Waiting for timeout periods and verifying automatic expiration
- Testing token reuse across different user contexts
middleBrick automatically detects CWE-613 vulnerabilities through its black-box scanning approach. The scanner tests session expiration by:
- Authenticating to the API and obtaining a session token
- Attempting to use the token after simulated logout
- Verifying that tokens expire after configured timeout periods
- Checking for proper session invalidation across all endpoints
The scanner reports findings with severity levels and provides specific remediation guidance for each detected instance of insufficient session expiration.
Remediation
Fixing insufficient session expiration requires implementing proper session lifecycle management at both the authentication and application levels.
1. Implement Proper Token Expiration:
// Secure JWT generation with proper expiration
const generateSecureToken = (userId) => {
return jwt.sign(
{ userId },
process.env.JWT_SECRET,
{
expiresIn: '15m', // Short access token lifetime
issuer: 'your-api-domain.com'
}
);
};
// Use refresh tokens for extended sessions
const refreshSession = (refreshToken) => {
// Validate refresh token
// Issue new access token
// Invalidate old refresh token (store in DB with used flag)
};2. Implement Proper Logout Handling:
app.post('/api/logout', async (req, res) => {
try {
const token = req.headers.authorization.split(' ')[1];
// Invalidate token server-side
await invalidateToken(token); // Store in revoked tokens DB
// Clear client-side cookies
res.clearCookie('authToken');
res.clearCookie('refreshToken');
res.json({ success: true });
} catch (error) {
res.status(500).json({ error: 'Logout failed' });
}
});3. Implement Session Timeout Middleware:
const sessionTimeoutMiddleware = (req, res, next) => {
const now = Date.now();
const lastActivity = req.session.lastActivity || now;
// 30 minute inactivity timeout
if (now - lastActivity > 30 * 60 * 1000) {
return res.status(401).json({ error: 'Session expired' });
}
req.session.lastActivity = now;
next();
};
app.use('/api/protected/*', sessionTimeoutMiddleware);4. Use Sliding Expiration for Active Sessions:
// Update expiration on each valid request
const slidingExpirationMiddleware = (req, res, next) => {
if (req.user) {
// Reset expiration timer on activity
req.user.lastAccessed = new Date();
await updateUserLastAccessed(req.user.id, req.user.lastAccessed);
}
next();
};
// Cleanup expired sessions periodically
const cleanupExpiredSessions = async () => {
const cutoff = new Date(Date.now() - 24 * 60 * 60 * 1000); // 24 hours
await User.updateMany(
{ lastAccessed: { $lt: cutoff } },
{ status: 'inactive' }
);
};
setInterval(cleanupExpiredSessions, 60 * 60 * 1000); // Run hourly