Enforce valid lis_outcome_service_url

Recently, a new institution joined CodeOcean and used a relative URL. This won't work, so that we are rejecting non-absolute URLs by now.
This commit is contained in:
Sebastian Serth
2024-04-26 09:31:41 +02:00
committed by Dominic Sauer
parent fa856adcf0
commit 96f5f1f8d7
5 changed files with 23 additions and 2 deletions

View File

@ -85,6 +85,16 @@ module Lti
private :require_valid_consumer_key
def require_valid_lis_outcome_service_url
# We want to check that any URL given is absolute, but none URL is fine, too.
return unless params[:lis_outcome_service_url]
url = URI.parse(params[:lis_outcome_service_url])
refuse_lti_launch(message: t('sessions.oauth.invalid_lis_outcome_service_url')) unless url.absolute?
end
private :require_valid_lis_outcome_service_url
def require_valid_exercise_token
proxy_exercise = ProxyExercise.find_by(token: params[:custom_token])
@exercise = if proxy_exercise.nil?

View File

@ -4,7 +4,8 @@ class SessionsController < ApplicationController
include Lti
%i[require_oauth_parameters require_valid_consumer_key require_valid_oauth_signature require_unique_oauth_nonce
set_current_user require_valid_exercise_token set_study_group_membership set_embedding_options].each do |method_name|
require_valid_lis_outcome_service_url set_current_user require_valid_exercise_token set_study_group_membership
set_embedding_options].each do |method_name|
before_action(method_name, only: :create_through_lti)
end

View File

@ -903,6 +903,7 @@ de:
failure: Leider ist ein Fehler aufgetreten.
invalid_consumer: Ungültiger OAuth-Key.
invalid_exercise_token: Ungültiges Aufgaben-Token.
invalid_lis_outcome_service_url: Ungültige URL für den LTI-Ergebnisdienst.
invalid_signature: Ungültige OAuth-Signatur.
missing_parameters: OAuth-Parameter fehlen.
used_nonce: Die Nonce wurde bereits verwendet.

View File

@ -903,6 +903,7 @@ en:
failure: 'Sorry, something went wrong.'
invalid_consumer: Invalid OAuth key.
invalid_exercise_token: Invalid exercise token.
invalid_lis_outcome_service_url: Invalid LTI outcome service URL.
invalid_signature: Invalid OAuth signature.
missing_parameters: Missing OAuth parameters.
used_nonce: Nonce has already been used.

View File

@ -65,6 +65,14 @@ RSpec.describe SessionsController do
end
end
context 'without a valid absolute LIS Outcome service URL' do
it 'refuses the LTI launch' do
allow_any_instance_of(IMS::LTI::ToolProvider).to receive(:valid_request?).and_return(true)
expect(controller).to receive(:refuse_lti_launch).with(message: I18n.t('sessions.oauth.invalid_lis_outcome_service_url')).and_call_original
post :create_through_lti, params: {oauth_consumer_key: consumer.oauth_key, oauth_nonce: nonce, oauth_signature: SecureRandom.hex, lis_outcome_service_url: '/relative/url'}
end
end
context 'without a valid exercise token' do
it 'refuses the LTI launch' do
allow_any_instance_of(IMS::LTI::ToolProvider).to receive(:valid_request?).and_return(true)
@ -75,7 +83,7 @@ RSpec.describe SessionsController do
context 'with valid launch parameters' do
let(:locale) { :de }
let(:perform_request) { post :create_through_lti, params: {custom_locale: locale, custom_token: exercise.token, oauth_consumer_key: consumer.oauth_key, oauth_nonce: nonce, oauth_signature: SecureRandom.hex, user_id: user.external_id} }
let(:perform_request) { post :create_through_lti, params: {custom_locale: locale, custom_token: exercise.token, oauth_consumer_key: consumer.oauth_key, oauth_nonce: nonce, oauth_signature: SecureRandom.hex, user_id: user.external_id, lis_outcome_service_url: 'https://example.org/'} }
let(:user) { create(:external_user, consumer:) }
before { allow_any_instance_of(IMS::LTI::ToolProvider).to receive(:valid_request?).and_return(true) }