I'm trying to login a user who was authenticated elsewhere to a Joomla-site and was following Brent Friar's nice program, but had to apply two modifications:
- added a field "return" which was contained in the form
- refencing com_users, not com_user
I do not know if that site has specific customizations, uses a specific login-module or if is a different version - I do not have admin-access to the site, so I cannot check. Now, my script is running, but it does not successfully login the user - it doesn't get a cookie in return which it is expecting.
Instead, the site returns
HTTP/1.1 100 Continue
HTTP/1.1 303 See other Date: Wed, 23 Jul 2014 18:18:25 GMT Server: Apache/2.2.22 X-Powered-By: PHP/5.2.17 Location: http://www.strassenbau.forum-kundenportal.de/login-erfolgreich Content-Length: 0 Connection: close Content-Type: text/html; charset=utf-8
I know a bit of Joomla, but know nothing about the depths of http-communication with it, so I have no idea what the problem is here.
Here's my code:
<?php
$uname = "*** secret";
$upswd = "*** credentials";
$url = "http://www.strassenbau.forum-kundenportal.de/login-anmeldung";
set_time_limit(0);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url );
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE );
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE );
curl_setopt($ch, CURLOPT_COOKIESESSION, TRUE );
curl_setopt($ch, CURLOPT_COOKIEJAR, realpath('./cookie.txt'));
curl_setopt($ch, CURLOPT_COOKIEFILE, realpath('./cookie.txt'));
curl_setopt($ch, CURLOPT_HEADER, TRUE );
$ret = curl_exec($ch);
if (!preg_match('/name="([a-zA-z0-9]{32})"/', $ret, $spoof)) {
preg_match("/name='([a-zA-z0-9]{32})'/", $ret, $spoof);
}
preg_match('/name="return" value="(.*)"/', $ret, $return); // search for hidden field "return" and get its value
// POST fields
$postfields = array();
$postfields['username'] = urlencode($uname);
$postfields['password'] = urlencode($upswd);
$postfields['option'] = 'com_users';
$postfields['task'] = 'user.login';
$postfields['return'] = $return[1];
$postfields[$spoof[1]] = '1';
// edit: using the location of the 303-result directly...but it does not make a difference
curl_setopt($ch, CURLOPT_URL , "http://www.strassenbau.forum-kundenportal.de/login-erfolgreich");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields);
$ret = curl_exec($ch);
echo "ret2: <pre>"; var_dump($ret); echo "</pre>"; // no cooking being set here!
// Get logged in cookie and pass it to the browser
preg_match('/^Set-Cookie: (.*?);/m', $ret, $m);
$cookie=explode('=',$m[1]);
setcookie($cookie[0], $cookie[1]);
?>
While looking for answers, I found a remark saying that Joomla now also uses session-tokens, so it would not work for that reason. Can anybody confirm that explanation? But how then is remote login handled in such situations? Could I overcome the issue by implementing my own login-module?
preg_match('/name="return" value="(.*)"/', $ret, $return)
looks vulnerable to overmatching. Did you ever echo out what values are actually being matched/captured? – mickmackusa♦ Nov 30 '18 at 0:23if (preg_match('~\bname=["\']\K\w{32}~', $ret, $spoof)) { $token = $spoof[0]; } else { echo "Valid Token Not Found in $ret"; }
andecho preg_match('~\bname=["\']return["\'] value=["\']\K[^"\']+~', $ret, $return) ? "Didn't get return value from $ret" : $return[0];
– mickmackusa♦ Nov 30 '18 at 0:31