Переработка и укрепление программы


Как было отмечено[link1] расширение кода WackoWiki себя исчерпало, и программа будет переписана с нуля с упором на аспекты безопасности. На этой странице можно будет следить за ходом разработки и обсуждать какие-то дизайнерские решения.

Комментарии, замечания и корректировки горячо приветствуются.
Оглавление документа:

Формализация

Профиль использования





Модель угрозы


Пояснения: задача противника (класс атак), вектор атаки, класс защиты, контрмера, отражающая атаку или изменяющая её вектор, рекомендация / вне контроля приложения. Стрелки в обозначениях классов внутри дерева — это ссылки на раскрытые деревья данных классов.








Мысли вслух

Антицензурный механизм


Репликация данных между сетью зеркал — это, по существу, единственный доступный на текущем этапе [ограниченный] антицензурный механизм. Ограничен он тем, что не в состоянии контролировать аутентичность приложения на каждом из зеркал, благодаря чему каждое зеркало в отдельности может лгать пользователям, выдавая не ту информацию, которая содержится в синхронизируемой с другими зеркалами БД. Полноценное решение — это клиентская программа, выполняющая весь ввод/вывод данных в БД зеркал, снимая с них задачу веб-сервера. Но следует отдать себе отчёт в том, что само такое решение не является универсальным и может быть реализовано только на более поздних этапах, если в принципе будет найдено целесообразным.

Текущее ограниченное решение заключается в том, чтобы "сверить часы" (или базы) зеркал перед коммитом изменений от мастер-сервера. Допустим, пользователь зашёл на сайт и внёс изменение в текст документа; вот что примерно должно происходить (это набросок, а не законченный протокол):

  1. Мастер-сервер (где находится пользователь) извлекает из своей БД записи с n-i по n+i (где n — номер отредактированной пользователем записи, i — некоторое небольшое число), сериализует их и хэширует результат.
  2. Мастер-сервер рассылает зеркалам параметры операции (n, i, тип выполняемого пользователем действия).
  3. Зеркала повторяют операцию мастер-сервера со своими БД, заверяют полученные хэши своими закрытыми ключами и возвращают результат мастер-серверу.
  4. Мастер подсчитывает "голоса" (каждое уникальное значение хэша) и сравнивает превалирующий хэш с собственным, полученным на этапе 1:
    • Если хэш мастера совпадает с большинством, он выполняет коммит зеркалам, передавая как введённые пользователем данные, так и все заверенные хэши, полученные от зеркал на этапе 3, и включая собственный. (Зеркала перед вводом данных в БД должны проверить правильность подсчётов мастера и отказать в коммите, если он лжёт.)
    • Если хэш мастера не совпадает с большинством, он запрашивает спорные записи у одного из зеркал с "правильным" хэшем, коммитит их в свою базу и перезапускает процесс с этапа 2.
    • Если все зеркала не имеют полного консенсуса относительно состояния базы, "меньшевики" по полученным от мастера заверенным хэшам также смогут определить, что у них что-то не так, и запросить "правильную" копию.

(Здесь не учтён ряд пограничных случаев типа спорного голосования пополам, полного отсутствия консенсуса и пр. Также пока непонятно, как быть с race conditions, если все зеркала равноправны, и два пользователя одновременно правят один и тот же документ или два соседних на разных зеркалах.)

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

