Commit 69bcdb52 authored by Cecilia Vela Gurovic's avatar Cecilia Vela Gurovic
Browse files

Security Bug 1701978: fix session cookie issues

1. when a user logs in it clears any obsolete
   usr_session cookies for the user
2. recording the user-agent of the session
   and if it changes to prompt the user to
   login again
3. when self adding / editing email address(es)
   send 2 emails
	- one to the new email address asking user to confirm address
	- and one to the primary email address to alert user
	that a new email is being added to their account and
	if this is bad how to contact their admin about the problem.

behatnotneeded
Change-Id: Ia44b66cf831abd553b72aa8b1d58d2a2634863b8
parent a732649d
Loading
Loading
Loading
Loading
+31 −4
Original line number Diff line number Diff line
@@ -265,6 +265,7 @@ function profileform_submit(Pieform $form, $values) {
    $email_errors = array();

    $lockedfields = locked_profile_fields();
    $alertuserofnewemail = array();

    foreach ($element_list as $element => $type) {

@@ -290,6 +291,8 @@ function profileform_submit(Pieform $form, $values) {
                $key_url_decline = $key_url . '&decline=1';

                try {
                    $alertuserofnewemail[] = $email;

                    $sitename = get_config('sitename');
                    email_user(
                        (object)array(
@@ -323,6 +326,33 @@ function profileform_submit(Pieform $form, $values) {
                );
            }

            // alert user that new email addresses have been added
            if (!empty($alertuserofnewemail)) {
                $emails = implode(', ', $alertuserofnewemail);
                try {
                    $sitename = get_config('sitename');
                    email_user(
                        (object)array(
                            'id'            => $USER->get('id'),
                            'username'      => $USER->get('username'),
                            'firstname'     => $USER->get('firstname'),
                            'lastname'      => $USER->get('lastname'),
                            'preferredname' => $USER->get('preferredname'),
                            'admin'         => $USER->get('admin'),
                            'staff'         => $USER->get('staff'),
                            'email'         => $profilefields['email']['default'],
                        ),
                        null,
                        get_string('newemailalert_subject', 'artefact.internal', $sitename),
                        get_string('newemailalert_body_text', 'artefact.internal', $USER->get('firstname'), $sitename, $emails, $sitename, get_config('wwwroot')),
                        get_string('newemailalert_body_html', 'artefact.internal', hsc($USER->get('firstname')), hsc($sitename), hsc($emails), hsc($sitename), get_config('wwwroot'))
                    );
                }
                catch (EmailException $e) {
                    $email_errors[] = $profilefields['email']['default'];
                }
            }

            // remove old addresses
            foreach ($profilefields['email']['validated'] as $email) {
                if (in_array($email, $values['email']['validated'])) {
@@ -393,10 +423,7 @@ function profileform_submit(Pieform $form, $values) {
                $USER->commit();
            }
        }
        else if ($element == 'maildisabled') {
            continue;
        }
        else if ($element == 'socialprofile') {
        else if (in_array($element, array('maildisabled', 'socialprofile'))) {
            continue;
        }
        else {
+23 −0
Original line number Diff line number Diff line
@@ -96,6 +96,29 @@ You have added the email address %s to your user account in %s. Please visit the
If this email belongs to you, but you have not requested adding it to your %s account, follow the link below to decline the email activation.

%s
EOF;
$string['newemailalert_subject'] = 'New email address added to your %s account';
$string['newemailalert_body_text'] = <<<EOF
Hello %s,

You have added the email addresses to your user account in %s:

%s

If you have not requested this change in your %s account, please contact the site administrator

%scontact.php

EOF;
$string['newemailalert_body_html'] = <<<EOF
<p>Hello %s,</p>

<p>You have added the email addresses to your user account in %s:</p>

<p>%s</p>

<p>If you have not requested this change in your %s account, please <a href="%scontact.php">contact the site administrator</a></p>

EOF;

$string['validationemailwillbesent'] = 'A validation email will be sent when you save your profile.';
+3 −1
Original line number Diff line number Diff line
@@ -417,7 +417,9 @@ function auth_setup () {
    // reset the password clearing the session from usr_session.
    $sessionexists = get_record('usr_session', 'usr', $USER->id, 'session', $USER->get('sessionid'));
    $parentuser = $USER->get('parentuser');
    if (($sessionlogouttime && isset($_GET['logout'])) || ($sessionexists === false && $USER->get('sessionid') != '' && empty($parentuser))) {
    if (($sessionlogouttime && isset($_GET['logout']))
       || ($sessionexists === false && $USER->get('sessionid') != '' && empty($parentuser))
       || ($sessionexists && isset($sessionexists->useragent) && $sessionexists->useragent != $_SERVER['HTTP_USER_AGENT'])) {
        // Call the authinstance' logout hook
        $authinstance = $SESSION->get('authinstance');
        if ($authinstance) {
+6 −1
Original line number Diff line number Diff line
@@ -1843,12 +1843,17 @@ class LiveUser extends User {

    private function store_sessionid() {
        $sessionid = $this->get('sessionid');
        delete_records('usr_session', 'session', $sessionid);
        delete_records('usr_session', 'usr', $this->get('id'));
        $useragent = 'unknown';
        if (isset($_SERVER['HTTP_USER_AGENT'])) {
            $useragent = $_SERVER['HTTP_USER_AGENT'];
        }
        insert_record('usr_session', (object) array(
            'usr' => $this->get('id'),
            'session' => $sessionid,
            'ctime' => db_format_timestamp(time()),
            'mtime' => db_format_timestamp(time()),
            'useragent' => $useragent,
        ));
    }

+1 −0
Original line number Diff line number Diff line
@@ -227,6 +227,7 @@
                <FIELD NAME="session" TYPE="char" LENGTH="255" NOTNULL="true" />
                <FIELD NAME="ctime" TYPE="datetime" NOTNULL="true"/>
                <FIELD NAME="mtime" TYPE="datetime" NOTNULL="false"/>
                <FIELD NAME="useragent" TYPE="text" LENGTH="small" NOTNULL="false"/>
            </FIELDS>
            <KEYS>
                <KEY NAME="primary" TYPE="primary" FIELDS="session" />
Loading