Add "future buffer" to iat validation for client credentials grant

Closes PLAT-4157

Test Plan:
Attempt to retrieve an access token using a client credentials
grant. The iat of the claimshould be 10 seconds in the future.
Verify you are still able to retrieve an access token.

Verify you cannot retrieve an access token if the iat is more than
30 seconds in the future.

Change-Id: I884f569c3ab4bcafaaa459c70fe3d0c2326153cd
Reviewed-on: https://gerrit.instructure.com/178477
Reviewed-by: Marc Phillips <mphillips@instructure.com>
QA-Review: Marc Phillips <mphillips@instructure.com>
Tested-by: Jenkins
Product-Review: Weston Dransfield <wdransfield@instructure.com>
This commit is contained in:
wdransfield 2019-01-18 10:13:30 -07:00 committed by Weston Dransfield
parent 9364cd0323
commit bf4aaae0ed
3 changed files with 24 additions and 1 deletions

View File

@ -73,8 +73,9 @@ module Canvas::Security
return if errors?
iat_time = Time.zone.at(@jwt.iat)
max_iat_age = Setting.get("oauth2_jwt_iat_ago_in_seconds", 5.minutes.to_s).to_i.seconds
iat_future_buffer = Setting.get("oauth2_jwt_iat_future_buffer", 30.seconds.to_s).to_i.seconds
errors.add(:base, "the 'iat' must be less than #{max_iat_age} seconds old") if iat_time < max_iat_age.ago
errors.add(:base, "the 'iat' must not be in the future") if iat_time > Time.zone.now
errors.add(:base, "the 'iat' must not be in the future") if iat_time > Time.zone.now + iat_future_buffer
end
def jti

View File

@ -580,6 +580,17 @@ describe Oauth2ProviderController do
it { is_expected.to have_http_status 400 }
end
context 'with iat in the future by a small amount' do
let(:future_iat_time) { 5.seconds.from_now }
let(:iat) { future_iat_time.to_i }
it 'returns an access token' do
Timecop.freeze(future_iat_time - 5.seconds) do
expect(subject).to have_http_status 200
end
end
end
context 'with bad iat' do
let(:iat) { 1.minute.from_now.to_i }

View File

@ -53,6 +53,17 @@ module Canvas::Oauth
expect(subject).to have_key key
end
end
context 'with iat in the future by a small amount' do
let(:future_iat_time) { 5.seconds.from_now }
let(:iat) { future_iat_time.to_i }
it 'returns an access token' do
Timecop.freeze(future_iat_time - 5.seconds) do
expect(subject).to be_a Hash
end
end
end
end
describe '#error_message' do