Вот проблемы и ограничения предложенной схемы:

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

  1. Скрытная модификация на одном из зеркал тех записей БД, которые обычно редко редактируются пользователями (или не редактируются совсем) и не имеют часто редактируемых соседей, так что подобное искажение может никогда не обнаружиться исполнением приведённого выше протокола. Решения:
    • Большое значение i, дабы каждым коммитом охватывать большее число соседних записей. Что, в свою очередь, означает дополнительную нагрузку на узлы при хэшировании большего объёма данных. В любом случае, само по себе такое решение не является полным.
    • Периодическое блокирование БД, хэширование всего содержимого и сравнение результатов между зеркалами. Собственные проблемы:
      1. Необходимость в синхронизации этого действа. В принципе, не слишком большая проблема (команду о выполнении полной проверки может рассылать один из узлов, получив которую, все начинают подготовку).
      2. Выявление спорных участков БД. Тоже решаемая задача: хэшировать блоки записей (скажем, по 100 строк), а затем — сам полученный набор хэшей. Такая схема позволит даже выполнять полную проверку в несколько этапов, дабы не останавливать работу сайта на длительный срок.
    • Оптимизированная версия предыдущего варианта. Во-первых, каждая строка БД уже содержит хэш существенных полей данной строки (что избавляет зеркала от необходимости пересчитывать хэши при каждом коммите мастера, который, вероятно, просто пытается их заDoSить). Во-вторых, специальное поле (единственное для таблицы или для всей БД), содержащее XOR всех хэш-значений всех предыдущих коммитов и их счётчик. То есть получается так: когда пользователь вносить изменения в БД, сервер подсчитывает хэш существенных полей данной записи, вносить этот хэш в ту же строку БД, а затем XOR'ит его с текущим значением этого специального поля. В итоге, для полной синхронизации зеркалам нужно только обменяться значениями этого специального поля, сравнить его и счётчик, а полную сверку (описанную в п.2 предыдущего варианта, но с предрассчитанными хэшами) проводить только в случае расхождений.

  1. В принципе, ничто не мешает мастеру коммитить любые изменения, отравляя зеркала, покуда эта отрава будет синхронизирована между зеркалами (т.е. схема защищает только от скрытной модификации БД без ведома админа сервера, но не от целенаправленных действий админа). Решения:
    • Зеркала могут проверять вводимые данные против текущего состояния системы (например, мог ли данный пользователь отредактировать данную страницу, учитывая его привилегии и ACL документа), но такой механизм крайне легко обойти: просто лгать (выбрать пользователя с наивысшей репутацией/привилегиями и "править" документ от его имени).
    • Аутентификация пользовательского действия ключом PGP (это то, что зеркала могут объективно проверить). Хотя аутентификация большинства действий кажется тривиальной, более серьёзное размышление вырисовывает ряд попутных проблем:
      1. Атаки с повторной передачей, если заверять один только текст документа (как сейчас) без каких-либо метаданных. Решение:
        • Первые строчки документа должны содержать декларацию, логически привязывающую текст к данному применению (например, это может быть адрес документа и номер последней редакции). Такое доказательство зеркала могут принять.
      2. Трудности с аутентификацией действий, отличных от ввода простого контента, к примеру, изменений настроек или ACL документа. Решение:
        • В подобных случаях сервер может сериализовать действие пользователя (представить его в виде понятного пользователю текстового набора команд плюс значения счётчика для защиты от повторной передачи), которое последний и должен заверить цифровой подписью.
      3. Существует некоторый класс часто повторяемых действий, постоянная аутентификация которых может свести пользователя с ума. В частности, это работа с репутационной системой. (Следует учитывать, что это в немалой степени зависит от конкретного дизайна такой системы. Пока я рассматриваю идею с "плюсами" и "минусами", которые участники могут расставлять объектам системы, оказывая тем самым влияние на рейтинг владельцев этих объектов. Более подробно данный вопрос будет рассмотрен отдельно, поскольку требует учёта ряда "трудных" ситуаций, как то "правильную" оценку редакций документов.) Решение:
        • Не требовать аутентифицировать каждое такое действие, а только накапливать их в виде простых команд, которые пользователь в любой момент может заверить скопом. Такой подход требует особого внимания к пользовательскому интерфейсу, поскольку пользователь может покинуть сайт, не произведя заверение команд, и они будут просто потеряны (правда, можно и сохранять их в БД до следующего визита пользователя)...
      4. Главная сложность возникает на точке входа. Хотя аутентичность последующих изменений БД можно проконтролировать с помощью описанных мер, у зеркал не может быть гарантии, что первая загрузка открытого ключа пользователя в действительности выполнена им самим, и ключ принадлежит пользователю. Ничто не мешает мастеру MITM'ить ключи всех пользователей. Решения:
        • Загрузив ключ на мастер, пользователь может обойти зеркала и проверить, что на них также находится его ключ. Но как он в случае подлога докажет зеркалам, что это и впрямь не его ключ?
        • На странице загрузки ключа помещать несколько самостоятельных веб-форм, каждая выполняющая POST-запрос на соответствующее зеркало. Дёшево и сердито, зато работает.
      5. Приведённую выше MITM-подмену ключа на точке входа можно обобщить на любые впервые вводимые данные. Так, если правила аутентификации операций над объектом не закреплены мандатно, их добровольная установка может быть подделана мастер-сервером, и зеркала об этом никогда не узнают. (По-русски: предположим, требование о заверении всех операций с помощью ключей не установлено на сайте глобально; пользователь создаёт новый документ и включает это свойство локально для данной страницы. Но, независимо от желания пользователя, мастер-сервер не рассылает это обновление зеркалам, поэтому может и впредь любым образом модифицировать документ, бесконтрольно отправляя зеркалам злоумышленные редакции.) Решение пока неизвестно.

Не окажется ли, что способы решения вышеназванных проблем превратят всю систему в мертворождённого ребёнка, сделав её практически непригодной к использованию? С другой стороны, множество механизмов безопасности, в том числе и аутентификация пользовательских действий, могут быть опциональны и применяться лишь на ограниченном наборе документов (или быть локализованы по иному признаку).

Репутационная система


"Человек может иметь столько электронных личностей, на создание скольких ему хватит времени и сил".
- J. S. Donath, "Identity and Deception in the Virtual Community"

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

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

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

Предоставленная сама себе, администрация будет поддерживать баланс этих условий, выражая интересы большинства по модулю своего личного субъективного мнения. Это может выражаться в жёстком цензурировании/удалении наиболее маргинальных материалов (с сопутствующей "текучестью кадров" в группах пользователей, представляющих данные материалы) и мягком цензурировании материалов, не отвечающих позиции администрации (но лишь до той степени, до которой данные материалы не находят поддержку у большинства пользователей; в противном случае администрация сталкивается с риском массового оттока посетителей, что нарушает условия игры и ведёт к проигрышу). Внешнее давление, запугивание и угрозы способны исказить приоритеты администрации с краткосрочного удовлетворения интересов посетителей к долгосрочной выживаемости ресурса, следовательно, навязанная цензура с высокой вероятностью будет принята, несмотря на сопротивление и отток пользователей. (Разумеется, подцензурность значительной доли материалов равносильна уничтожению ресурса. Определить действия администрации в подобной ситуации без учёта всего комплекса "жизненных" факторов не представляется возможным.)

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

Отмеченную централизацию власти можно устранить в коллективном управлении контентом. Коллективное управление может выражаться посредством голосований за удаление комментария или документа, запуск/остановку опроса, блокирование пользователя, иные подобные действия. Реализованное в таком виде, коллективное управление открывает простор для сивилловых (sybil) атак: противник, зарегистрировав произвольно большое количество пользователей и используя их для голосований, будет способен влиять на принятие решений и, в итоге, на объём и состав представленный материалов. Модель репутации пользователей способна серьёзно снизить применимость подобной атаки.

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

Типы хэндлеров документов (пространства имён)





Предотвращение race conditions. Атомарные операции


Клиентское приложение (плагин Firefox?) для автоматического зашифрования/расшифрования особо важных документов


Реализация на втором этапе (отдалённая перспектива). Характеристики:


Ссылки
[link1] http://www.vladmiller.info/blog/index.php?comment=96