Сообщаем об ошибках phpBB 3.0.x разработчикам

Проблемы с установкой или работой phpBB 3.0.x? Получите помощь здесь!
С 1 января 2017 года phpBB Group прекращает поддержку phpBB версии 3.0.
Сайт официальной русской поддержки phpBB Guru продолжит поддержку phpBB 3.0 до 1 июля 2017 года.
Подробнее: Окончание поддержки phpBB 3.0.
Правила форума
Местная Конституция | Шаблон запроса | Документация (phpBB3) | Переход на 3.0.6 и выше | FAQ-3 (phpbb3) | Как задавать вопросы | Как устанавливать моды

Ваш вопрос может быть удален без объяснения причин, если на него есть ответы по приведённым ссылкам (а вы рискуете получить предупреждение ;) ).
Аватара пользователя
Alek$
Former team member
Сообщения: 2616
Стаж: 21 год 1 месяц
Откуда: Новосибирск
Поблагодарили: 37 раз

Re: Сообщаем об ошибках phpBB 3.0.x разработчикам

Сообщение Alek$ »

mih_io
Выглядит разумно, спасибо.
Самая страшная ошибка, это ошибка без видимых причин и конкретных последствий.
phpBB3 [db_update.php generator]
Первая помощь по всем phpBB-вопросам: phpBB2 и phpBB3 FAQ; Правила общения;
Все консультации в icq или личке - на платной основе.
outta
phpBB 1.2.0
Сообщения: 11
Стаж: 15 лет 9 месяцев

Re: Сообщаем об ошибках phpBB 3.0.x разработчикам

Сообщение outta »

Продукт: phpBB 3.0.8
Скрипт: viewtopic.php
Описание: неверная обработка параметра f при инициализации скрипта
Следствие: (для нормального пользователя) некорректная работа с правами в важных темах; (для остальных) повышение собственных прав доступа на чтение закрытых разделов конференции

Суть проблемы:
В коде формирования запроса на получения данных о запрашиваемом топике допущена ошибка.

Код: Выделить всё

// This rather complex gaggle of code handles querying for topics but
// also allows for direct linking to a post (and the calculation of which
// page the post is on and the correct display of viewtopic)
$sql_array = array(
    'SELECT'    => 't.*, f.*',

    'FROM'        => array(FORUMS_TABLE => 'f'),
);

// Firebird handles two columns of the same name a little differently, this
// addresses that by forcing the forum_id to come from the forums table.
if ($db->sql_layer === 'firebird')
{
    $sql_array['SELECT'] = 'f.forum_id AS forum_id, ' . $sql_array['SELECT'];
}

// The FROM-Order is quite important here, else t.* columns can not be correctly bound.
if ($post_id)
{
    $sql_array['SELECT'] .= ', p.post_approved';
    $sql_array['FROM'][POSTS_TABLE] = 'p';
}

// Topics table need to be the last in the chain
$sql_array['FROM'][TOPICS_TABLE] = 't';

if ($user->data['is_registered'])
{
    $sql_array['SELECT'] .= ', tw.notify_status';
    $sql_array['LEFT_JOIN'] = array();

    $sql_array['LEFT_JOIN'][] = array(
        'FROM'    => array(TOPICS_WATCH_TABLE => 'tw'),
        'ON'    => 'tw.user_id = ' . $user->data['user_id'] . ' AND t.topic_id = tw.topic_id'
    );

    if ($config['allow_bookmarks'])
    {
        $sql_array['SELECT'] .= ', bm.topic_id as bookmarked';
        $sql_array['LEFT_JOIN'][] = array(
            'FROM'    => array(BOOKMARKS_TABLE => 'bm'),
            'ON'    => 'bm.user_id = ' . $user->data['user_id'] . ' AND t.topic_id = bm.topic_id'
        );
    }

    if ($config['load_db_lastread'])
    {
        $sql_array['SELECT'] .= ', tt.mark_time, ft.mark_time as forum_mark_time';

        $sql_array['LEFT_JOIN'][] = array(
            'FROM'    => array(TOPICS_TRACK_TABLE => 'tt'),
            'ON'    => 'tt.user_id = ' . $user->data['user_id'] . ' AND t.topic_id = tt.topic_id'
        );

        $sql_array['LEFT_JOIN'][] = array(
            'FROM'    => array(FORUMS_TRACK_TABLE => 'ft'),
            'ON'    => 'ft.user_id = ' . $user->data['user_id'] . ' AND t.forum_id = ft.forum_id'
        );
    }
}

if (!$post_id)
{
    $sql_array['WHERE'] = "t.topic_id = $topic_id";
}
else
{
    $sql_array['WHERE'] = "p.post_id = $post_id AND t.topic_id = p.topic_id";
}

