Задать вопрос
  • Стоит ли фильтровать пароль на символы?

    Vamp
    @Vamp
    У вас классическая проблема обработки пользовательского ввода. Решается она по-разному в зависимости от контекста, в котором используются данные. Так как вы не указываете контекст, то и ответ будет соответствующе широким.

    1. Запрос первоначально поступает в node.js (конкретно в движок v8, отвечающий за сетевое взаимодействие). Здесь возможны уязвимости, при которых специальным образом сформированный запрос может привести к отказу в обслуживании (DoS), несанкционированному доступу к памяти (вспоминается эпичнейшая уязвимость heartbleed) и иным спецэффектам.

    2. Далее запрос поступает в express, где он парсится и преобразовывается в объект req. Здесь так же могут быть уязвимости, эксплуатируемые путем отправки специально сформированного запроса.

    Пункты 1 и 2 исполняются до вашего кода, поэтому всё что вы можете здесь поделать - это вовремя обновлять софт и библиотеки.

    3. Далее ваш код занимается обработкой данных. Важный момент в этом - санация и валидация данных.

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

    Валидация - это проверка данных на корректность. Например, вы ожидаете номер телефона в поле phone. После санации останется проверить, что длина номера не нулевая и не больше 15.

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

    Либо если данные будут вставляться в базу данных, то необходимо экранировать данные (либо вставлять данные через подготовленные запросы) чтобы не получить SQL injection уязвимость.

    Вот тут как раз и появляется зависимость от контекста. В контексте базы данных - один способ экранирования. В контексте json - другой. В контексте HTML (при выводе данных пользователю) - третий. В ещё каком-нибудь другом контексте будут свои способы обезопасить данные.

    Если рассматривать конкретно пароль, то с ним всё просто. Как правило, пароли не хранятся на сервере в открытом виде и предварительно подвергаются преобразованию в криптографически стойкий хеш (например, argon2 или scrypt). Сам хеш уже имеет фиксированный размер и известный набор символов. Поэтому санировать пароль не нужно, а при валидации просто проверить минимально допустимую длину, несовпадение с логином, email и может ещё какие-нибудь проверки, навязанные бизнесом или применяемыми стандартами.
    Ответ написан
    6 комментариев
  • Как в контейнере сделаться рутом?

    Vamp
    @Vamp
    Ваш образ создан from scratch. Это значит, что в нём только приложение. И больше ничего лишнего нет. В том числе и бинарника /bin/bash, путь к которому вы указываете в /etc/passwd

    Возьмите образ на основе альпины: anycable/anycable-go:1.2-alpine
    Там есть /bin/sh, пакетный менеджер и ещё всяких разных утилит по мелочи.
    Ответ написан
    1 комментарий
  • Как работать с сырыми результатами SELECT MySQL CLI в PHP CLI?

    Vamp
    @Vamp
    Вам придется самостоятельно парсить $res в более удобный массив или объект. Можно слегка упростить вывод mysql, добавив аргумент --batch.
    Ответ написан
    1 комментарий
  • Как авторизовавшись на одном сайте в "сети сайтов", быть автоматически авторизованным и на других?

    Vamp
    @Vamp
    Видел однажды такую реализацию.

    При успешном прохождении авторизации кидает на страницу, где через тег img подключается "картинка" с каждого домена, участвующего в sso тусовке.

    <h2>Вы успешно вошли</h2>
    <img src="https://example.com/auth.php?key=1hB7fa014bbXCDg920">
    <img src="https://example.net/auth.php?key=hVVFD41looas8730MM">
    <img src="https://example.org/auth.php?key=QnaVBhj7mqwaBK9xq6">

    При авторизации создаётся и записывается в базу пачка одноразовых временных токенов, привязанных к только что авторизованному пользователю. При загрузке auth.php проверяется этот токен (передается через key в примере выше) и если токен ещё не просрочился, то выдаётся однопиксельный прозрачный gif с авторизационным кукисом. Этот кукис привязывается к домену, с которого загружается картинка.
    Ответ написан
    1 комментарий
  • Зачем освобождать память в C?

    Vamp
    @Vamp
    Потому что неосвобождённая память остаётся занятой даже после выхода указателя за пределы области видимости. В итоге если вы будете только аллоцировать память, но не освобождать её, то рано или поздно программа сожрёт всю память в системе.
    Ответ написан
    1 комментарий
  • Что означает синтаксис dockerfile (php-fpm)?

    Vamp
    @Vamp
    что такое dev суфикс (freetype и freetype-dev) и как понять какую версию ставить (я ставил методом тыка, когда получал ошибки и гуглил)

    Dev суффикс означает, что в данном пакете присутствуют файлы, необходимые для компиляции кода, использующего устанавливаемую библиотеку. Устанавливать нужно обе версии. Обычная версия "freetype" содержит саму библиотеку в so файле, которую gd будет подключать в рантайме. Dev версия "freetype-dev" нужна для сборки самого gd, так как модуль собирается из исходников.

    почему, например, для mycrypt мне сперва нужно загрузить именно libmcrypt-dev, потом через pecl скачать mcrypt, а потом через алиас docker-php-ext-enable включить (экспериментировал и не работает с другими сценариями), а если смотреть на opcache, тот тут сразу docker-php-ext-install и все, а xdebug еще один сценарий: pecl -> docker-php-ext-enable - почему все по разному, как это понять?

    Для разных модулей требуются разные сторонние библиотеки. Для gd это freetype (для работы со шрифтами), libpng (для поддержки формата png), libjpeg-turbo (для поддержки jpeg). У opcache таких зависимостей нет, поэтому ничего дополнительно устанавливать не требуется.

    в чем отличие этих сценариев установки расширений (что делает каждая команда, простыми словами)?

    У php есть модули, которые поставляются с самим php. Например: zip, opcache, pdo_mysql, intl. Такие модули устанавливаются специально предусмотренным для этого скриптом docker-php-ext-install. Этот скрипт распаковывает исходники php, собирает запрошенные вами модули, копирует их в /usr/local/lib/php/extensions/no-debug-non-zts-20190902 (в других образах php путь может отличаться), прописывает загрузку модуля в ini и удаляет распакованные ранее исходники. То есть под капотом скрипт docker-php-ext-install вызывает скрипты docker-php-source, docker-php-ext-configure, docker-php-ext-enable.

    А есть модули, которые хостятся отдельно на сайте pecl.php.net. Это официальный репозиторий, где хостятся всякие разные сторонние модули типа mcrypt, imagick, xdebug. Для их установки нужно использовать утилиту pecl. Так как pecl автоматически не включает модули в ini, из-за этого необходимо самому включать их при помощи скрипта docker-php-ext-enable.

    нагуглил что
    docker-php-source - создает /usr/src/php

    Ещё распаковывает туда исходники самого php и поставляемых с ним модулей.

    docker-php-ext-install - скачивает (ОТКУДА?)

    Из архива /usr/src/php.tar.xz

    docker-php-ext-configure- конфигурирует перед установкой (что это значит?)

    Этот скрипт настраивает настройки, с которыми будет скомпилирован модуль. Например, тот же gd можно собрать без поддержки jpeg если сконфигурировать без опции --with-jpeg. Нужно ли запускать docker-php-ext-configure так же зависит от того, что написано в документации. Очень мало модулей требует предварительной конфигурации перед установкой. Мне на ум приходит только gd.

    В целом, официальная документация php вам поможет понять каким способом нужно устанавливать модули. Смотрим раздел requirements. Если написано "This extension is bundled with PHP", значит нужно устанавливать при помощи скрипта docker-php-ext-install. Если написано что-то вроде "This PECL extension is not bundled with PHP", значит нужно устанавливать через pecl.

    Независимо от способа установки, нужно всегда устанавливать библиотеки, от которых зависят конкретные нужные вам модули. Например, в том же imagick написано "ImageMagick >= 6.2.4 is required". Это значит, что нужно установить библиотеку imagemagick. В вашем базовом образе на основе alpine 3.16 в репозиториях ОС присутствует версия 7.1.0, которая подходит под условие >= 6.2.4:

    /var/www/html # apk info imagemagick
    imagemagick-7.1.0.35-r0 description:
    Collection of tools and libraries for many image formats
    
    imagemagick-7.1.0.35-r0 webpage:
    https://imagemagick.org/
    
    imagemagick-7.1.0.35-r0 installed size:
    4664 KiB


    Для intl нужна "ICU library, version 4.0.0 or newer". Такая библиотека тоже присутствует в репозиториях альпины:

    /var/www/html # apk info icu
    icu-71.1-r2 description:
    International Components for Unicode library
    
    icu-71.1-r2 webpage:
    https://icu.unicode.org/
    
    icu-71.1-r2 installed size:
    796 KiB


    Dev версии библиотек нужны только в момент установки модулей. Дальше их желательно удалить, чтобы уменьшить размер вашего образа.
    Ответ написан
    6 комментариев
  • Установка php в Docker?

    Vamp
    @Vamp
    RUN DEBIAN_FRONTEND=noninteractive apt-get install -y php php-pgsql php-mbstring php-xml php-apcu composer php-mongodb php-curl php-memcached
    Ответ написан
    Комментировать
  • Почему не работает List-Unsubscribe?

    Vamp
    @Vamp
    Спамеры пользуются этой фичей как подтверждением доставки. Раз отписался, значит точно живой и начнут спамить в три раза сильнее.

    Раз кнопка не появилась, значит ваша репутация рассыльщика недостаточно хороша или вообще отсутствует. Соблюдайте требования почтовых сервисов и кнопка появится рано или поздно.
    Ответ написан
    Комментировать
  • Как организовать monorepo с привязкой к версии maven?

    Vamp
    @Vamp
    Вы можете собрать весь проект целиком, тогда в maven reactor будут добавлены сразу все модули и dependency resolver сможет разобраться в зависимостях от соседних модулей. Но если собирать один конкретный модуль, то мавен уже не разберётся и полезет во внешние репозитории. В таком случае необходимо передать дополнительный ключ -am (--also-make):

    mvn -am -pl модуль package
    Ответ написан
    Комментировать
  • Как данные перемещаются в сети интернет, всегда конвертируются в кадры Ethernet или остаются в пакетах IP?

    Vamp
    @Vamp
    1. Пакеты не конвертируются друг в друга, а вкладываются. То есть в типичном пакете имеются сразу три заголовка - Ethernet, IP и TCP. И когда маршрутизатор решает куда отправить пакет дальше, смотрит только на заголовок IP. У маршрутизатора существует таблица маршрутизации, которая указывает какие IP адреса на какой интерфейс отправлять. Непосредственно перед отправкой маршрутизатор перезапишет ethernet заголовок и вставит в него свой MAC в поле "source MAC address", а MAC выбранного следующего получателя в поле "destination mac address".

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

    2. Упаковка в Ethernet может быть пропущена только если источник пакета по каким-то своим внутренним соображениям решает не отправлять его. Например, если сработало запрещающее правило фаервола. Очевидно, что такой пакет не покинет своего места рождения. И, кстати, Ethernet - это ещё не физический уровень.

    3. Ethernet используется в локальных сетях. И топология LAN на это не влияет - с маршрутизатором или без него.

    4. Если есть чисто локалка на свиче, то сетевой уровень по-любому используется?
    Да, сетевой уровень используется и здесь.

    Допустим с датаграммы udp упаковка в ip пакет, затем только в кадр ethernet?
    Да, UDP заворачивается сначала в IP, а затем в Ethernet.

    И по-любому отрабатывают dhcp и arp?
    DHCP не является обязательным для применения (он, кстати, работает поверх UDP). ARP тоже может не использоваться, если в этой сети не используется IP адресация (а вот ARP уже самостоятельный протокол канального уровня, который упаковывается только в Ethernet).

    5. Во времена до изобретения Ethernet использовались другие протоколы. Соответственно, и оборудование было другое, поддерживающее данные протоколы.
    Ответ написан
    3 комментария
  • Почему поток не останавливается?

    Vamp
    @Vamp
    Тут есть две проблемы.

    Первая очевидная проблема в том, что main поток на первой же итерации впадает в сон на методе wait(), а в программе больше нет потоков, которые могли бы вызвать notify() и разбудить main. Поэтому main бесконечно ждёт и не может остановить liche и sude.

    Вторая совсем неочевидная в том, что синхронизация некорректно используется. У вас синхронизируется только запись в переменную isRun. Чтение этой переменной так же должно быть синхронизировано. Иначе это приведет к странным неуловимым багам.
    Ответ написан
    2 комментария
  • Как запустить майнкрафт через коммандную строку?

    Vamp
    @Vamp
    Для 1.17.1 нужна java версии 17. Судя по ошибкам у вас 8 версия.
    Ответ написан
    Комментировать
  • DNAT. Где ошибка?

    Vamp
    @Vamp
    Нужно ещё указать таблицу nat

    iptables -t nat -A PREROUTING -d 4.4.4.100 -p tcp -m tcp --dport 2222 -j DNAT --to-destination 192.168.100.100:22
    Ответ написан
    Комментировать
  • Методы или инструменты на python для построения маршрута на схематичной карте в игре?

    Vamp
    @Vamp
    Вам необходимо разбить карту на тайлы и воспользоваться одним из алгоритмов поиска пути.

    Например, A*. Это популярный алгоритм с большим количеством примеров по всему интернету. Наверняка найдется и готовая библиотека с его реализацией.
    Ответ написан
    1 комментарий
  • Как на PHP при OAuth-авторизации в Яндекс.Почте работать по протоколам IMAP и SMTP, используя не пароль, а OAuth-токен?

    Vamp
    @Vamp
    Стандартный модуль php_imap не поддерживает XOAUTH2. И, вероятно, никогда не будет поддерживать. Существует план поддержки XOAUTH2, но работа по нему не ведётся.

    Вам следует воспользоваться альтернативными реализациями IMAP протокола, поддерживающие XOAUTH2. Например, webklex/php-imap.

    С SMTP так же - берите любую библиотеку с поддержкой XOAUTH2.
    Ответ написан
    Комментировать
  • Технический нейминг серверов. По какому принципу называть сервера?

    Vamp
    @Vamp
    Я использую нейминг по физическому расположению сервера.

    {имя дц}-{номер стойки}-{номер юнита в стойке}

    Получается что-то типа:

    miran-8-40
    itsoft-1-1

    Если хотите покороче и фикс длину, можно брать первую букву ДЦ (или две буквы, если есть совпадения) и выравнивать цифры ведущим нулём:

    m-08-40
    i-01-01

    Если серверов не так много чтобы арендовать стойки целиком, то просто порядковый номер сервера:

    m-01
    i-15

    Ну или два/три ведущих нуля, если количество серверов 1000/10000:

    m-001
    i-015

    Самый короткий вариант нейминга у меня получился 2х символьный.

    Почему не 1 символ?
    Ответ написан
    3 комментария
  • Платформа/движок для сбора обращений граждан?

    Vamp
    @Vamp
    Подойдёт любая тикетница. Например, OTRS или osTicket. Каждое обращение - новый тикет. Тикетам можно настраивать напоминания, если они не закрыты какое-то время (sla), приоритеты.
    Ответ написан
    Комментировать
  • Как в терминале открыть путь до папки?

    Vamp
    @Vamp
    Выполнить один раз на сервере команду:
    echo 'cd /papka' >> ~/.bashrc
    Ответ написан
    Комментировать
  • Как правильно написать свой обработчик ошибок php?

    Vamp
    @Vamp
    Как правило, обычные ошибки не обрабатывают в таком обработчике, а конвертируют в ErrorException.

    function error_handler(
        $error_code,
        $error_message,
        $error_file_name,
        $error_line
        // $error_context - не объявляйте этот аргумент. Он не существует.
      ){
    
        throw new ErrorException($error_message, 0, $error_code, $error_file_name, $error_line);
    
      }
    
      set_error_handler('error_handler', -1);

    Ну а дальше ловите исключения как обычно.

    // some code...
    
    $host_db = '127.0.0.1';
    $login_db = 'root';
    $password_db = '';
    $database_db = 'some_db';
    
    $DB = new PDO('mysql:host=' . $host_db . ';dbname=' . $database_db, $login_db, $password_db);
    $DB -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    try {
        $DB -> beginTransaction();
    
        // some code...
    
        $DB -> commit();
    } catch (\Throwable $e) {
        $DB->rollback();
    }
    // some code...
    Ответ написан
    6 комментариев
  • Как происходит связывание с предыдущим узлом в LinkedStack?

    Vamp
    @Vamp
    1. Просто чтобы продемонстрировать использование паттерна sentinel value. В данном конкретном примере можно было обойтись просто null.

    2. В присваивании сначала выполняется правая часть - создаётся объект Node, которому в аргументы конструктора передается item и текущее значение, хранящееся в переменной top. После этого переменной top присваивается ссылка на этот новый объект.

    Это более короткий вариант следующего кода:
    Node<T> oldTop = top;
    top = new Node<T>(item, oldTop);
    Ответ написан
    4 комментария