Безопасность: код установки ретранслятора (M1), zip-slip 7z (M3), L1/L5/L2

Продолжение исправлений по security-аудиту.

M1 (MEDIUM) — установщик PHP-ретранслятора был открыт без входа: до создания
админа атакующий из интернета мог завести админа кабинета или подменить адрес
ядра/ключ. Добавлен «код установки»: генерируется в файл install.lock рядом с
данными (вне веб-корня), прочитать его можно только с доступом к файловой
системе (FTP/файловый менеджер) — то есть владельцу сервера. Шаги connect и
admin (включая «пропустить») требуют верный код. Регексп loopback заякорен
(`http://127.0.0.1.attacker.com` больше не проходит как loopback). Код удаляется
по завершении установки. Проверено встроенным php-сервером.

M3 (MEDIUM) — распаковка 7z в мастере ключа (ExtractISO) сохраняла пути из
архива → запись «../…» вышла бы за каталог. Перед распаковкой архив
просматривается (7z l -slt, без записи); при абсолютном пути или выходе за
корень распаковка отклоняется. Тест TestUnsafeArchivePath.

L1 — target_device не проверялся перед root mount: значение не из списка
съёмных теперь отклоняется (иначе root смонтировал бы произвольный девайс).
L5 — likeEscape в ручном поиске DEPO (manualDepoSearch): метасимволы LIKE от
пользователя больше не «расползаются» по базе.
L2a — кука сессии ядра получает Secure и за TLS-терминирующим прокси на loopback
(reqIsHTTPS учитывает X-Forwarded-Proto только от loopback).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q4YVo4UMopqT5DzicqpPjL
This commit is contained in:
zuevav
2026-09-18 21:35:38 +03:00
parent d975957335
commit e16d4454ce
6 changed files with 159 additions and 5 deletions
+3 -1
View File
@@ -71,7 +71,9 @@ func manualDepoSearch(rc *RuntimeConfig, q string) ([]manualDepoFace, string) {
defer db.Close()
digits := strings.ReplaceAll(q, " ", "")
// Действующая версия карточки (LAST_FLAG=1); счета привязаны к исходной записи (SELF_ID).
rows, err := db.QueryContext(ctx, fsql.Man01, sql.Named("q", q+"%"), sql.Named("d", digits))
// likeEscape: метасимволы LIKE (% _ [) в имени от пользователя означают сами себя,
// иначе поиск «расползается» по всей базе (wildcard-injection).
rows, err := db.QueryContext(ctx, fsql.Man01, sql.Named("q", likeEscape(q)+"%"), sql.Named("d", digits))
if err != nil {
return nil, "поиск в DEPO: " + err.Error()
}