$sql_array['WHERE'] .= ' AND (f.forum_id = t.forum_id';

if (!$forum_id)
{
    // If it is a global announcement make sure to set the forum id to a postable forum
    $sql_array['WHERE'] .= ' OR (t.topic_type = ' . POST_GLOBAL . '
        AND f.forum_type = ' . FORUM_POST . ')';
}
else
{
    $sql_array['WHERE'] .= ' OR (t.topic_type = ' . POST_GLOBAL . "
        AND f.forum_id = $forum_id)";
}

$sql_array['WHERE'] .= ')'; 
Проявляется она при $forum_id == false. Составляется ошибочный запрос к базе:

Код: Выделить всё

SELECT t.*, f.*, tw.notify_status, bm.topic_id as bookmarked, tt.mark_time, ft.mark_time as forum_mark_time
FROM (phpbb_forums f, phpbb_topics t)
LEFT JOIN phpbb_topics_watch tw ON (tw.user_id = 2 AND t.topic_id = tw.topic_id)
LEFT JOIN phpbb_bookmarks bm ON (bm.user_id = 2 AND t.topic_id = bm.topic_id)
LEFT JOIN phpbb_topics_track tt ON (tt.user_id = 2 AND t.topic_id = tt.topic_id)
LEFT JOIN phpbb_forums_track ft ON (ft.user_id = 2 AND t.forum_id = ft.forum_id)
WHERE t.topic_id = 2 AND (f.forum_id = t.forum_id OR (f.forum_type = 1))
(где user_id и topic_id могут быть любым). Результатом такого запроса является не одна строка, как это по логике ожидается, а целая таблица:
bug1.png
в которой столбец forum_id содержится дважды, а второе значение переопределяет первое.

Следующий далее во viewtopic.php код выставляет для нашего запроса неверный идентификатор форума:

Код: Выделить всё

$sql = $db->sql_build_query('SELECT', $sql_array);
$result = $db->sql_query($sql);
$topic_data = $db->sql_fetchrow($result);
$db->sql_freeresult($result);

// link to unapproved post or incorrect link
if (!$topic_data)
{
...
}

$forum_id = (int) $topic_data['forum_id']; 
тем самым подсовывая функциям проверки прав из класса $auth (acl_get) другое значение.

Вывод: имея доступ к первому форуму на конференции (в приведённом примере — к форуму с forum_id = 2) мы можем прочитать любую тему просто немного изменив запрос к viewtopic.php.

Временный костыль: я заменил проблемный код (указан мной в начале сообщения) следующим:

Код: Выделить всё

// This rather complex gaggle of code handles querying for topics but
// also allows for direct linking to a post (and the calculation of which
// page the post is on and the correct display of viewtopic)
$sql_array = array(
    'SELECT'    => 't.*, f.*',
    'LEFT_JOIN'    => array(),
);
$sql_array['LEFT_JOIN'][] = array(
    'FROM'    => array(FORUMS_TABLE => 'f'),
    'ON'    => 'f.forum_id = t.forum_id'
);

// Firebird handles two columns of the same name a little differently, this
// addresses that by forcing the forum_id to come from the forums table.
if ($db->sql_layer === 'firebird')
{
    $sql_array['SELECT'] = 'f.forum_id AS forum_id, ' . $sql_array['SELECT'];
}

// The FROM-Order is quite important here, else t.* columns can not be correctly bound.
if ($post_id)
{
    $sql_array['SELECT'] .= ', p.post_approved';
    $sql_array['FROM'][POSTS_TABLE] = 'p';
}

// Topics table need to be the last in the chain
$sql_array['FROM'][TOPICS_TABLE] = 't';

if ($user->data['is_registered'])
{
    $sql_array['SELECT'] .= ', tw.notify_status';

    $sql_array['LEFT_JOIN'][] = array(
        'FROM'    => array(TOPICS_WATCH_TABLE => 'tw'),
        'ON'    => 'tw.user_id = ' . $user->data['user_id'] . ' AND t.topic_id = tw.topic_id'
    );

    if ($config['allow_bookmarks'])
    {
        $sql_array['SELECT'] .= ', bm.topic_id as bookmarked';
        $sql_array['LEFT_JOIN'][] = array(
            'FROM'    => array(BOOKMARKS_TABLE => 'bm'),
            'ON'    => 'bm.user_id = ' . $user->data['user_id'] . ' AND t.topic_id = bm.topic_id'
        );
    }

    if ($config['load_db_lastread'])
    {
        $sql_array['SELECT'] .= ', tt.mark_time, ft.mark_time as forum_mark_time';

        $sql_array['LEFT_JOIN'][] = array(
            'FROM'    => array(TOPICS_TRACK_TABLE => 'tt'),
            'ON'    => 'tt.user_id = ' . $user->data['user_id'] . ' AND t.topic_id = tt.topic_id'
        );

        $sql_array['LEFT_JOIN'][] = array(
            'FROM'    => array(FORUMS_TRACK_TABLE => 'ft'),
            'ON'    => 'ft.user_id = ' . $user->data['user_id'] . ' AND t.forum_id = ft.forum_id'
        );
    }
}

