Личные сообщения доступны администраторам, если у них есть ссылка

Я только что выяснил, что если кто-то отправляет личное сообщение другому пользователю — например, с аккаунта joe на jane — и по какой-то причине авторизованный пользователь узнает правильный «ID темы», то он сможет прочитать это сообщение.

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

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

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

Если вам необходимо обеспечить по-настоящему конфиденциальную систему, существует плагин discourse-encrypt, который обеспечивает сквозное шифрование сообщений.

9 лайков

Это не обязательно, просто я об этом не подумал.

Я проверю с обычным аккаунтом и обновлю информацию, на всякий случай.

1 лайк

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

Если это вызывает беспокойство, понизьте свою роль до модератора (войдите в систему под другой учетной записью, чтобы проверить), или включите ведение журнала посещений личных сообщений администраторами в настройках вашего сайта.

5 лайков

Возможно, глупый вопрос — где именно находится эта настройка? Мы используем стабильную версию (которая, в теории, должна иметь этот переключатель), но я никак не могу её найти.

Редактирование: Наш другой администратор нашёл её — это «log personal messages views» на вкладке «Users». Я бы сказал, что это должно быть в разделе «Безопасность», но, если подумать, понимаю, почему оно находится здесь.

2 лайка

Дополнительный вопрос: возможно ли включить ведение журнала, когда администратор просматривает сообщения, доступные аккаунту, даже если он не открывал конкретное сообщение для чтения его содержимого?

В контексте нашего форума администраторы могли бы злоупотреблять своими полномочиями, просто просматривая сведения о некоторых личных сообщениях, в которых участвует пользователь. Чтение содержимого не обязательно наносит больший ущерб, чем знание имени и того, какие пользователи имеют доступ; при этом эта информация в настоящее время не регистрируется, несмотря на то, что соответствующая настройка включена. В идеале мы хотели бы исправить это и регистрировать каждый случай, когда администратор просматривает сообщения, в которых участвует пользователь, а не только когда он просматривает содержимое конкретного сообщения.

1 лайк

Лучший способ сделать это — использовать сквозное шифрование, которое стало возможным благодаря нашему плагину discourse-encrypt.

Администраторы являются администраторами форума и имеют доступ ко всем данным. Существует множество способов для администраторов просматривать содержимое сообщений без регистрации этого действия:

  • загрузка резервной копии
  • Data Explorer
  • имперсонация
  • создание ключей API

Чтобы полностью защитить пользователей, лучшее решение — использовать шифрованное сообщение. Если вы не доверяете своим администраторам, они не должны быть администраторами.

5 лайков

Как я понимаю, большинство из этих действий можно записывать в логи, и это всё, что нам действительно нужно. Честно говоря, я не уверен, что могу доверять самому себе: я могу случайно зайти на страницу сообщений пользователя и просто продолжить работу, как будто ничего не произошло. В нашем случае это может быть вредным (в частности, мы не ожидаем, что это создаст угрозу безопасности, но это может стать угрозой целостности данных — то есть долгосрочного ущерба не будет, пока пользователь, получивший доступ к этой информации, честно сообщит об этом и воздержится от обсуждения соответствующих тем).

Конечно, это значительно упростило бы задачу: мы могли бы гарантировать, что никто не совершит таких действий случайно или намеренно, не сообщив об этом, если бы такие действия фиксировались в логах наряду со всеми остальными способами доступа к тем же данным.

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

1 лайк

Вы можете скрыть или замаскировать заголовки сообщений других пользователей в их списках сообщений с помощью темы вашего сайта.

Если это сделано намеренно, то это уже другой вопрос.

Другие места, где можно получить такую информацию для аудита: логи веб-сервера.

Я уверен, что создание плагина для записи этой информации не составит труда, но я не уверен, должно ли это быть включено в наш внутренний план разработки.

2 лайка

Как это можно сделать, не скрывая при этом ваши собственные списки сообщений? Насколько мне известно, нет слага с именем пользователя учетной записи, которую вы просматриваете, которое можно было бы использовать для применения CSS только к страницам сообщений, которые не являются вашими собственными.

1 лайк

Вы, возможно, сможете использовать селектор для заголовка на этой странице — «Сообщения» — это ваши, а «Имя пользователя — Сообщения» — это сообщения другого человека.

2 лайка

Моя основная проблема в том, что мой скрипт, похоже, извлекает данные до их обновления — то есть я могу прочитать метаданные при смене страницы, но они обновляются раньше, чем обновляются данные страницы.

<script type="text/discourse-plugin" version="0.8">
    api.onPageChange(() => {
        window.onload = determineUser();
    });
    
    function determineUser() {
        var pageURL = document.querySelector("meta[property='og:url']").getAttribute("content");
        var userPage = pageURL.includes("https://www.fortressoflies.com/u/");
        document.documentElement.style.setProperty('--currUsername', pageURL);
        
        if(userPage)
        {
            document.documentElement.style.setProperty('--lastUsername', pageURL);
        }
    }
</script>

По сути, мой --currUsername обновляется, а затем мета-тег обновляется новым URL, поэтому мой --currUsername всегда отстает на одну страницу от того, что я на самом деле просматриваю. Это происходит независимо от того, есть ли у меня строка “window.onload” или нет.

Есть ли у вас идеи, где я ошибаюсь?

Конечная цель — просто добавить класс к body в зависимости от того, какую страницу вы просматриваете, а затем стилизовать на основе этого. Это должно позволить нам, например, читать поле title вместо поля og:url, а затем добавить класс “myMessages” к body, чтобы в данном случае добиться желаемого эффекта. В теории.

1 лайк

Это чудовищно криво, но следующий код, по-видимому, работает, заставляя JavaScript-функцию подождать одну двадцатую секунды:

<script type="text/discourse-plugin" version="0.8">
    api.onPageChange(() =>{
        window.onload = determineUser();
    });
    
    async function determineUser() {
        await sleep(50);
        var pageURL = document.querySelector("meta[property='og:url']").getAttribute("content");
        var userPage = pageURL.includes("https://www.fortressoflies.com/u/");
        document.documentElement.style.setProperty('--currUsername', pageURL);
        if(userPage)
        {
            document.documentElement.style.setProperty('--lastUsername', pageURL);
        }
    }
    
    function sleep(ms)
    {
        return new Promise(resolve => setTimeout(resolve, ms));
    }
</script>

Посмотрю, получится ли заставить это работать так, как задумано.

2 лайка