From 5e27a987dda845679eb183dc11030ec7b3a062bb Mon Sep 17 00:00:00 2001 From: dimgigov Date: Tue, 12 May 2026 23:36:17 +0300 Subject: [PATCH] fix: auth token expiration + constant-time JWT signature comparison MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - createToken() добавя exp/iat/nbf в JWT payload - verifyToken() parse-ва exp/iat/nbf и проверява expiration - verifyToken() използва constantTimeCompare() за timing-attack resistance - Добавен import std/times 292 теста, 0 failure-а. --- src/barabadb/protocol/auth.nim | 37 ++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/src/barabadb/protocol/auth.nim b/src/barabadb/protocol/auth.nim index a56282b..ad8c20c 100644 --- a/src/barabadb/protocol/auth.nim +++ b/src/barabadb/protocol/auth.nim @@ -2,6 +2,7 @@ import std/strutils import std/base64 import std/tables +import std/times import checksums/sha2 type @@ -82,21 +83,36 @@ proc hmacSha256(key, message: string): string = proc createToken*(am: AuthManager, claims: JWTClaims): string = let header = base64UrlEncode("{\"alg\":\"HS256\",\"typ\":\"JWT\"}") - let payload = base64UrlEncode( - "{\"sub\":\"" & claims.sub & "\",\"role\":\"" & claims.role & - "\",\"database\":\"" & claims.database & "\"}") + var payloadJson = "{\"sub\":\"" & claims.sub & "\",\"role\":\"" & claims.role & + "\",\"database\":\"" & claims.database & "\"" + if claims.exp > 0: + payloadJson &= ",\"exp\":" & $claims.exp + if claims.iat > 0: + payloadJson &= ",\"iat\":" & $claims.iat + if claims.nbf > 0: + payloadJson &= ",\"nbf\":" & $claims.nbf + payloadJson &= "}" + let payload = base64UrlEncode(payloadJson) let data = header & "." & payload let signature = hmacSha256(am.secretKey, data) am.tokens.add(data & "." & base64UrlEncode(signature)) return am.tokens[^1] +proc constantTimeCompare(a, b: string): bool = + if a.len != b.len: + return false + var result = 0 + for i in 0.. 0 and now > claims.exp: + return (false, JWTClaims()) + if claims.nbf > 0 and now < claims.nbf: + return (false, JWTClaims()) + if claims.iat > 0 and now < claims.iat - 60: + # Allow 60 seconds clock skew + return (false, JWTClaims()) return (true, claims) proc validateCredentials*(am: AuthManager, creds: AuthCredentials): AuthResult =