Приведён код на сервере на PHP, который формирует SQL-запрос строкой, принимая данные от пользователя, и шифрование данных реализовано на собственном алгоритме XOR: оцените уязвимости (включая SQL-инъекции и криптографические ошибки), опишите возможные атаки и предложите конкретные безопасные практики для исправления кода

26 Сен в 20:29
16 +1
0
Ответы
1

Спасибо — ниже привожу развернённую оценку типичных уязвимостей в описанной вами конструкции (формирование SQL-запроса строкой + собственный алгоритм XOR), возможные атаки и конкретные безопасные практики + примеры исправления на PHP.

Кратко: комбинирование ручной конкатенации SQL + «домашняя» криптография (XOR) — высокоопасно. Нужно срочно убрать конкатенацию в пользу параметризированных запросов и заменить XOR на проверенные криптографические примитивы (AEAD). Также улучшить управление ключами, обработку ошибок и привилегии БД.

1) Уязвимости и почему они опасны

SQL-инъекция (очевидно)

Конкатенация пользовательских строк в SQL позволяет вставлять синтаксис SQL и выполнять произвольные запросы (SELECT … OR 1=1; ; DROP TABLE; UNION SELECT …).Может привести к утечке данных, модификации/удалению таблиц, обходу авторизации.

Криптографические ошибки при использовании XOR

XOR с кратким повторяющимся ключом = полифазная подстановка (аналог Vigenère). Поддаётся частотному и статистическому анализу.Повторное использование ключа для разных сообщений = критическое нарушение (как reuse в одноразовом блокноте OTP). Из XOR-шифров возможно получение XOR двух plaintext’ов, что упрощает восстановление.Отсутствие аутентификации сообщения: атаки на подделку/модификацию (bit-flipping) возможны без обнаружения.Отсутствие защищённого хранения/генерации ключа, отсутствие нормального IV/nonce.Доморощенные алгоритмы часто имеют дополнительные побочные ошибки (байтовые границы, непредсказуемое паддинг и т.п.).

Прочие проблемы

Отсутствие TLS или слабая конфигурация транспортного уровня.Неправильное хранение секретов в коде / config.Неправильная обработка паролей (шифровать пароли — нет, хешировать нужно).Логирование секретных данных/ошибок в открытый лог.Неправильные привилегии БД (root вместо ограниченной учётной записи).

2) Возможные реальные атаки

SQL-инъекция:

Вставка "' OR '1'='1" в поле логина для обхода авторизации.UNION SELECT для вытаскивания других таблиц.Вставка ; DROP TABLE users; -- для удаления таблицы (если БД позволяет составные запросы).Blind SQLi через тайминги/Boolean/инфо-уровень.

Крипто-атаки на XOR:

Chosen-plaintext: если атака может подставить известный ввод и получить зашифрованный результат, можно вычислить ключовый поток (keystream) и дешифровать другие сообщения, шифрованные тем же ключом.Known-plaintext: если известен фрагмент plaintext и соответствующий ciphertext, можно извлечь часть ключа.Statistical attacks: для больших объёмов и повторяющихся ключей — восстановление всего ключа.Bit-flipping: возможность модифицировать зашифрованные данные и атаковать логику приложения (если нет MAC).Replay attacks: отсутствие контроля целостности и времени/nonce — можно повторно отправлять старые зашифрованные данные.

3) Конкретные рекомендации/правки

A. Защита от SQL-инъекций (обязательно)

Всегда использовать параметризованные запросы (prepared statements) с bind-параметрами. Не формируйте SQL строкой через конкатенацию.Пример (PDO), безопасная вставка данных:
Подключение:
$pdo = new PDO('mysql:host=...;dbname=...', $user, $pass, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);Выполнение:
$stmt = $pdo->prepare('INSERT INTO users (username, email) VALUES (:username, :email)');
$stmt->execute([':username' => $username, ':email' => $email]);Для числовых значений — приводите тип вручную (intval) перед вставкой. Никогда не вставляйте часть SQL (имена колонок, LIMIT) от пользователя без жёсткой белого списка.Ограничьте учётную запись БД по привилегиям (только нужные права: SELECT/INSERT/UPDATE/DELETE на нужной схеме).Обработку ошибок: не выдавайте подробные SQL-ошибки пользователю; логируйте внутренне.Используйте ORM или query builder (Eloquent, Doctrine) как дополнительный уровень защиты.

B. Криптография — не использовать XOR, использовать проверенные примитивы

