Представляю вам сайт bin.so — сервис для обмена текстовой информацией. Отличается от других функциями защиты данных:


  • Каждому загруженному тексту выделяется уникальный случайный URL
  • Если указать пароль, то информация шифруется прямо в браузере и на сервер сохраняется только зашифрованная версия данных. Для просмотра данных нужно ввести пароль, чтобы расшифровать в браузере данные, полученные с сервера.
  • Поисковым системам запрещено индексировать содержимое сайта
  • HTTPS везде

Шифрование данных в браузере обеспечено библиотекой SJCL. Данные шифруются AES алгоритмом в режиме GCM. Исходный код доступен на github. Серверная часть написана на python, веб-фреймворк Bottle, доступ к данным через peewee. База данных, по-умолчанию, sqlite.


Пользователи heroku могут запустить копию сайта в пару кликов мышки. Склонируйте репу на github. Через веб-интерфейс heroku создайте новое приложение и подключите github-репу.

Поделиться с друзьями
-->

Комментарии (77)


  1. mwizard
    07.10.2016 00:21
    +10

    Немного, самую капельку, смущает webvisor от Яндекса, который отправляет в Яндекс все нажатия клавиш (включая контент и пароли), и адреса секретных страниц.


    1. Reeze
      07.10.2016 00:49
      +1

      Идея хорошая, НО…

      Отличается от других функциями защиты данных




      В свете этой новости: https://geektimes.ru/post/281188/

      Домен в зоне пиратского Сомали тоже не внушает.

      Всё это поправимо.


      1. itforge
        07.10.2016 01:03

        По startcom ничего не скажу сейчас, надо разбираться.

        По поводу .so хочу услышать подробности, как доменное имя влияет на защиту данных.


        1. Reeze
          07.10.2016 01:29

          По startcom ничего не скажу сейчас, надо разбираться.


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

          По доменному имени моё чисто субъективное мнение.


          1. itforge
            07.10.2016 01:41

            Я правильно понял, что мне нужно поменять центр сертификации ДО чтения статьи? Потому что вы так сказали сделать? Я правильно понял? :)


            1. Reeze
              07.10.2016 02:08
              -1

              Вы статью выше прочитали?

              Вообще, мне нравится ваш подход.
              «Защищённый сервис, которому можно доверять»

              Я завершаю комментирование в этой теме.


              1. itforge
                07.10.2016 02:40
                +2

                Статью читал, и не только её. Центр сертификации скорее всего поменяю.


      1. antonwork
        07.10.2016 01:17
        +1

        Слышал звон, да не знает, где он


  1. mwizard
    07.10.2016 00:34
    +1

    Каково происхождение файла /static/sjcl.js? Он существенно отличается от официальной минифицированной версии. Как получить вашу версию из официальной?


    1. itforge
      07.10.2016 00:38
      +2

      Файл был скачан с cdnjs.com. Конкретно, вот ссылка на файл: https://cdnjs.cloudflare.com/ajax/libs/sjcl/1.0.6/sjcl.min.js


  1. itforge
    07.10.2016 00:36
    +1

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


    1. thunderspb
      07.10.2016 13:12
      +1

      посмотрите на piwik


    1. eternal_sorrow
      07.10.2016 15:35

      неужели не осталось возможности как раньше, добавить на страницу пиксель счётчика чтобы получать минимальную статистику? все счётчики тянут с собой длинный js?


      1. itforge
        07.10.2016 15:36

        Осталось возможности. Например, liveinternet. Но я решил вообще убрать JS статистику.


  1. vsb
    07.10.2016 00:38
    +6

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


    1. itforge
      07.10.2016 00:41
      +2

      Думаю — никак. Единственное решение, поднять копию сервиса на своём сервере.


      1. wscms
        07.10.2016 00:44

        Или уйти от *.min.js, чтоб все было прозрачно


        1. itforge
          07.10.2016 00:48

          Что вы имеете в виду? Грузить с github?


          1. DenimTornado
            07.10.2016 10:23

            Нет, просто положить несжатые версии файлов.


      1. rumkin
        07.10.2016 03:32

        Думаю, можно сделать standalone-версию в виде архива с md5-хэшем содержимого. А тем кому "на постоянку" в electron завернуть.


        1. itforge
          07.10.2016 04:01

          standalone-версия чего? Исходного кода? А разве любой отдельной взятый commit в github репозитории не явялется такой standalone-версией?


          1. rumkin
            07.10.2016 13:44

            Нет, в standalone-версии все что можно нужно уместить в самом html-файле.


            1. itforge
              07.10.2016 16:20

              Этот сервис нельзя уместить в одном html файле, потому что ему нажна база данных для хранения дампов.


              1. rumkin
                10.10.2016 12:39

                standalone-версия клиента.


    1. dom1n1k
      07.10.2016 00:45

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


      1. zartdinov
        07.10.2016 01:30
        +3

        Возможно будут интересны механизмы уже встроенные в последние версии браузеров, такие как Subresource Integrity, Content Security Policy и тд.

        <script src="https://example.com/example-framework.js"
                integrity="sha384-Li9vy3DqF8tnTXuiaAJuML3ky+er10rcgNR/VqsVpcw+ThHmYcwiB1pbOxEbzJr7"
                crossorigin="anonymous"></script>
        


        1. mwizard
          07.10.2016 01:32
          +1

          Интегрити защищает от того, что CDN вместо ожидаемого jquery выдаст jquery с бонусом, собирающим пароли. Но интегрити не защищает от того, что владелец сайта выдаст вредоносный скрипт с правильным интегрити. Либо просто добавит еще один скрипт в страницу, который перезаписывает часть объектов и функций.


          1. rumkin
            07.10.2016 03:40

            Гипотетически для этого есть HTTP-заголовок Content-MD5 + исходники на github с GPG подписью. Но с автоматической проверкой будут проблемы.


          1. zartdinov
            07.10.2016 13:41

            Да, лишь для тех кто форкает и поднимает свою копию


          1. itforge
            08.10.2016 16:27

            На данный момент:

            * сторонний JS грузится только через CDN с заданным integrity
            * я зарефакторил client-side часть приложения в один HTML/JS файл. При желании можно сверять SHA-хэш содержимого страницы (то что изначально выдаёт веб-сервер по GET запросу) с хэшем файла на github.


      1. mwizard
        07.10.2016 01:31

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


        1. rumkin
          07.10.2016 03:46

          Я предполагаю что решить это можно с помощью локального прокси, который на все html-ки будет вычислять хеши и проверять в какой-нибудь распределенной БД с подписями для версий. Но это подходит для SPA и статических сайтов. Так же снизится скорость при первой загрузке. Ну и придется эту распределенную БД сделать и поддерживать )


          1. yamatoko
            07.10.2016 04:52
            +1

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


        1. itforge
          08.10.2016 16:28

          Смотрите чуть выше мой комментарий, это решает проблему.


    1. mwambanatanga
      07.10.2016 09:41

      Как вариант, решается путём использования механизма, существующего в нескольких реализациях. Например, PGP есть как в виде традиционного софта, так и в виде JS (например, https://github.com/openpgpjs/openpgpjs). Существование выбора позволяет — при наличии сомнений в подлинности скрипта — полностью отключить в браузере скрипты, шифровать текст оффлайновой программой и вставлять готовые кракозябры в поле ввода.


      1. VeroLom
        08.10.2016 09:54

        Какой тогда в этом сервисе смысл, если можно просто обменяться публичными ключами и перекидываться кракозябрами через E-mail/Telegram/IRC/etc?


        1. itforge
          08.10.2016 09:55

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


  1. dcc0
    07.10.2016 00:52

    Интересная идея. Т.е. вполне можно поднять в корпоративной сети и хранить копии документов.


    1. dartraiden
      07.10.2016 08:17

      Можно ещё ZeroBin для этой цели рассмотреть.


  1. InfiniteCode
    07.10.2016 02:22

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

    Сейчас тот факт, что оно хранится на бекенде, уже не особо.


    1. itforge
      08.10.2016 16:33

      Интересная идея, но думаю будет очень много проблем из-за ограничений браузеров, а также всяких промежуточных прокси-серверов. Кстати, придумал забавный вариант кодирования информации, можно настроить * сабдомен для домена и запихивать всю информацию в поддомены, разбивая на 63 символа (максимальная длинна сегмента в доменном имени).


  1. Hacksli
    07.10.2016 02:49

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


    1. itforge
      08.10.2016 16:35

      Я зарефакторил код приложения, сейчас это один html/js файл (на riotjs) + парочка API вызовов, которые совсем не сложно будет сделать на PHP или nodejs


  1. mwizard
    07.10.2016 03:25
    +3

    Автор, я посмотрел немного на вашу реализацию, и у меня есть вопросы к тому, что вы делаете, и почему так.


    Зашифрованные данные хранятся в виде base64, в котором json, в котором параметры шифра в base64. Зачем так сложно? У вас шифротексты распухают в несколько раз по сравнению с открытыми данными, причем без малейшего увеличения безопасности. Почему не использовать бинарную структуру с номером версии в первом байте?


    Для того, чтобы сгенерировать новый адрес для дампа, вы десять раз генерируете случайное число в пределах 263 и пытаетесь создать запись в БД с таким первичным ключом. Если не получилось десять раз, то все, все пропало. Что это, и зачем? Откуда число 10? Почему вы не используете uuid + sha3 контента по вкусу?


    Насколько вообще тут нужен SQLite, да и вообще, любая RDBMS, учитывая, что все виды запросов сводятся к записи по первичному ключу и к чтению по первичному ключу. Ни поисков, ни подсчетов. Зачем тут БД, которая еще и не масштабируется?


    1. itforge
      07.10.2016 03:59
      -3

      Я это всё по приколу за два дня написал. Плюс криптографию я знаю на уровне «Криптография? Не, не слышал». Поэтому есть простор для оптимизации :)

      1) JSON запихал в base64 для красоты, чтобы не было видно потроха JSON. Насчёт размера данных не думал пока. Бинарная структура, как её встроить в страницу? Ведь при просмотре дампа данные должны быть как-то встроены в страницу перед тем, как можно будет их расшифровать с помощью пароля.

      2) Число 10 от балды. Как именно из «uuid + sha3» получить число в диапазоне 1-2^63? Чем это будет отличаться от генерации случайного числа?

      3) По-умолчанию, используется sqlite, чтобы можно было легко запустить приложение и начать с ним играться. Конкретно на bin.so сейчас postgres используется. В целом, вопрос не понял. Чем вам не нравится использование RDBMS и какую альтернативу вы предлагаете.


      1. ZyXI
        07.10.2016 11:25
        +4

        Я бы сначала просто сохранял в файловой системе файлы вида static/paste/614c9128/8c65/11e6/ba31/50465d597777, отдавая их напрямую веб?сервером. И никаких БД вообще, пока с таких подходом не появятся (если вообще появятся) проблемы, которые решаются введением БД.


        1. itforge
          07.10.2016 15:58

          У меня нет никаих проблем с БД, зачем мне заменять её на файловую систему?


          1. mwizard
            07.10.2016 15:59

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


            1. itforge
              07.10.2016 16:18

              Хорошо, для начала соглашусь с вами. Однако есть нюансы, о которых я не говорил. Я планирую запретить грузить дампы больше нескольких мегабайт на сервер. Как раз для того, чтобы никто не грузил туда сотню дампов размером в гигабайт-два :) Мой сервис не предназначен для обмена файлами, он предназначен для обмена текстовой информацией небольшого размера.

              Думаю, размер дампа сейчас ограничен дефолтным значением nginx настройки client_max_body size, равной 1мб.

              Можно я теперь буду таки использовать базу данных? :)


              1. mwizard
                07.10.2016 16:22

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


      1. mwizard
        07.10.2016 13:44
        +4

        1. бинарную структуру можно встроить в страницу тем же base64, но при этом увеличение объема составит только 30%, либо запросить ее по сети с адреса вида http://bin.so/raw/<paste-id>, и тогда увеличения объема не будет вовсе, плюс не придется парсить <pre> ???р?????е???г??????у??л????я???рк?????ами?????.


        2. зачем вам число в диапазоне 1-2^63? Вам нужно получить уникальное число, которым нужно описать контент. Желательно, с первой попытки. UUID4 справляется с этим сам по себе, но если мы хотим быть совсем перестраховщиками, мы кроме случайной компоненты учитываем еще и хэш контента. В этом вроде как на первый взгляд нет практической необходимости, но у сервера может быть не очень качественный источник энтропии, и таким образом мы это немного исправляем. Для справки, UUID4 имеет размер 122 бита, SHA3 имеет размер 512 бит.

        Предположим, каждую наносекунду на вашем сервисе содается один миллиард записей. В год это будет 31'536'000'000'000'000'000'000'000 записей, или, округляя вверх, 285. Вероятность того, что за год у нас будет сгенерировано два одинаковых идентификатора, составляет:


        • только для UUID4 = 1 к 3 * 1011
        • только для SHA3 = 1 к 7 * 10128
        • для UUID4 + SHA3 = 1 к 4 * 10165

        Википедия утверждает, что годовая вероятность того, что в отдельно взятого человека прямой наводкой упадет метеорит, составляет 1 к 6 * 1011, что примерно дает понимание масштаба указанных цифр. Для понимания масштаба количества записок в такой нотации, если каждая записка займет 1 байт, то за год их соберется 32 йобибайта (32768 зебибайта = 33554432 эксбибайта = 34359738368 пебибайта), или, если пересчитать на 15 ТБ SSD-модули от Samsung, где-то 24 мегатонны чистого кремния.


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


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


        1. itforge
          07.10.2016 15:54
          -2

          По поводу базы данных. У меня нет ничего такого, для чего бы мне понадобилось использовать файловую систему. База данных вполне решает проблему чтения-сохранения данных.


        1. itforge
          07.10.2016 16:11

          Число 2^64 это примерно 10 позиций числа в 52-ричной системе счисления. Откуда 52? Это латинские буквы в двух регистра плюс цифры минус буквы и цифры, которые похожи на другие буквы и цифры. То есть я выкинул i, l, 1, o, 0 и т.д. Так вот если у нас урл состоит из 10 буквоцифр, то его можно на бумажку записать. И уникальность вполне себе хорошая. Если взять uuid, то буквоцифр будет в два раза больше и записывать на бумажку можно, конечно, но уже труднее. И тут вопрос, для чего использовать длинные уникальные урлы, если можно использовать короткие уникальные урлы и это будет удобнее.

          >>> math.log(2**64, 52)
          11.227204069245088
          >>> math.log(2**122, 52)
          21.40185775699845


          1. mwizard
            07.10.2016 16:21

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


            1. itforge
              07.10.2016 16:47
              -2

              Я не понимаю, что вам не нравится. В данный момент сервис генеририрует случайные урлы для каждого дампа. Я объяснил, почему хочу, чтобы размер урла был около 10 байт. Пересчитайте это в мегатонны чистого кремния и россыпи SSD-дисков — достаточная же уникальность?


      1. planarik
        07.10.2016 15:38

        Минималистичный защищённый сервис обмена текстовой информацией
        Плюс криптографию я знаю на уровне «Криптография? Не, не слышал»

        Shit up and take my money!


        1. mwizard
          07.10.2016 15:54

          "Shit up" — это ведь не опечатка, верно? 😏


  1. azsx
    07.10.2016 04:34

    Спасибо, интересно.
    1. Не верно работают пароли в кирилице.
    2. Если ввести текст, пароль, нажать шифрование, а затем нажать кнопку в браузере назад — то поведение сайта становится не очевидным.


    1. itforge
      07.10.2016 04:36

      2. Что вы имеете в виду?


      1. azsx
        07.10.2016 09:27

        Извините, пожалуйста, не совсем понимаю как именно, но я явно ошибся.


    1. itforge
      07.10.2016 04:40

      1. Попробовал пароли из чистой кириллицы, а также смесь кириллицы и латиницы — у меня работает всё.


  1. stargrave2
    07.10.2016 08:17

    Написано что используется режим шифрования SGM, но в коде я вижу «This script works only with data encrypted in AES GCM mode». Опечатка?


    1. itforge
      07.10.2016 08:23

      Опечатка, поправил статью.


  1. Antelle
    07.10.2016 09:26
    +4

    Шифрование данных в браузере обеспечено библиотекой SJCL.

    Советую посмотреть в сторону WebCrypto, он и быстрее, и вопросов не будет, чем вы шифруете. http://caniuse.com/#feat=cryptography
    Домен в .so — хорошо. Ещё хорошо бы написать в FAQ, абузоустойчивый сервис или нет, удаляете ли пасту по запросу. Ещё самоудаляемые пасты по времени (или при первом просмотре) были бы полезны такому сервису.


    1. itforge
      07.10.2016 16:30

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

      Сервис не абузоустойчивый. А такие вообще бывают? Ну, допустим, можно купить за 100-200 баков крайне лояльный к абузам хостинг, но ведь абузы могут и регистратору слать.

      > http://caniuse.com/#feat=cryptography

      Смущает, например, что на мобилках с андроидом 4.4 не будет работать.


      1. mihmig
        07.10.2016 23:02
        +1

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


        1. prefrontalCortex
          07.10.2016 23:18

          Можно юзерагент смотреть, например.
          А мессенджеры нынче как на отправленные в них ссылки ходят? Тупо GET'ом берут и идут? Даже HEAD не пытаются?


          1. mwizard
            07.10.2016 23:48
            +2

            Нужно отдавать не страницу с контентом, а страницу с кнопкой "посмотреть", которая POST-ом получает и удаляет контент.


            1. itforge
              08.10.2016 09:53

              Да, это хорошая идея.


  1. mihmig
    07.10.2016 15:53

    Раньше использовал как онлайн хранитель паролей keymemo.com
    Для случаев, когда не на своём компе а надо записать сточно и даже карандаша нет использую
    http://piratepad.net/ — в нём можно создавать свой URL, например http://piratepad.net/задача1
    (но шифровать заметки вроде бы нельзя)


  1. dom1n1k
    08.10.2016 22:17

    Я бы переверстал страницу — все ссылки и настройки свалил бы в левую колонку в столбик, а textarea на ~75% ширины и 100% высоты.


    1. itforge
      08.10.2016 22:21

      С целью?


      1. dom1n1k
        09.10.2016 00:29

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


        1. itforge
          09.10.2016 02:40

          Я подумаю. А какая у вас ширина браузера? Я за стареньким 19" квадратным моником сижу :)


          1. dom1n1k
            09.10.2016 13:05

            FullHD у меня. И думаю, что сейчас это уже близко к минимуму для сегмента проф пользователей.
            Если говорить о массовой публике, то там очень популярны ноуты 1366x768 — но в любом случае, это тоже широкий экран.
            Квадратных мониторов сейчас, вроде бы, менее 10%.


          1. dom1n1k
            09.10.2016 15:23

            И настоятельно советую сменить Courier на нормально читаемый шрифт, благо такие давно есть. Как-то так примерно:

            font-family: Consolas, Monaco, Andale Mono, Roboto Mono, DejaVu Mono, monospace;
            


            1. mwizard
              09.10.2016 15:50

              Или даже так, т.к. Menlo визуально плотнее Monaco.

              font-family: Menlo, Consolas, Monaco, Andale Mono, Roboto Mono, DejaVu Mono, monospace;