From beaabe222a6dd971c9c6726f5fa1bef99220c84e Mon Sep 17 00:00:00 2001 From: Alex Jordan Date: Wed, 20 Dec 2023 19:51:26 -0800 Subject: [PATCH 1/4] do not allow LTI access to admin course --- lib/WeBWorK/Authen.pm | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lib/WeBWorK/Authen.pm b/lib/WeBWorK/Authen.pm index 962dc3d9c5..ff9cd2de24 100644 --- a/lib/WeBWorK/Authen.pm +++ b/lib/WeBWorK/Authen.pm @@ -152,6 +152,18 @@ sub verify { debug('BEGIN VERIFY'); return $self->call_next_authen_method if !$self->request_has_data_for_this_verification_module; + my $authen_ref = ref($self); + if ($c->ce->{courseName} eq $c->ce->{admin_course_id} + && !(grep {/^$authen_ref$/} @{ $c->ce->{authen}{admin_module} })) + { + $self->write_log_entry("Cannot authenticate into admin course using $authen_ref."); + $c->stash( + authen_error => $c->maketext( + 'There was an error during the login process. Please speak to your instructor or system administrator.' + ) + ); + return $self->call_next_authen_method(); + } $self->{was_verified} = $self->do_verify; From 662473f72c308918e6bb40c521f48dc49cc3c22d Mon Sep 17 00:00:00 2001 From: Alex Jordan Date: Sat, 23 Dec 2023 14:38:01 -0800 Subject: [PATCH 2/4] make it configurable which authentication modules can be used for the admin course --- conf/authen_CAS.conf.dist | 18 ++++++++++++++ conf/authen_LTI.conf.dist | 20 +++++++++++++++ conf/authen_ldap.conf.dist | 18 ++++++++++++++ conf/defaults.config | 31 ++++++++++++----------- conf/localOverrides.conf.dist | 47 ++++++++++++++++++++++++++++++++++- 5 files changed, 118 insertions(+), 16 deletions(-) diff --git a/conf/authen_CAS.conf.dist b/conf/authen_CAS.conf.dist index 67f482b21e..aa1cc059af 100644 --- a/conf/authen_CAS.conf.dist +++ b/conf/authen_CAS.conf.dist @@ -12,6 +12,24 @@ $authen{user_module} = { "*" => "WeBWorK::Authen::CAS", }; +# List of authentication modules that may be used to enter the admin course. +# This should be a non-empty sublist of whatever is in $authen{user_module}. +# Since the admin course provides overall power to add/delete courses, access +# to this course should be protected by the best possible authentication you +# have available to you. The current default is +# WeBWorK::Authen::Basic_TheLastOption which is simple password based +# authentication for a password locally stored in your WeBWorK server's +# database. On one hand, this is necessary as the initial setting, as it is the +# only option available when a new server is being installed. However, since +# this option does not make use of multi-factor authentication or provide any +# capabilities to prevent dictionary attacks, etc. At the very least you should +# use a very strong password. If you have the option to use a more secure +# authentication approach to the admin course (one which you are confident +# cannot be spoofed) that is preferable. +$authen{admin_module} = [ + 'WeBWorK::Authen::CAS' +]; + $authen{cas_options} = { # Options to pass to the AuthCAS module. # Note that this is (plain) AuthCAS, not Apache::AuthCAS diff --git a/conf/authen_LTI.conf.dist b/conf/authen_LTI.conf.dist index 091bdc4e89..fa06a79503 100644 --- a/conf/authen_LTI.conf.dist +++ b/conf/authen_LTI.conf.dist @@ -45,6 +45,26 @@ $authen{user_module} = [ { '*' => 'WeBWorK::Authen::Basic_TheLastOption' } # fallback authorization method ]; +# List of authentication modules that may be used to enter the admin course. +# This should be a non-empty sublist of whatever is in $authen{user_module}. +# Since the admin course provides overall power to add/delete courses, access +# to this course should be protected by the best possible authentication you +# have available to you. The current default is +# WeBWorK::Authen::Basic_TheLastOption which is simple password based +# authentication for a password locally stored in your WeBWorK server's +# database. On one hand, this is necessary as the initial setting, as it is the +# only option available when a new server is being installed. However, since +# this option does not make use of multi-factor authentication or provide any +# capabilities to prevent dictionary attacks, etc. At the very least you should +# use a very strong password. If you have the option to use a more secure +# authentication approach to the admin course (one which you are confident +# cannot be spoofed) that is preferable. +$authen{admin_module} = [ + 'WeBWorK::Authen::LTIAdvantage', + 'WeBWorK::Authen::LTIAdvanced', + 'WeBWorK::Authen::Basic_TheLastOption' +]; + # Include configurations. You must uncomment at least one of the following. You may uncomment # both if the site may be using both LTI 1.1 and 1.3 in different courses. After uncommenting # the LTI_1_x line, you must copy the file authen_LTI_1_x.conf.dist to authen_LTI_1_x.conf and diff --git a/conf/authen_ldap.conf.dist b/conf/authen_ldap.conf.dist index e895334729..d6fcb18c77 100644 --- a/conf/authen_ldap.conf.dist +++ b/conf/authen_ldap.conf.dist @@ -12,6 +12,24 @@ $authen{user_module} = { "*" => "WeBWorK::Authen::LDAP", }; +# List of authentication modules that may be used to enter the admin course. +# This should be a non-empty sublist of whatever is in $authen{user_module}. +# Since the admin course provides overall power to add/delete courses, access +# to this course should be protected by the best possible authentication you +# have available to you. The current default is +# WeBWorK::Authen::Basic_TheLastOption which is simple password based +# authentication for a password locally stored in your WeBWorK server's +# database. On one hand, this is necessary as the initial setting, as it is the +# only option available when a new server is being installed. However, since +# this option does not make use of multi-factor authentication or provide any +# capabilities to prevent dictionary attacks, etc. At the very least you should +# use a very strong password. If you have the option to use a more secure +# authentication approach to the admin course (one which you are confident +# cannot be spoofed) that is preferable. +$authen{admin_module} = [ + 'WeBWorK::Authen::LDAP' +]; + $authen{ldap_options} = { # hosts to attempt to connect to, in order. For example: # auth.myschool.edu -- uses LDAP scheme and port 389 diff --git a/conf/defaults.config b/conf/defaults.config index aca53eab22..b65958fbda 100644 --- a/conf/defaults.config +++ b/conf/defaults.config @@ -716,28 +716,29 @@ $modelCoursesForCopy = [ "modelCourse" ]; # Select the authentication module to use for normal logins. # # If this value is a string, the given authentication module will be used -# regardless of the database layout. If it is a hash, the database layout name -# will be looked up in the hash and the resulting value will be used as the -# authentication module. The special hash key "*" is used if no entry for the -# current database layout is found. -# If this value is a sequence of strings or hashes, then each -# string or hash in the sequence will be successively tested to see if it -# provides a module that can handle -# the authentication request (by calling the module's -# sub request_has_data_for_this_verification_module ). -# The first module that responds affirmatively will be used. +# regardless of the database layout. # +# If it is a hash, the database layout name will be looked up in the hash and +# the resulting value will be used as the authentication module. The special +# hash key "*" is used if no entry for the current database layout is found. # -$authen{user_module} = { - # sql_moodle => "WeBWorK::Authen::Moodle", - # sql_ldap => "WeBWorK::Authen::LDAP", - "*" => "WeBWorK::Authen::Basic_TheLastOption", -}; +# If this value is a sequence of strings or hashes, then each string or hash in +# the sequence will be successively tested to see if it provides a module that +# can handle the authentication request by calling the module's sub +# request_has_data_for_this_verification_module(). The first module that +# responds affirmatively will be used. + +$authen{user_module} = {"*" => "WeBWorK::Authen::Basic_TheLastOption"}; # Select the authentication module to use for proctor logins. # A string or a hash is accepted, as above. $authen{proctor_module} = "WeBWorK::Authen::Proctor"; +# List of authentication modules that may be used to enter the admin course. +# This should always be an array reference with a subset of the modules named +# in $authen{user_module}. +$authen{admin_module} = ['WeBWorK::Authen::Basic_TheLastOption']; + ################################################################################ # Authorization system (Make local overrides in localOverrides.conf ) ################################################################################ diff --git a/conf/localOverrides.conf.dist b/conf/localOverrides.conf.dist index 453d6197ae..0e137037fc 100644 --- a/conf/localOverrides.conf.dist +++ b/conf/localOverrides.conf.dist @@ -437,12 +437,57 @@ $mail{feedbackRecipients} = [ # END_PREAMBLE ################################################################################ -# Authentication Methods +# Authentication ################################################################################ # Extra modules have been created to allow WeBWorK to use certain external # methods of authentication. +# Select the authentication module to use for normal logins. +# +# If this value is a string, the given authentication module will be used +# regardless of the database layout. +# +# If it is a hash, the database layout name will be looked up in the hash and +# the resulting value will be used as the authentication module. The special +# hash key "*" is used if no entry for the current database layout is found. +# +# If this value is a sequence of strings or hashes, then each string or hash in +# the sequence will be successively tested to see if it provides a module that +# can handle the authentication request by calling the module's sub +# request_has_data_for_this_verification_module(). The first module that +# responds affirmatively will be used. + +#$authen{user_module} = { +# sql_moodle => "WeBWorK::Authen::Moodle", +# sql_ldap => "WeBWorK::Authen::LDAP" +# "*" => "WeBWorK::Authen::Basic_TheLastOption" +#}; + +# Select the authentication module to use for proctor logins. +# A string or a hash is accepted, as above. +#$authen{proctor_module} = "WeBWorK::Authen::Proctor"; + +# List of authentication modules that may be used to enter the admin course. +# This should be a non-empty sublist of whatever is in $authen{user_module}. +# Since the admin course provides overall power to add/delete courses, access +# to this course should be protected by the best possible authentication you +# have available to you. The current default is +# WeBWorK::Authen::Basic_TheLastOption which is simple password based +# authentication for a password locally stored in your WeBWorK server's +# database. On one hand, this is necessary as the initial setting, as it is the +# only option available when a new server is being installed. However, since +# this option does not make use of multi-factor authentication or provide any +# capabilities to prevent dictionary attacks, etc. At the very least you should +# use a very strong password. If you have the option to use a more secure +# authentication approach to the admin course (one which you are confident +# cannot be spoofed) that is preferable. +#$authen{admin_module} = [ +# 'WeBWorK::Authen::Moodle', +# 'WeBWorK::Authen::LDAP', +# 'WeBWorK::Authen::Basic_TheLastOption' +#]; + ################################################################################ # IMS LTI Authentication ################################################################################ From 08dc828a9302d8ad4fcd87739a5b96394f53809b Mon Sep 17 00:00:00 2001 From: Alex Jordan Date: Fri, 9 Feb 2024 12:01:36 -0800 Subject: [PATCH 3/4] change the default for LTI access to the admin course --- conf/authen_LTI.conf.dist | 4 ++-- conf/localOverrides.conf.dist | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/conf/authen_LTI.conf.dist b/conf/authen_LTI.conf.dist index fa06a79503..b1aa65746e 100644 --- a/conf/authen_LTI.conf.dist +++ b/conf/authen_LTI.conf.dist @@ -60,8 +60,8 @@ $authen{user_module} = [ # authentication approach to the admin course (one which you are confident # cannot be spoofed) that is preferable. $authen{admin_module} = [ - 'WeBWorK::Authen::LTIAdvantage', - 'WeBWorK::Authen::LTIAdvanced', + #'WeBWorK::Authen::LTIAdvantage', + #'WeBWorK::Authen::LTIAdvanced', 'WeBWorK::Authen::Basic_TheLastOption' ]; diff --git a/conf/localOverrides.conf.dist b/conf/localOverrides.conf.dist index 0e137037fc..0604d1f5b2 100644 --- a/conf/localOverrides.conf.dist +++ b/conf/localOverrides.conf.dist @@ -482,6 +482,10 @@ $mail{feedbackRecipients} = [ # use a very strong password. If you have the option to use a more secure # authentication approach to the admin course (one which you are confident # cannot be spoofed) that is preferable. +# +# Note that if you include authentication module config files further down, +# those may override the setting of $authen{admin_module} here. + #$authen{admin_module} = [ # 'WeBWorK::Authen::Moodle', # 'WeBWorK::Authen::LDAP', From 00642b4fe695acd4b6da4dc4a05be173bc501dd6 Mon Sep 17 00:00:00 2001 From: Alex Jordan Date: Wed, 14 Feb 2024 13:54:43 -0800 Subject: [PATCH 4/4] suggested edits from PR#2292 --- conf/authen_CAS.conf.dist | 11 +---------- conf/authen_ldap.conf.dist | 11 +---------- 2 files changed, 2 insertions(+), 20 deletions(-) diff --git a/conf/authen_CAS.conf.dist b/conf/authen_CAS.conf.dist index aa1cc059af..b6393fb5d8 100644 --- a/conf/authen_CAS.conf.dist +++ b/conf/authen_CAS.conf.dist @@ -16,16 +16,7 @@ $authen{user_module} = { # This should be a non-empty sublist of whatever is in $authen{user_module}. # Since the admin course provides overall power to add/delete courses, access # to this course should be protected by the best possible authentication you -# have available to you. The current default is -# WeBWorK::Authen::Basic_TheLastOption which is simple password based -# authentication for a password locally stored in your WeBWorK server's -# database. On one hand, this is necessary as the initial setting, as it is the -# only option available when a new server is being installed. However, since -# this option does not make use of multi-factor authentication or provide any -# capabilities to prevent dictionary attacks, etc. At the very least you should -# use a very strong password. If you have the option to use a more secure -# authentication approach to the admin course (one which you are confident -# cannot be spoofed) that is preferable. +# have available to you. $authen{admin_module} = [ 'WeBWorK::Authen::CAS' ]; diff --git a/conf/authen_ldap.conf.dist b/conf/authen_ldap.conf.dist index d6fcb18c77..3d794b96bb 100644 --- a/conf/authen_ldap.conf.dist +++ b/conf/authen_ldap.conf.dist @@ -16,16 +16,7 @@ $authen{user_module} = { # This should be a non-empty sublist of whatever is in $authen{user_module}. # Since the admin course provides overall power to add/delete courses, access # to this course should be protected by the best possible authentication you -# have available to you. The current default is -# WeBWorK::Authen::Basic_TheLastOption which is simple password based -# authentication for a password locally stored in your WeBWorK server's -# database. On one hand, this is necessary as the initial setting, as it is the -# only option available when a new server is being installed. However, since -# this option does not make use of multi-factor authentication or provide any -# capabilities to prevent dictionary attacks, etc. At the very least you should -# use a very strong password. If you have the option to use a more secure -# authentication approach to the admin course (one which you are confident -# cannot be spoofed) that is preferable. +# have available to you. $authen{admin_module} = [ 'WeBWorK::Authen::LDAP' ];