if (!$post_id)
{
    $sql_array['WHERE'] = "t.topic_id = $topic_id";
}
else
{
    $sql_array['WHERE'] = "p.post_id = $post_id AND t.topic_id = p.topic_id";
} 
Использование LEFT JOIN предотвращает «подцепку» лишних данных и forum_id не переопределяется:

Код: Выделить всё

SELECT t.*, f.*, tw.notify_status, bm.topic_id as bookmarked, tt.mark_time, ft.mark_time as forum_mark_time
FROM (phpbb_topics t)
LEFT JOIN phpbb_forums f ON (f.forum_id = t.forum_id)
LEFT JOIN phpbb_topics_watch tw ON (tw.user_id = 2 AND t.topic_id = tw.topic_id)
LEFT JOIN phpbb_bookmarks bm ON (bm.user_id = 2 AND t.topic_id = bm.topic_id)
LEFT JOIN phpbb_topics_track tt ON (tt.user_id = 2 AND t.topic_id = tt.topic_id)
LEFT JOIN phpbb_forums_track ft ON (ft.user_id = 2 AND t.forum_id = ft.forum_id)
WHERE t.topic_id = 2
bug2.png

Что скажут Гуру?
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Аватара пользователя
rxu
phpBB Guru
phpBB Guru
Сообщения: 17273
Стаж: 20 лет 4 месяца
Откуда: Красноярск
Благодарил (а): 632 раза
Поблагодарили: 2413 раз

Re: Сообщаем об ошибках phpBB 3.0.x разработчикам

Сообщение rxu »

outta писал(а):Проявляется она при $forum_id == false.
Каким образом такое может произойти?
Изображение
outta
phpBB 1.2.0
Сообщения: 11
Стаж: 15 лет 9 месяцев

Re: Сообщаем об ошибках phpBB 3.0.x разработчикам

Сообщение outta »

Приведение типов...

Код: Выделить всё

($forum_id = 0) == false

Код: Выделить всё

($forum_id = NULL) == false
Аватара пользователя
rxu
phpBB Guru
phpBB Guru
Сообщения: 17273
Стаж: 20 лет 4 месяца
Откуда: Красноярск
Благодарил (а): 632 раза
Поблагодарили: 2413 раз

Re: Сообщаем об ошибках phpBB 3.0.x разработчикам

Сообщение rxu »

outta
Я имел ввиду в коде phpBB. Какой параметр я должен задать в URL, чтобы получить описываемый результат.
Изображение
outta
phpBB 1.2.0
Сообщения: 11
Стаж: 15 лет 9 месяцев

Re: Сообщаем об ошибках phpBB 3.0.x разработчикам

Сообщение outta »

Ты должен опустить параметр f или указать вместо значения 0.
Аватара пользователя
rxu
phpBB Guru
phpBB Guru
Сообщения: 17273
Стаж: 20 лет 4 месяца
Откуда: Красноярск
Благодарил (а): 632 раза
Поблагодарили: 2413 раз

Re: Сообщаем об ошибках phpBB 3.0.x разработчикам

Сообщение rxu »

Т.е. опускаю указанный параметр, задаю t= id темы из закрытого форума, и читаю?
Для гостей срабатывает?
Изображение
outta
phpBB 1.2.0
Сообщения: 11
Стаж: 15 лет 9 месяцев

Re: Сообщаем об ошибках phpBB 3.0.x разработчикам

Сообщение outta »

rxu писал(а):Т.е. опускаю указанный параметр, задаю t= id темы из закрытого форума, и читаю?
Да, если
outta писал(а):имея доступ к первому форуму на конференции (в приведённом примере — к форуму с forum_id = 2)
rxu писал(а):Для гостей срабатывает?
Да.
Аватара пользователя
rxu
phpBB Guru
phpBB Guru
Сообщения: 17273
Стаж: 20 лет 4 месяца
Откуда: Красноярск
Благодарил (а): 632 раза
Поблагодарили: 2413 раз

Re: Сообщаем об ошибках phpBB 3.0.x разработчикам

Сообщение rxu »

outta
Не воспроизводится. Что я не так делаю?

