Secure login screen

Secure login screen

by Rob Delissen -
Number of replies: 20
I would feel confident iwhen I could let my users fill in their (ldap) passwords on a https-secured login page.
Average of ratings: -
In reply to Rob Delissen

Re: Secure login screen

by Martin Dougiamas -
Picture of Core developers Picture of Documentation writers Picture of Moodle HQ Picture of Particularly helpful Moodlers Picture of Plugin developers Picture of Testers
So set one up ... mixed

Moodle runs fine under https ...
In reply to Martin Dougiamas

Re: Secure login screen

by Rob Delissen -
You mean the entire site, Martin. I was thinking about just the login page, , because of the overhead of https
In reply to Rob Delissen

Re: Secure login screen

by Martin Dougiamas -
Picture of Core developers Picture of Documentation writers Picture of Moodle HQ Picture of Particularly helpful Moodlers Picture of Plugin developers Picture of Testers
Ah, that's a little more tricky ... I guess there will have to be a $CFG->loginpage variable so the login URL can be specified separately to wwwroot, then the cookie needs to be set there so that it applies to the http site ... if anyone wants to work out the details please do!
In reply to Martin Dougiamas

Re: Secure login screen

by Paul Hague -
I was just looking at this again and trying a few things as it would be very beneficial to our site's performance.

Using this theoretical $CFG->loginpage that points to the https://... version would ....

in login/index_form.html:

<form action="<?php echo $CFG->loginpage ?>/login/index.php" method="post" name="form" id="form">

instead of:

<form action="index.php" method="post" name="form" id="form">

be the correct place to ensure a secure login?

Of course for this to work cleanly secureforms would need to be switched off which might defeat the purpose somewhat.
In reply to Paul Hague

Re: Secure login screen

by Runy Calmera -

Hi all,

Just a quick question? How secure is Moodle actually?Assuming you are hosting on an ISP, running on Apache, mysql with https:

- Can other persons (without a userid) get into a moodle course?

- If I upload confidential files, can they view these files?

- Are the files uploaded indexed by a search engine, so other people can get a link to a file in my courses, other than via the standard log in?

The reason I'm asking is that I would like to use a special course of moodle to upload "business critical" files. I don't want anybody to get in and view these files except from myself. Moodle will be my document management system, because I'm tired of Bill Gates lousy File sytem. Everytime a folder is migrated, my links and shortcuts are broken.

Thanks,

Runy

In reply to Runy Calmera

Re: Secure login screen

by Sean Keogh -
We use moodle for doing that here.  All of the support files for all of the subjects are stored in a moodle course, with a topic for each subject.  I call it The Vault.

Any registered staff or student can get in and view or download the files, but no one without a valid ID would be able to do anything.

Students cannot change anything, theoretically the staff can, but only a few have had the relevant training, so they are set as "editing" teachers, the rest as "non-editing".

Works very well.


Oxford Beardie
In reply to Martin Dougiamas

Re: Secure login screen

by Thomas Robb -
I was just talking to the computer people here at La Trobe about using their existing authentication system with my Moodle installation, which is hosted in an external server. They pointed out that while it was technically possible, they wouldn't want plaintext passwords being sent out to the server and currently there are no settings in Moodle to permit secure logins, as Martin mentions in the parent to this posting.

Would it be difficult to implement this as a standard feature? I see that no one has stepped forward to do this since the time of Martin's response (Nov. 2003).

Martin, where would this fit in to your priorities? Any other takers? I'm afraid that my technical background isn't up to the task.
In reply to Thomas Robb

Re: Secure login screen

by Martin Dougiamas -
Picture of Core developers Picture of Documentation writers Picture of Moodle HQ Picture of Particularly helpful Moodlers Picture of Plugin developers Picture of Testers
The problem is that https security is not a Moodle thing or a PHP thing - it's a web server thing. You have to set up Apache with a certificate. Real certificates cost $$$. You can make a fake one for free but your users will get dialog warnings about the site being possibly insecure, which isn't nice.

