@sun-asterisk/sunlint
Version:
☀️ SunLint - Multi-language static analysis tool for code quality and security | Sun* Engineering Standards
162 lines (161 loc) • 5.4 kB
JSON
{
"rule": {
"id": "S044",
"name": "Re-authentication Required for Sensitive Operations",
"description": "Require re-authentication before performing sensitive operations such as password changes, email changes, profile updates, and other critical account modifications. This prevents unauthorized access to sensitive account functions even if a session is compromised.",
"category": "security",
"severity": "error",
"languages": ["typescript", "javascript"],
"frameworks": ["express", "nestjs", "node"],
"version": "1.0.0",
"status": "stable",
"tags": ["security", "authentication", "re-authentication", "sensitive-operations", "owasp"],
"references": [
"https://owasp.org/www-community/controls/Authentication_Cheat_Sheet",
"https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html",
"https://owasp.org/www-community/attacks/Session_Management_Cheat_Sheet"
]
},
"configuration": {
"enableReAuthenticationDetection": true,
"sensitiveOperations": [
"changePassword",
"updatePassword",
"resetPassword",
"changeEmail",
"updateEmail",
"changeProfile",
"updateProfile",
"deleteAccount",
"deactivateAccount",
"changePhoneNumber",
"updatePhoneNumber",
"changeSecurityQuestion",
"updateSecurityQuestion",
"changeTwoFactorSettings",
"updateTwoFactorSettings",
"changeBillingInfo",
"updateBillingInfo",
"changePaymentMethod",
"updatePaymentMethod"
],
"authenticationMethods": [
"verifyPassword",
"confirmPassword",
"reAuthenticate",
"verifyCurrentPassword",
"validatePassword",
"checkPassword",
"authenticateUser",
"verifyIdentity"
],
"middlewarePatterns": [
"requireReAuth",
"requireReAuthentication",
"verifyReAuth",
"checkReAuth",
"validateReAuth"
],
"frameworkSpecific": {
"express": {
"routePatterns": [
"/change-password",
"/update-password",
"/change-email",
"/update-email",
"/change-profile",
"/update-profile",
"/delete-account",
"/deactivate-account"
]
},
"nestjs": {
"decorators": [
"@RequireReAuth",
"@ReAuthenticationRequired",
"@VerifyReAuth"
],
"guards": [
"ReAuthGuard",
"ReAuthenticationGuard",
"VerifyReAuthGuard"
]
}
},
"excludePatterns": [
"login",
"register",
"logout",
"forgot-password",
"reset-password-request"
]
},
"examples": {
"violations": [
{
"description": "Password change without re-authentication",
"code": "@Post('change-password')\nasync changePassword(@Body() changePasswordDto: ChangePasswordDto) {\n return this.userService.changePassword(changePasswordDto);\n}"
},
{
"description": "Email change without re-authentication",
"code": "@Put('email')\nasync updateEmail(@Body() emailDto: UpdateEmailDto) {\n return this.userService.updateEmail(emailDto);\n}"
},
{
"description": "Profile update without re-authentication",
"code": "app.put('/profile', (req, res) => {\n return userService.updateProfile(req.body);\n});"
}
],
"fixes": [
{
"description": "Password change with re-authentication",
"code": "@Post('change-password')\n@UseGuards(ReAuthGuard)\nasync changePassword(@Body() changePasswordDto: ChangePasswordDto) {\n return this.userService.changePassword(changePasswordDto);\n}"
},
{
"description": "Email change with re-authentication",
"code": "@Put('email')\n@UseGuards(ReAuthGuard)\nasync updateEmail(@Body() emailDto: UpdateEmailDto) {\n return this.userService.updateEmail(emailDto);\n}"
},
{
"description": "Profile update with re-authentication",
"code": "app.put('/profile', requireReAuth, (req, res) => {\n return userService.updateProfile(req.body);\n});"
}
]
},
"testing": {
"testCases": [
{
"name": "password_change_without_reauth",
"type": "violation",
"description": "Password change endpoint without re-authentication"
},
{
"name": "email_change_without_reauth",
"type": "violation",
"description": "Email change endpoint without re-authentication"
},
{
"name": "profile_update_without_reauth",
"type": "violation",
"description": "Profile update endpoint without re-authentication"
},
{
"name": "password_change_with_reauth",
"type": "clean",
"description": "Password change endpoint with re-authentication guard"
},
{
"name": "email_change_with_reauth",
"type": "clean",
"description": "Email change endpoint with re-authentication guard"
},
{
"name": "profile_update_with_reauth",
"type": "clean",
"description": "Profile update endpoint with re-authentication middleware"
}
]
},
"performance": {
"complexity": "O(n)",
"description": "Linear complexity based on number of route handlers and method calls in the source code"
}
}