Безопасность: код установки ретранслятора (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:
@@ -306,12 +306,19 @@ func (h *setupHandlers) keyWizardInstall(w http.ResponseWriter, r *http.Request)
|
||||
targetDev := strings.TrimSpace(r.FormValue("target_device"))
|
||||
targetMnt := ""
|
||||
if targetDev != "" {
|
||||
found := false
|
||||
for _, d := range listFlashDrives() {
|
||||
if d.Device == targetDev {
|
||||
targetMnt = d.Mountpoint
|
||||
targetMnt, found = d.Mountpoint, true
|
||||
break
|
||||
}
|
||||
}
|
||||
// Устройство должно быть из списка обнаруженных съёмных: иначе root-воркер
|
||||
// смонтировал бы произвольный блочный девайс/путь, переданный из формы.
|
||||
if !found {
|
||||
h.keyWizFlash(w, r, "Выбранное устройство не найдено среди съёмных носителей — обновите список и повторите.")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(r.Context(), 3*time.Minute)
|
||||
|
||||
Reference in New Issue
Block a user