Discussion:
[TYPO3-english] fe_typo_user cookie: Changes from 6.2.3 to 6.2.4
Valentin R
2014-11-13 12:28:37 UTC
Permalink
Hi Forum,

we have an extranet with a closed usergroup where the users can login using their username as a parameter to the URL. (This is not a security issue because the user does not have any influence on this parameter)!

If the user wants to login but already has got the fe_typo_user cookie the behaviour was as follows using Typo3 6.2.3 (shortened output of tcpdump):

GET /index.php?user=40026706 HTTP/1.1
Cookie: nc_staticfilecache=fe_typo_user_logged_in; fe_typo_user=6c3b39633e778b771c9289fcd0e4cfec

HTTP/1.1 303 See Other
Location: ht tp://entextranet.company.com/index.php?id=2
Set-Cookie: fe_typo_user=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/
Set-Cookie: fe_typo_user=6c3b39633e778b771c9289fcd0e4cfec; path=/; httponly

The old cookie was deleted and a new cookie is set and therefore the user is logged in successfully!

If the user wants to login but already has got the fe_typo_user cookie the behaviour was as follows using Typo3 6.2.4+ (shortened output of tcpdump):

GET /index.php?user=40026706 HTTP/1.1
Cookie: nc_staticfilecache=fe_typo_user_logged_in; fe_typo_user=95baf7ae6ed0037092004c6e1707c685

HTTP/1.1 303 See Other
Location: ht tp://entextranet.company.com/index.php?id=2
Set-Cookie: fe_typo_user=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/
Set-Cookie: nc_staticfilecache=fe_typo_user_logged_in; path=/

