LINUX.ORG.RU

Одновременное залогивание в разных браузерах для php

 ,


0

1

Написал webgui на php. Для залогивания в него используется такой код:

<?php

require_once dirname(__FILE__)."/lib/config.php";

$f = array();
$errors = array();

$f['username'] = (isset($_POST['username']) && is_string($_POST['username'])) ? mb_trim($_POST['username']) : "";
$f['password'] = (isset($_POST['password']) && is_string($_POST['password'])) ? $_POST['password'] : "";

if (isset($_POST['submitted'])) {
	require_once FILE_BASE."/db.php";
	$user = $db->users->findOne(array('username' => $f['username'], 'password' => $f['password']));
	//exit("here");
	if (is_null($user)) {
		$errors[] = "Access Denied!";
	} else {
		$_SESSION['user'] = $user;
		$_SESSION['timezone'] = (isset($user['timezone'])) ? $user['timezone'] : DEFAULT_TIMEZONE;
		go((isset($_GET['ret']) && is_string($_GET['ret'])) ? $_GET['ret'] : "{$www_base}/");
	}
}

На моём компе с gentoo всё работает отлично. Однако на компе заказчика с дебианом возникла такая странная проблема:

если пользователь уже залогинен например в mozilla когда он заходит в другом браухере например chromium он попадает на страницу login.php, вводит корректные данные (username/password) и всё равно не может залогиниться. Как было выяснено код внутри else {} выполняется и $user сохраняется в $_SESSION['user'] однако после редиректа оказывается что этих данных нет в сессии. Вот код из /lib/config.php:

<?php

error_reporting(E_ALL ^ E_DEPRECATED);

define('IS_WEB', !(php_sapi_name() == 'cli'));

require_once dirname(__FILE__)."/conf.php";
require_once FILE_BASE."/func.php";

date_default_timezone_set("UTC");
mb_internal_encoding("UTF-8");

