mirror of
				https://github.com/iv-org/invidious.git
				synced 2025-10-30 12:11:55 +00:00 
			
		
		
		
	Verify token signature in constant time, Run cheap checks first in token validation process (#1032)
* Verify token signature in constant time To prevent timing side channel attacks * Run cheap checks first in token validation process Expensive checks such as the nonce lookup on the database or the signature check can be run after cheap/fast checks.
This commit is contained in:
		| @@ -1,3 +1,5 @@ | ||||
| require "crypto/subtle" | ||||
|  | ||||
| def generate_token(email, scopes, expire, key, db) | ||||
|   session = "v1:#{Base64.urlsafe_encode(Random::Secure.random_bytes(32))}" | ||||
|   PG_DB.exec("INSERT INTO session_ids VALUES ($1, $2, $3)", session, email, Time.utc) | ||||
| @@ -76,14 +78,25 @@ def validate_request(token, session, request, key, db, locale = nil) | ||||
|     raise translate(locale, "Hidden field \"token\" is a required field") | ||||
|   end | ||||
|  | ||||
|   if token["signature"] != sign_token(key, token) | ||||
|     raise translate(locale, "Invalid signature") | ||||
|   expire = token["expire"]?.try &.as_i | ||||
|   if expire.try &.< Time.utc.to_unix | ||||
|     raise translate(locale, "Token is expired, please try again") | ||||
|   end | ||||
|  | ||||
|   if token["session"] != session | ||||
|     raise translate(locale, "Erroneous token") | ||||
|   end | ||||
|  | ||||
|   scopes = token["scopes"].as_a.map { |v| v.as_s } | ||||
|   scope = "#{request.method}:#{request.path.lchop("/api/v1/auth/").lstrip("/")}" | ||||
|   if !scopes_include_scope(scopes, scope) | ||||
|     raise translate(locale, "Invalid scope") | ||||
|   end | ||||
|  | ||||
|   if !Crypto::Subtle.constant_time_compare(token["signature"].to_s, sign_token(key, token)) | ||||
|     raise translate(locale, "Invalid signature") | ||||
|   end | ||||
|  | ||||
|   if token["nonce"]? && (nonce = db.query_one?("SELECT * FROM nonces WHERE nonce = $1", token["nonce"], as: {String, Time})) | ||||
|     if nonce[1] > Time.utc | ||||
|       db.exec("UPDATE nonces SET expire = $1 WHERE nonce = $2", Time.utc(1990, 1, 1), nonce[0]) | ||||
| @@ -92,18 +105,6 @@ def validate_request(token, session, request, key, db, locale = nil) | ||||
|     end | ||||
|   end | ||||
|  | ||||
|   scopes = token["scopes"].as_a.map { |v| v.as_s } | ||||
|   scope = "#{request.method}:#{request.path.lchop("/api/v1/auth/").lstrip("/")}" | ||||
|  | ||||
|   if !scopes_include_scope(scopes, scope) | ||||
|     raise translate(locale, "Invalid scope") | ||||
|   end | ||||
|  | ||||
|   expire = token["expire"]?.try &.as_i | ||||
|   if expire.try &.< Time.utc.to_unix | ||||
|     raise translate(locale, "Token is expired, please try again") | ||||
|   end | ||||
|  | ||||
|   return {scopes, expire, token["signature"].as_s} | ||||
| end | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 leonklingele
					leonklingele