@sun-asterisk/sunlint
Version:
☀️ SunLint - Multi-language static analysis tool for code quality and security | Sun* Engineering Standards
125 lines (124 loc) • 3.34 kB
JSON
{
"rule": {
"id": "S049",
"name": "Authentication tokens should have short validity periods",
"description": "Authentication tokens (JWT, session tokens, etc.) should have appropriately short validity periods to minimize the risk of token compromise. Long-lived tokens increase the attack surface and potential impact of token theft.",
"category": "security",
"severity": "error",
"languages": ["typescript", "javascript"],
"frameworks": ["express", "nestjs", "node"],
"version": "1.0.0",
"status": "stable",
"tags": ["security", "authentication", "tokens", "jwt", "session", "owasp"],
"references": [
"https://owasp.org/www-project-web-security-testing-guide/v42/4-Web_Application_Security_Testing/04-Authentication_Testing/01-Testing_for_Credentials_Transported_over_an_Encrypted_Channel",
"https://owasp.org/www-project-application-security-verification-standard/",
"https://cheatsheetseries.owasp.org/cheatsheets/JSON_Web_Token_for_Java_Cheat_Sheet.html",
"https://tools.ietf.org/html/rfc7519#section-4.1.4"
]
},
"configuration": {
"enableJWTValidityCheck": true,
"enableSessionTokenCheck": true,
"enableOAuthTokenCheck": true,
"maxValidityPeriods": {
"accessToken": 3600,
"refreshToken": 86400,
"sessionToken": 1800,
"idToken": 3600,
"authToken": 3600
},
"jwtProperties": [
"exp",
"expiresIn",
"expiry",
"expires",
"ttl",
"maxAge",
"lifetime"
],
"tokenMethods": [
"sign",
"create",
"generate",
"issue",
"encode"
],
"jwtLibraries": [
"jsonwebtoken",
"jose",
"@nestjs/jwt",
"jwt-simple",
"node-jsonwebtoken",
"passport-jwt"
],
"sessionMethods": [
"session",
"cookie",
"maxAge",
"expires"
],
"sessionLibraries": [
"express-session",
"connect-session",
"cookie-session",
"client-sessions"
],
"oauthProperties": [
"access_token_lifetime",
"refresh_token_lifetime",
"token_lifetime",
"expires_in"
],
"timeUnits": {
"seconds": 1,
"minutes": 60,
"hours": 3600,
"days": 86400,
"weeks": 604800,
"months": 2592000,
"years": 31536000
},
"dangerousPatterns": [
"no-expire",
"never-expire",
"permanent",
"forever",
"infinite",
"unlimited"
],
"exemptedScenarios": [
"test",
"testing",
"mock",
"development",
"dev"
]
},
"examples": {
"violations": [
{
"description": "JWT token with excessive expiration time",
"code": "jwt.sign(payload, secret, { expiresIn: '30d' })"
},
{
"description": "Session with very long max age",
"code": "session({ maxAge: 30 * 24 * 60 * 60 * 1000 })"
},
{
"description": "Token with no expiration",
"code": "jwt.sign(payload, secret)"
}
],
"clean": [
{
"description": "JWT token with appropriate expiration",
"code": "jwt.sign(payload, secret, { expiresIn: '1h' })"
},
{
"description": "Session with reasonable max age",
"code": "session({ maxAge: 30 * 60 * 1000 })"
}
]
}
}