if (IS_WEB) {
	$www_proto = (
		isset($_SERVER['HTTPS']) && is_string($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == "on"
	) ? "https" : "http";
	$www_base = "{$www_proto}://{$_SERVER['HTTP_HOST']}{$conf['www_path']}";
	
	if (get_magic_quotes_runtime()) set_magic_quotes_runtime(0);
	if (get_magic_quotes_gpc()) {
		function removeMagic($a) {
			if (is_array($a)) {
				foreach ($a as $key => $val) $a[$key] = removeMagic($a);
			} else {
				$a = stripslashes($a);
			}
			return $a;
		}
		$_GET = removeMagic($_GET);
		$_POST = removeMagic($_POST);
		$_COOKIE = removeMagic($_COOKIE);
	}
	
	session_set_cookie_params(
		0, // unlimited lifetime
		"{$conf['www_path']}",
		$_SERVER['HTTP_HOST'],
		false, // secure connections (httpS) only
		true // HTTP only, no JavaScript allowed to modify cookies
	);
	session_start();
	
	// Protection against CSRF attacks
	if (!isset($_SESSION['csrf'])) $_SESSION['csrf'] = randStr();
	if ($_SERVER['REQUEST_METHOD'] != 'GET') {
		if (!( isset($_POST['csrf']) && is_string($_POST['csrf']) && $_POST['csrf'] == $_SESSION['csrf'] )) {
			exit("CSRF attack!");
		}
	}
	
	if (!(
		preg_match('#/login\\.php$#', $_SERVER['PHP_SELF']) ||
		preg_match('#/logout\\.php$#', $_SERVER['PHP_SELF']) ||
		preg_match('#/users/index\\.php$#', $_SERVER['PHP_SELF']) ||
		preg_match('#/users/passwd\\.php$#', $_SERVER['PHP_SELF'])
	)) session_write_close();
}

Т.к. на моём компе всё работает подохреваю что дело в каких то настройках внутри php.ini.


Ответ на: комментарий от amomymous

$conf['www_path'] в данной установке равно пустой строке " т.к. установлено в корневой каталог.

Сейчас обнаружил ещё более странную особенность. Оказывается не работает только в случае если залогиниваться с адреса http://domain.com/login.php?ret=/cats/ и в /cats/index.php print_r($_SESSION) показывает что user там нет хотя в других файлах показывает что есть. Такое происходит даже если поместить print_r($_SESSION) в config.php, магическим образом если он вкладывается в файл из каталога /var/www/cats/ user из сессии исчезает. Переименовал каталог в catss и юзер там появился. Это что за спец название каталога??? Чёртовы глюки, весь софт пишется кое как, ничего надёжного нет!!!

mongo
() автор топика

Что-то подсказывает мне, что проблема кроется в этом:

if (!(
		preg_match('#/login\\.php$#', $_SERVER['PHP_SELF']) ||
		preg_match('#/logout\\.php$#', $_SERVER['PHP_SELF']) ||
		preg_match('#/users/index\\.php$#', $_SERVER['PHP_SELF']) ||
		preg_match('#/users/passwd\\.php$#', $_SERVER['PHP_SELF'])
	)) session_write_close();
Kilte ★★★★★
()
Ответ на: комментарий от mongo

Может быть стоит попробовать вызывать её всегда при завершении запроса? (При условии, что удалял полностью всё, включая вызов функции)

Вообще не понял, к чему там такая проверка.

Kilte ★★★★★
()
Последнее исправление: Kilte (всего исправлений: 2)

Короче $_SESSION['user'] магическим образом исчезает из сессии если каталог имеет одно из следующих названий: cats, categ, categories.

Итак, смотрим http://192.168.5.30/categories/govno.php, и видим:

Array
(
    [csrf] => O432LvmuO9s93M7i607itk8xZHHa2t0F8ntROI2iSL6n1PTtqQ1sTrAmOebJUZE14HwL642CC95ezheAeVeI23F3v2Uz7FcMTqBfXKjPzGbEIynpl6V8Mm7XQDSup939TfMelJ0PRGyW0DGp5mZGMGj01v5Z1u7d9f38g439j9Kug19u35N67p9KmR4D3jdSe7T9R6am3V60rGY007kopgZ7q546b6G3aLKRA3Vvl60tzrNv6Yn4C1wN690gkXI
)

Набираем по SSH `mv categories categorie` и, непроизводя АБСОЛЮТНО НИКАКИХ ДРУГИХ ДЕЙСТВИЙ, смотрим http://192.168.5.30/categorie/govno.php, и видим:

Array
(
    [csrf] => yLa3mOEN470mD9FGa59A4v4qxrvh5DnXnikWfVHXrFNM33mx0642k4rFKRIC2KwsfrVgp7h735Pw3T7x29IanW4QNB4iS8rp2xbx8vq1885jJqIfkB1ny5cl47bM1IlxW1GSJ3j0XYQ04vxXuK0IwyTa08K9bu9O4X6N4ksdw0l9Jk75728mYR7cJ7DmmcFnuaO7Jn9x2DJie6V1yyqx86cyP5P40HBG0n28yR9pdeLBTiFl6L77PvkA3l6v8t4
    [user] => Array
        (
            [_id] => MongoId Object
                (
                    [$id] => 549c36b7ade91cdd685115f2
                )

            [password] => testpass
            [timezone] => Europe/Brussels
            [username] => admin
        )

    [timezone] => Europe/Brussels
)

Как такое возможно? grep -R categories /etc/apache2/* и grep -R categories /etc/php/* ничего не показывает.

mongo
() автор топика
Ответ на: комментарий от Kilte

Вообще не понял, к чему там такая проверка.

Там есть скрипты которые выполняются долго и делают невозможным загрузку любой другой страницы в это время которая обращается к той же сессии. Это точно не из-за этого т.к. удалял это место абсолютно безрезультатно.

mongo
() автор топика
Ответ на: комментарий от mongo

Вобщем пока переименовал просто каталог в просто /c/ т.к. нет времени выяснять дальше, но было бы интересно всё таки узнать что за чертовщина происходит.

mongo
() автор топика
Ответ на: комментарий от mongo

выполняются долго и делают невозможным загрузку любой другой страницы

В таких случаях имеет смысл завести воркер.

Вообще муть какая-то. Судя по симптомам в первую очередь баг искать надо в приложении, т.к. конфиги апача и пыха насколько я знаю таким образом влиять на сессию не могут. Вот если бы сессия полностью пустая была, тогда другое дело.

Kilte ★★★★★
()
Ответ на: комментарий от amomymous

.htaccess вообще нет ни в /var/www/ ни в /var/www/cats/

mongo
() автор топика
Ответ на: комментарий от Kilte

На одном компе такой проблемы нет а на другом есть, значит не в приложении. Видимо чего то напихал туда админ какого то говнософта типа файервола, других объяснений нет.

mongo
() автор топика
Ответ на: комментарий от Komintern

Я с ними поверхностно знаком, в apache rewrite может отменять действие сессии? Ну даже если так где же он? .htaccess нет, grep -R cats /etc/apache2/* ничего не находит. Где ещё может быть?

mongo
() автор топика
Ответ на: комментарий от mongo

по идее любой htaccess на пути от корня до каталога с твоим скриптом может все испортить при AllowOverride All.

Komintern ★★★★★
()
Ответ на: комментарий от mongo

grep -R cats /etc/apache2/* ничего не находит. Где ещё может быть?

Да где угодно, на самом деле. Популярные в определённых кругах панели администрирования любят втыкать свои конфиги, нагенерённые веб-мордой, откуда угодно, хоть из /var и /usr.

Надо смотреть ещё и по Include в конфигах, и далее по всем подключаемым файлам.

risenshnobel ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.