TypeError in LFS token validation when JWT header is malformed
Summary
A TypeError: no implicit conversion of String into Integer is raised in Gitlab::LfsToken#token_valid? when a malformed token with an invalid JWT header is passed for validation.
Sentry Error
https://new-sentry.gitlab.net/organizations/gitlab/issues/3211045
Root Cause
When a malformed token has:
- Exactly 2 segments (missing signature)
- A header that decodes to a JSON Array instead of a Hash (e.g.,
["HS256"]) The JWT gem callsheader['alg']to check for thenonealgorithm. SinceArray#[]expects an Integer index, passing a String key raises:
TypeError: no implicit conversion of String into Integer
Stack trace:
token.header['alg']
^^^^^
from jwt/decode.rb:117:in `[]'
from jwt/decode.rb:117:in `alg_in_header'
from jwt/decode.rb:113:in `none_algorithm?'
from jwt/decode.rb:107:in `validate_segment_count!'
from jwt/decode.rb:31:in `decode_segments'
from jwt.rb:51:in `block in decode'
from lib/json_web_token/hmac_token.rb:17:in `decode'
from lib/gitlab/lfs_token.rb:99:in `token_valid?'
Reproduction
user = User.first
lfs_token = Gitlab::LfsToken.new(user, nil)
encoded_header = Base64.urlsafe_encode64('["HS256"]', padding: false)
encoded_payload = Base64.urlsafe_encode64('{}', padding: false)
malformed_token = "#{encoded_header}.#{encoded_payload}"
lfs_token.token_valid?(malformed_token)
# => TypeError: no implicit conversion of String into Integer
Proposed Fix
Rescue TypeError alongside JWT::DecodeError in HMACToken#token_valid?:
def token_valid?(token_to_check)
decoded_token = JSONWebToken::HMACToken.decode(token_to_check, secret).first
# ...
rescue JWT::DecodeError, TypeError
false
end
Invalid tokens should return false regardless of the specific error type.
Edited by 🤖 GitLab Bot 🤖