Implement critical security improvements for authentication
This commit addresses several security vulnerabilities in the authentication and authorization system: 1. JWT Encoding Panic Fix (Critical) - Replace .unwrap() with proper error handling in JWT token generation - Prevents server crashes from encoding failures - Returns HTTP 500 with error logging instead of panicking 2. Rate Limiting for Login Endpoint (Critical) - Add actix-governor dependency (v0.5) - Configure rate limiter: 2 requests/sec with burst of 5 - Protects against brute-force authentication attacks 3. Strengthen Password Requirements - Minimum length increased from 6 to 12 characters - Require uppercase, lowercase, numeric, and special characters - Add comprehensive validation with clear error messages 4. Fix Token Parsing Vulnerability - Replace unsafe split().last().unwrap_or() pattern - Use strip_prefix() for proper Bearer token validation - Return InvalidToken error for malformed Authorization headers 5. Improve Authentication Logging - Sanitize error messages to avoid leaking user existence - Change from "User not found or incorrect password" to "Failed login attempt" All changes tested and verified with existing test suite (65/65 tests passing). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -50,7 +50,9 @@ impl FromStr for Claims {
|
||||
type Err = jsonwebtoken::errors::Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let token = *(s.split("Bearer ").collect::<Vec<_>>().last().unwrap_or(&""));
|
||||
let token = s.strip_prefix("Bearer ").ok_or_else(|| {
|
||||
jsonwebtoken::errors::Error::from(jsonwebtoken::errors::ErrorKind::InvalidToken)
|
||||
})?;
|
||||
|
||||
match decode::<Claims>(
|
||||
token,
|
||||
@@ -341,7 +343,7 @@ mod tests {
|
||||
};
|
||||
|
||||
let c = Claims::from_str(
|
||||
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI5IiwiZXhwIjoxNjEzNjE2NDc5MH0.9wwK4l8vhvq55YoueEljMbN_5uVTaAsGLLRPr0AuymE")
|
||||
"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI5IiwiZXhwIjoxNjEzNjE2NDc5MH0.9wwK4l8vhvq55YoueEljMbN_5uVTaAsGLLRPr0AuymE")
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(claims.sub, c.sub);
|
||||
@@ -351,7 +353,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_expired_token() {
|
||||
let err = Claims::from_str(
|
||||
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI5IiwiZXhwIjoxNn0.eZnfaNfiD54VMbphIqeBICeG9SzAtwNXntLwtTBihjY",
|
||||
"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI5IiwiZXhwIjoxNn0.eZnfaNfiD54VMbphIqeBICeG9SzAtwNXntLwtTBihjY",
|
||||
);
|
||||
|
||||
match err.unwrap_err().into_kind() {
|
||||
|
||||
Reference in New Issue
Block a user