It's quite possible and relatively easy to put all of Moodle under a https server now - it will work fine and I don't find performance to be affected THAT much by having every page encyrypted (then again I'm on ADSL).

If performance is an issue, then you have to run TWO servers, one http and one https, and they have to share session information (on the server side) so that the session cookie generated on the https server isent to the browser, which then sends it back to the http server which then finds the session info and continues the session cleanly.

The only Moodle mod needed would be a variable to specify the https login page and then a little code to make sure it gets used every time a redirect to the login page (ie /login/index.php) is performed. If the wwwroot of Moodle is set to be the http server then it should go back to http automatically after the login.
In reply to Martin Dougiamas

Re: Secure login screen

by Zbigniew Fiedorowicz -

We use a secure server for our entire Moodle installation. There is no special setup for running Moodle under https as opposed to http. Our sysdadmin estimates that the performance penalty for doing this is less than 10%. We bought our server certificate from: http://www.comodo.net/. It costs us $50 per annum, hardly $$$.

However, I've just added a new form of authentication to our Moodle, entitled "Custom authentication", which among other things allows having a secure login page, but running the rest of Moodle under a nonsecure web server.  I'll be sending my mods to Martin for his consideration for inclusion in version 1.2.

In reply to Thomas Robb

Re: Secure login screen

by John Papaioannou -
I know this isn't completely relevant with the LDAP discussion, but as to passwords being sent "in the clear" when users log on:

There is a solution to prevent this, even when using normal HTTP. However, it requires that session information is kept on the server itself, and not in cookies (which may be a big performance hit on the server if you have 1000s of users in at once). I actually have code which does exactly that, and use it in the login screen of my home-made application framework. It goes something like this:


  1. The user's browser contacts the server. The server sees the user has no session information and prepares for login. The server produces a random number, stores it in the user's session variables and sends it back with http.
  2. The user's login page is displayed. The user writes username and password and submits.
  3. The page has an onSubmit event, which runs some JavaScript code. The code calculates the MD5 hash of the password and sets the value of some hidden field to it. The "clear" password field (which the user just set) is set to an empty string.
  4. The cleartext username, MD5 of password, and cleartext random number (which the server sent us) are returned with the HTTP form.
  5. The server checks to see if the random number is the same as in its local session variables. Then it checks the username and MD5 of password (remember passwords are stored as hashes in the database). If everything matches, the user is authenticated. We can now unset the random number. If not, change the random number to something else and repeat ad nauseum.

The advantages of this method are:

  1. ADOdb (which Moodle uses) makes it very easy to have session vars in MySQL. There is the matter of the performance hit, but in my case there is no contest, since using cookies exposes you to a whole new class of problems.
  2. It's very easy to implement (just a little JavaScript and 10 lines of code in your page, the server-side logic is about one pageful of self-evident code).
  3. It's secure against eavesdropping (the attacker knows the MD5 of your password, but doesn't know your password).
  4. It's secure against replay attacks (even if later he tries to use spoofed TCP packets, he won't be able to login after your session has expired. The random number he would have to send has changed).

There are two disadvantages:

  1. The performance hit.
  2. You cannot use this method if the server needs the cleartext password for some reason (e.g. to authenticate you with another server). I 'm not familiar with how LDAP works, but it probably falls in this case.

I hope that someone finds some of this helpful! smile
In reply to John Papaioannou

Re: Secure login screen

by Martin Dougiamas -
Picture of Core developers Picture of Documentation writers Picture of Moodle HQ Picture of Particularly helpful Moodlers Picture of Plugin developers Picture of Testers
Great idea! Found scripts here:

http://pajhome.org.uk/crypt/md5/

The server-side session stuff is no trouble, as we already have that set up (just set/unset variables in $SESSION variable), and we can put a refresh of 15 minutes or so on the login page to make sure the session stays active.  To start with it only makes sense when using internal authentication, I think.

It does make Javascript a mandatory thing for students, which currently is not the case, but I think most admins would be happy to make this tradeoff (it will be an option, of course). 
In reply to Martin Dougiamas

Re: Secure login screen

by John Papaioannou -
LOL.... big grin

That's where I got the scripts when I read about and decided to use this scheme too! big grin

So, since you 're interested:

Javascript and HTML (for the login form):

<script type='text/javascript'>
function onLoginSubmit() {
var f = document.forms[0];
if (!f) {alert('Your browser is not compatible.'); return false;}
f.encoded_pass.value = calcMD5(f.passwd.value);
f.encoded_rand.value = calcMD5(f.randval.value);
f.passwd.value='';
return true;
}
</script>

HTML editor workaround: Intentional blank space left between "on" and "submit"

<form on submit="return onLoginSubmit();" name="logon" method="post" action="index.php">

<!--
Other fields and submit button here. You will need to match the fieldnames
with those present in the onLoginSubmit() function above.
-->

<input type='hidden' name='encoded_pass' value='' />
<input type='hidden' name='encoded_rand' value='' />
<input type='hidden' name='randval' value = '{$SESSION_RANDVAL}' />
<input type='hidden' name='action' value='login' />

</form>



PHP code (login module):

<?php

if(!isset($_REQUEST['op'])) $_REQUEST['op'] = ''; // Gets rid of an E_NOTICE just below

switch($_REQUEST['op']) {
default:
case 'login':
if(!$GLOBALS['APP']->UserLoggedIn()) {
op_login();
}
else {
$GLOBALS['APP']->ModuleActivate();
}
break;
case 'logout':
if($GLOBALS['APP']->UserLoggedIn()) op_logout();
else op_login();
break;
}