Добавлено спустя 1 минуту 27 секунд:
У нас есть форум Корзина, закрытый для гостей. Тема 30696, попробуйте и покажите скриншот.
Изображение
mih_io
phpBB 1.4.2
Сообщения: 56
Стаж: 16 лет
Благодарил (а): 8 раз
Поблагодарили: 12 раз

Re: Сообщаем об ошибках phpBB 3.0.x разработчикам

Сообщение mih_io »

outta писал(а):имея доступ к первому форуму на конференции (в приведённом примере — к форуму с forum_id = 2)
не понимаю, как определить первый форум на конференции
Т.е. я захожу под админом (имею доступ ко всем форумам) и начинаю перебирать, какой у меня форум вообще первый. Делаю так:
http://мойдомен.ru/viewforum.php?f=1 - заругался "Запрошенного форума не существует."
http://мойдомен.ru/viewforum.php?f=2 - заругался "Запрошенного форума не существует."
...
До тех пор пока он не загрузил первый форум. У меня это метка ид 5. Тут же запоминаю ид темы из скрытого раздела.

Захожу под пользователем. Смотрю. Есть ли у него доступ к форуму с ид 5. Т.е. запускаю так:
http://мойдомен.ru/viewforum.php?f=5.
Работает, открылось. И теперь если я делаю такой запрос из под этого пользователя
http://мойдомен.ru/viewtopic.php?t=ид секретной темы
То тема должна у него открыться? Не открывается.
Shredder
Former team member
Сообщения: 2266
Стаж: 17 лет 9 месяцев
Благодарил (а): 283 раза
Поблагодарили: 584 раза

Re: Сообщаем об ошибках phpBB 3.0.x разработчикам

Сообщение Shredder »

В ИЕ8 в окошке настроек прав доступа (любых) какая- то полоса:
Clip_5.png
В других браузерах нет. Из ИЕ - проверял только восьмой. Подумал сначала, что кривое обновление, но на чистом phpBB всё то же самое.
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Аватара пользователя
rxu
phpBB Guru
phpBB Guru
Сообщения: 17273
Стаж: 20 лет 4 месяца
Откуда: Красноярск
Благодарил (а): 632 раза
Поблагодарили: 2413 раз

Re: Сообщаем об ошибках phpBB 3.0.x разработчикам

Сообщение rxu »

outta
В теперешнем виде этот код находится с 02.07.2006 года, не знаю, каким образом он оказался не таким в вашем случае.
Изображение
outta
phpBB 1.2.0
Сообщения: 11
Стаж: 15 лет 9 месяцев

Re: Сообщаем об ошибках phpBB 3.0.x разработчикам

Сообщение outta »

rxu
Да, действительно, я только что проверил на нескольких дистрибутивах; запрос, который был мной приведён, генерировался изменённым кодом, в блоке

Код: Выделить всё

if (!$forum_id)
{
    // If it is a global announcement make sure to set the forum id to a postable forum
    $sql_array['WHERE'] .= ' OR (t.topic_type = ' . POST_GLOBAL . '
        AND f.forum_type = ' . FORUM_POST . ')';
} 
отсутствовало

Код: Выделить всё

t.topic_type = ' . POST_GLOBAL . '
        AND  
что странно, т.к. в приведённом мной же блоке кода этот кусок есть.

Но всё-таки несмотря на то, что бага с повышением прав нет (кстати, может стоит удалить сообщения, что бы не вводить в заблуждение народ?), сама ошибка в запросе имеется, правда ввиду кода t.topic_type = ' . POST_GLOBAL . ' касается она только глобальных тем. Так, если у посетителя нет прав доступа к первому форуму, то при попытке загрузить глобальную тему без указания параметра f, будет выдан отказ в доступе.
Shredder
Former team member
Сообщения: 2266
Стаж: 17 лет 9 месяцев
Благодарил (а): 283 раза
Поблагодарили: 584 раза

Re: Сообщаем об ошибках phpBB 3.0.x разработчикам

Сообщение Shredder »

Сообщаем об ошибках phpBB 3.0.x разработчикам

Кстати, переустановил ОС - эта полоса пропала. Странно...
Аватара пользователя
rxu
phpBB Guru
phpBB Guru
Сообщения: 17273
Стаж: 20 лет 4 месяца
Откуда: Красноярск
Благодарил (а): 632 раза
Поблагодарили: 2413 раз

Re: Сообщаем об ошибках phpBB 3.0.x разработчикам

Сообщение rxu »

Возможно, просто проблема с рендерингом в браузере (возможно, драйверозависимая).
Изображение

Вернуться в «Поддержка phpBB 3.0.х»