Не писать собственные алгоритмы шифрования. Используйте libsodium (sodium_* в PHP 7.2+) или OpenSSL AEAD (AES-GCM, ChaCha20-Poly1305).Пример правильного шифрования с libsodium (XChaCha20-Poly1305, AEAD):
Генерация ключа: $key = random_bytes(SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_KEYBYTES); (хранить 32 байта безопасно)Шифрование:
$nonce = random_bytes(SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES); // 24 байта
$cipher = sodium_crypto_aead_xchacha20poly1305_ietf_encrypt($plaintext, $associated_data, $nonce, $key);
// Сохраняйте nonce + cipher (и associated_data если используете)Расшифровка:
$plaintext = sodium_crypto_aead_xchacha20poly1305_ietf_decrypt($cipher, $associated_data, $nonce, $key);Если используете OpenSSL AES-GCM:
Используйте AES-256-GCM, сохраняйте IV (nonce) и auth tag; проверяйте tag при расшифровке.Всегда использовать authenticated encryption (AEAD), чтобы обеспечить и конфиденциальность, и целостность.Per-message nonce/IV: генерируйте случайный nonce для каждого сообщения, никогда не повторяйте nonce с тем же ключом.Ключи:
Генерация — random_bytes, не хардкодить в исходнике.Хранение — безопасно (KMS, HSM, vault). Ротация ключей, поддержка нескольких ключей (key-id в метаданных).Минимизируйте время жизни ключей.Пароли: не храните пароли через шифрование; используйте password_hash (bcrypt/Argon2id) и password_verify.
Пример: $hash = password_hash($password, PASSWORD_ARGON2ID);

C. Если нужно хранить зашифрованные данные в базе

Храните: ciphertext, nonce, auth_tag (если используется AES-GCM), key_id или metadata.Для поиска по зашифрованным полям: используйте хэши/HMAC (с отдельным ключом) или специализированные схемы (deterministic encryption только если осознаёте риски).Не храните секретные ключи рядом с базой данных в открытом виде.

D. Аутентификация, транспорт и логирование

Обязательно HTTPS/TLS для передачи данных.Логи не должны содержать секретных значений (пароли, ключи, raw ciphertext если не нужно).Мониторинг и алерты на всплески неудачных запросов/ошибок (может указать на попытки SQLi).

E. Дополнительные меры

WAF как дополнительный уровень защиты (не замена подготовленных запросов).Ограничение размера и типа входных данных (валидируйте по белому списку).Контроль доступа: RBAC, минимальные права.Подписывайте или проверяйте целостность данных, отправляемых клиенту (JWT с подписью, MAC).

4) Примеры безопасного кода (минимально)

Безопасный запрос с PDO:
$pdo = new PDO($dsn, $dbUser, $dbPass, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
$stmt = $pdo->prepare('SELECT id, password_hash FROM users WHERE username = :username');
$stmt->execute([':username' => $username]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);

Шифрование с sodium:
// генерация ключа (сделать один раз и хранить безопасно)
$key = random_bytes(SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_KEYBYTES);
// шифрование
$nonce = random_bytes(SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES);
$cipher = sodium_crypto_aead_xchacha20poly1305_ietf_encrypt($plaintext, $aad = '', $nonce, $key);
// сохранить base64_encode($nonce) и base64_encode($cipher) в БД
// расшифровка
$plaintext = sodium_crypto_aead_xchacha20poly1305_ietf_decrypt($cipher, $aad, $nonce, $key);

5) Контрольный список для исправления существующей реализации (приоритеты)

Срочно:
Убрать все места, где строится SQL через конкатенацию — заменить на подготовленные запросы.Отключить отображение подробных SQL-ошибок пользователю.Ограничить права БД-аккаунта.Короткий срок:
Заменить XOR-шифрование на libsodium AEAD (или AES-GCM/ChaCha20-Poly1305).Обеспечить уникальный nonce на запись и хранить его вместе с ciphertext.Использовать password_hash для паролей.Среднесрочно:
Реализовать хранение ключей в безопасном хранилище (Vault / KMS).Внедрить аудит логов, тесты на SQLi (fuzzing), code review.Ввести ротацию ключей и процесс восстановления.

6) Заключение

SQL-инъекции и собственные криптоалгоритмы — сочетание крайне опасное. Даже если XOR «практически скрывает» данные — это не криптографически безопасно и легко ломается/подделывается.Управление безопасностью: не изобретайте криптографию заново; используйте стандартные библиотеки и практики. Параметризованные запросы + AEAD = существенный шаг к восстановлению безопасности.

Если хотите, пришлите конкретный фрагмент вашего PHP-кода (SQL-формирование и функция XOR), и я:

укажу точные места эксплойта;предложу конкретную правку кода (готовый исправленный фрагмент с PDO + libsodium или openssl) под вашу задачу.
26 Сен в 21:01
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир