Код-ревью Middle SSRF, файлы и редиректы обновлено

Ревью: редирект после входа на Go

Вопрос

Найдите проблемы в обработчике входа.

func login(w http.ResponseWriter, r *http.Request) {
	next := r.URL.Query().Get("next")
	if !checkPassword(r.FormValue("login"), r.FormValue("password")) {
		http.Error(w, "wrong password for "+r.FormValue("login"), 401)
		return
	}
	setSession(w, r.FormValue("login"))
	if strings.HasPrefix(next, "/") {
		http.Redirect(w, r, next, http.StatusFound)
		return
	}
	http.Redirect(w, r, "/", http.StatusFound)
}

Коротко

Проверка HasPrefix("/") классическая ошибка: протокол-относительные URL начинаются с той же косой черты. Плюс типичные проблемы входа: перебор и фиксация сессии.

Что должен найти ревьюер

  1. Безопасностьстрока 8
    Открытый редирект: //evil.ru и /\evil.ru начинаются с /, но ведут на чужой хост. Нужно запретить второй символ / и \ или использовать список разрешённых путей.
  2. Безопасностьстрока 4
    Логин отражается в ответе без экранирования: http.Error отдаёт text/plain, но такой паттерн легко превращается в XSS при смене типа, и сообщение подтверждает существование логина.
  3. Безопасностьстрока 7
    Нет перевыпуска идентификатора сессии и защиты от перебора паролей (лимиты, задержки).

Разбор

Проверка HasPrefix("/") классическая ошибка: протокол-относительные URL начинаются с той же косой черты. Плюс типичные проблемы входа: перебор и фиксация сессии.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.