persistent_login icon indicating copy to clipboard operation
persistent_login copied to clipboard

Cookie is checked as "stolen" as false positive

Open Offerel opened this issue 2 years ago • 0 comments

If token data is removed from database, but the cookie is present in the browser, line 143 (if (($data = $rcmail->get_dbh()->fetch_assoc($res)))) will be set to false. In this case the cookie is reported as "stolen" and all other (and also valid tokens) are removed from the database. If another browser now tries to login (with its saved cookie), this will fail also, is reported as stolen again, all other tokens will be removed and so on... in this case, login is stuck in a loop as log a valid local cookie is found in the browser.

I know, a stolen cookie can be a problem. But personally i think, removing all tokens for this user from the db, is not the right solution. Instead of this, the user should be notified, that there is a risk of a stolen cookie and let the decision what to do, to the user. Maybe we should record the IP address where this cookie was last used and present this to the user. If this IP is unknown to the user, the cookie is really stolen and all tokens should be removed. If the IP is known, then this is mostly no issue. A stolen cookie is at least in my eyes a very rare issue. Only to present the raw IP to the user in such a case is not helpful for unexperienced users, we should get more and additional info's about this IP address, like location, carrier ip address pool/range from specific carrier and time of this specific login. This info's should be gathered only at the time, this issue occurs, but not saved to the db, we need only the IP address.

In my bookmark back-end, i use a similar technique, feel free to use it here to:

function ip_info() {
	$ipArr = [];
	if(!empty($_SERVER['HTTP_CLIENT_IP'])) {
        $ip = $_SERVER['HTTP_CLIENT_IP'];
    } else if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])){
        $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
    } else {
        $ip = $_SERVER['REMOTE_ADDR'];
    }
    
    $ipArr['ip'] = $ip;
    $wArr = preg_split('/\r\n|\r|\n/', shell_exec("whois '".addslashes($ipArr['ip'])."'"));
	foreach($wArr as $ipi ) {
		$iarr = explode(": ", $ipi);
		if($iarr[0] == "descr") {
			$ipArr['de'] = trim($iarr[1]);
			break;
		}
	}
	
	$ip_info = @json_decode(file_get_contents("http://www.geoplugin.net/json.gp?ip=".$ipArr['ip']));
	if($ip_info && $ip_info->geoplugin_countryName != null){
		$ipArr['co'] = $ip_info->geoplugin_continentName;
		$ipArr['ct'] = $ip_info->geoplugin_countryName;
		$ipArr['re'] = $ip_info->geoplugin_region;
		$ipArr['ua'] = $_SERVER['HTTP_USER_AGENT'];
		$ipArr['tm'] = time();
	}
	
	return $ipArr;
}

If saving the IP address in the database is fine for you, i can try to make pull request. But since is a huge privacy aspect, I'm not sure, if this i fine for your.

Offerel avatar Jul 09 '22 18:07 Offerel