function op_login()
{
if(isset($_POST['encoded_pass']) &&
isset($_POST['encoded_rand']) &&
isset($_SESSION['randval']) &&
$_POST['encoded_rand'] == md5($_SESSION['randval']) &&
!empty($_POST['username']))
{
if(!ereg('[a-z0-9]', $_POST['encoded_pass'])) {
$GLOBALS['APP']->ModuleActivate('reset');
}
if(ereg('['"]', $_POST['username'])) {
$GLOBALS['APP']->ModuleActivate('reset');
}
$userinfo = $GLOBALS['DBCONN']->GetRow('SELECT UserID, Username FROM '.
DB_Table('users').' WHERE Password=''.$_POST['encoded_pass'].
'' AND Username=''.$_POST['username'].''');
if(!empty($userinfo) && $userinfo['Username'] == $_POST['username'])
{
// Login successful
unset($_SESSION['randval']);
$_SESSION['user'] = $userinfo['Username'];
$_SESSION['userID'] = $userinfo['UserID'];
$GLOBALS['APP']->ModuleActivate(); // Default module
}
else
{
// Login failed
// display some message
$GLOBALS['ERROR_MSGS'][$_REQUEST['action']][] =
'Bad username/password';
$GLOBALS['SMARTY']->assign(array(
'SESSION_RANDVAL' => $_SESSION['randval'],
));
}
}
else
{
// Display login form
if(!isset($_SESSION['randval'])) {
mt_srand ((double) microtime() * 1000000);
$_SESSION['randval'] = mt_rand();
}
$GLOBALS['SMARTY']->assign(array(
'SESSION_RANDVAL' => $_SESSION['randval'],
));
}
}

function op_logout()
{
$_SESSION = array();
session_destroy();
$GLOBALS['APP']->ModuleActivate($GLOBALS['module']);
}

?>


General Notes:

I 've noticed that my strings have been unslashed. Keep this in mind, you 'll get some syntax errors as it is (single quotes within singly quoted strings).

$GLOBALS['DBCONN'] is an ADOdb connection.
$GLOBALS['SMARTY'] is... what its name says! You 'll have to change things a bit, and of course the random number value in the HTML form will have to be given "by hand".
$GLOBALS['APP'] is my Application object. In this snippet only 2 methods are exposed:

UserLoggedIn() returns true if there is session information and it says that this is a logged-in user.

ModuleActivate($module) loads and activates a module. Without arguments it activates the "main" module (this is what I do when the user successfully logs in). The ModuleActivate('reset') call just displays a screen which says something to the lines of "Security precaution: your session has been reset. Please login in again." and destroys all session variables. (This means that on the next login page access, a new random number will be assigned).

In reply to Martin Dougiamas

Re: Secure login screen

by Paolo Oprandi -
I just moved login/index.php to the https server and redirected in httpd.conf and it seems to work fine. Should I also move index_form.html and/or other files to the secure server?
In reply to Paolo Oprandi

Re: Secure login screen

by Martin Dougiamas -
Picture of Core developers Picture of Documentation writers Picture of Moodle HQ Picture of Particularly helpful Moodlers Picture of Plugin developers Picture of Testers
This thread is old ... there is a solution now.

Set up the two sites so that the sites share exactly the same directory, and use the setting on admin >> configuration >> variables called "loginhttps" ... it will redirect people to the https page for the login, and the redirect them back afterwards.
In reply to Martin Dougiamas

Re: Secure login screen

by Paolo Oprandi -
Thanks Martin for your prompt reply, but I don't get it. I downloaded moodle in early June and am running version 1.226.4.5 and I don't have a setting in admin >> configuration >> variables called loginhttps although the variable name sounds familiar.

Also when I do find it should I have a complete copy of moodle on the secure server or just the login and/or auth directory?

Thanks,
Paolo
In reply to Paolo Oprandi

Re: Secure login screen

by Martin Dougiamas -
Picture of Core developers Picture of Documentation writers Picture of Moodle HQ Picture of Particularly helpful Moodlers Picture of Plugin developers Picture of Testers
The variable was probably added to the page in 1.4 ... before that you can just add

$CFG->loginhttps = true;

in the config.php file.

The best way is NOT to have any separate copies of any files. Have one single copy, and set up your server to use that same set of files for access on port 80 (http) and port 443 (https).
In reply to Martin Dougiamas

Re: Secure login screen

by Ray Jr -

Hello Martin,

First, I just would like to say thanks for leading the way in creating such a wonderful virtual learning environment!!! (this is my first post to the Moodle community)

I recently installed Moodle 1.4.2. and I did notice the loginhttps variable on the admin configuration page. However, it was locked and I couldn't change the setting. Is this by design? If yes, why?

The web hosting company that I use does support https. I just have to name a folder in my wwwroot directory called ssl and place any page I want encrypted into this ssl folder. Can I just move the login/index.php page to this ssl folder? If yes, what other changes would I have to make to get this to work (secure the login screen)?

Best regards,

Ray

In reply to Ray Jr

Re: Secure login screen

by warmac - -
can every one speak english he he i don't understand a word that any of you are saying all this computer terminology is making my head spin.

A good system is one that is easy to use and understand by the one at the keyboard, developers will do good to remember this. If a folder has too many files and complexed coding then its to difficult

That's my $1.98 cents worth lol :D