Unfortunately, a new cookie was not set any longer and therefore the user is not logged in :-(

The next time the user tries to login the cookie is set correctly, but this is not workaround ...

Any help is highly appreciated,

TIA, Valentin
Helmut Hummel
2014-11-15 18:03:50 UTC
Permalink
Hi!
Post by Valentin R
we have an extranet with a closed usergroup where the users can login using their username as a parameter to the URL. (This is not a security issue because the user does not have any influence on this parameter)!
How did you implement this functionality?
Post by Valentin R
If the user wants to login but already has got the fe_typo_user cookie
A cookie is only sent if there is something stored in an (anonymous)
session (fe_session_data table).
Post by Valentin R
Set-Cookie: fe_typo_user=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/
Set-Cookie: fe_typo_user=6c3b39633e778b771c9289fcd0e4cfec; path=/; httponly
The old cookie was deleted and a new cookie is set and therefore the user is logged in successfully!
Which is still buggy, as the cookie should neither have been deleted,
nor set again (browser sent the cookie, there is a session id already
which is now going to be used for the authenticated session.
Post by Valentin R
Set-Cookie: fe_typo_user=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/
This only happens, if you make use of the logoff_pre_processing or
logoff_post_processing and delete the session data (fe_session_data
table) belonging the the current session id.

The thing is, that during an authentication request (login) ->logoff()
is called to make sure no other session with that id is already present.
This means the logoff hooks I mentioned above are also called during
*login*! If there are hook subscribers that delete the session data, the
cookie will be removed (as logoff is requested and neither a session,
nor session data is present).

HTH

Kind regards,
Helmut
--
Helmut Hummel
Release Manager TYPO3 6.0
TYPO3 CMS Active Contributor, TYPO3 Security Team Member

TYPO3 .... inspiring people to share!
Get involved: typo3.org
Valentin R
2014-11-18 10:51:03 UTC
Permalink
Hi Helmut!

thanks for your quick response!

We have implemented the functionality of login via parameter ( GET /index.php?username=xyz ) via an extbase extension.
A rough description:

* Classes/Service/TerminalAccessService.php:
class TerminalAccessService extends \TYPO3\CMS\Sv\AbstractAuthenticationService {

/**
* Sets login credentials based on HTTP Basic Auth
*
* @param array $loginData
* @param string $passwordTransmissionStrategy
* @return integer
*/
public function processLoginData(&$loginData, $passwordTransmissionStrategy = '') {
$loginData['uname'] = $_GET['username'];
$loginData['uident'] = \TYPO3\CMS\Core\Utility\GeneralUtility::getRandomHexString(10);
$loginData['uident_text'] = \TYPO3\CMS\Core\Utility\GeneralUtility::getRandomHexString(10);

return TRUE;
}

/**
* Initializes the service and checks for availability
*
* @return boolean
*/
public function init() {
$available = parent::init();
if ($available) {
if (!self::isAvailable()) {
$available = FALSE;
}

}
return $available;
}

/**
* @return bool
*/
static public function isAvailable() {
$iprange = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['terminal_auth']['ipRangeForTerminal'];
if ( cidr_match($_SERVER['REMOTE_ADDR'],$iprange) && isset($_GET['username'])) {
return TRUE;
}
return FALSE;
}

public function compareUident($user,$loginData,$passwordCompareStrategy='') {
return TRUE;
}

public function authUser($user) {
return 200;
}
}

* Classes/Hook/FrontendPreProcessRequestHook.php:
public function initializeTerminalAuthIfApplicable() {
if (\Company\TerminalAuth\Service\TerminalAccessService::isAvailable()) {
\TYPO3\CMS\Core\Utility\GeneralUtility::_GETset('login', 'logintype');
$GLOBALS['TYPO3_CONF_VARS']['FE']['checkFeUserPid'] = FALSE;
}
}

--

We have inspected the behaviour of Typo3 6.2.3 in more detail.
Post by Helmut Hummel
Post by Valentin R
Set-Cookie: fe_typo_user=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/
Set-Cookie: fe_typo_user=6c3b39633e778b771c9289fcd0e4cfec; path=/; httponly
Nothing is stored in the table fe_session_data, but we have a long living entry in fe_session (joined with fe_users to display username and lastlogin):

| username | ses_id | ses_name | ses_iplock | ses_hashlock | ses_userid | ses_permanent | ses_data | lastaction | lastlogin |
| ***@xyza | 6c3b39633e778b771c9289fcd0e4cfec | fe_typo_user | 192.168 | 112396423 | 296509 | 0 | NULL | 2014-11-17 15:40:23 | 2014-11-17 15:40:21 |

Unfortunately, we do not have a explicit logoff requests and no influence on that because the client boxes are under responsiblity of our vendor.
We only have login requests.
Post by Helmut Hummel
The thing is, that during an authentication request (login) ->logoff()
is called to make sure no other session with that id is already present.
This means the logoff hooks I mentioned above are also called during
*login*! If there are hook subscribers that delete the session data, the
cookie will be removed (as logoff is requested and neither a session,
nor session data is present).
Helmut: is it possible to adapt our extension that the logoff hook is not called?
Then everything should be fine, except that we have to clean up the fe_session table from while to while ...

Best regards, Valentin
Helmut Hummel
2014-11-21 15:57:14 UTC
Permalink
Hi Valentin!
Post by Valentin R
We have implemented the functionality of login via parameter ( GET /index.php?username=xyz ) via an extbase extension.
Looks fine so far, except that you are authenticating the user on every
request (forcing logintype set to login)
Post by Valentin R
We have inspected the behaviour of Typo3 6.2.3 in more detail.
Post by Valentin R
Set-Cookie: fe_typo_user=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/
Set-Cookie: fe_typo_user=6c3b39633e778b771c9289fcd0e4cfec; path=/; httponly
| username | ses_id | ses_name | ses_iplock | ses_hashlock | ses_userid | ses_permanent | ses_data | lastaction | lastlogin |
Where does this session come from?
I assume from from a previous request.
Post by Valentin R
Helmut: is it possible to adapt our extension that the logoff hook is not called?
Then everything should be fine, except that we have to clean up the fe_session table from while to while ...
The logoff hook is not an issue in your case (session data is empty).

The issue is that a cookie is obiously set during a first login request
and in a second request your are going to pretend that credentials have
been sent once again, this the complete authentication process is
started again.

As outlined before, the authentication process starts by clearing up
session records that are present for the given cookie to avoid unwnated
re-use of session records.

Then FrontendUserAuthentication::logoff()

does not find a session any more for the cookie but recognizes that a
cookie was sent in this request thus correctly removes the cookie again.

I could reproduce the behavior by re-submitting the login form directly
after a successful login.

A quick fix for you could be to implement the initAuth method in your
service class and set the forceSetCookie property of the passed user
authentication object to TRUE.

It would be cleaner though, if you would kick your
FrontendPreProcessRequestHook

set

$GLOBALS['TYPO3_CONF_VARS']['SVCONF']['auth']['setup']['FE_fetchUserIfNoSession']
= TRUE;

in your configuration

implement the getUser method (and register your auth service to use it)
and fetch the user from the database from the passed username and return it.

The benefit of the second suggestion would be that after one successful
login, the whole authentication process is not started again, but
authentication is based on the session cookie.

HTH


Kind regards,
Helmut
--
Helmut Hummel
Release Manager TYPO3 6.0
TYPO3 CMS Active Contributor, TYPO3 Security Team Member

TYPO3 .... inspiring people to share!
Get involved: typo3.org
Valentin R
2014-11-27 08:44:54 UTC
Permalink
Hi Helmut,

excellent :-)

Thanks for your help! The following lines placed in the service class do the job:

public function initAuth($mode, array $loginData, array $authInfo, \TYPO3\CMS\Core\Authentication\AbstractUserAuthentication &$pObj) {
$pObj->forceSetCookie=TRUE;
parent::initAuth($mode,$loginData,$authInfo,$pObj);
}

Kind regards,

Valentin

Loading...