Автор статьи: Якушков Федор

Куки (HTTP Cookies) используются для хранения данных на стороне клиента, например, для аутентификации, управления сессиями или персонализации контента. В языке Go работа с куками реализована через стандартную библиотеку net/http, что делает их использование простым и удобным. В этой статье мы разберем основные операции с куками в Go, а также рассмотрим аспекты их безопасности.
Основные операции с куками в Go
Установка кук
Чтобы установить куку в ответе сервера, нужно использовать заголовок Set-Cookie. В Go для этого используется http.SetCookie():
package main import ( "net/http" ) func setCookieHandler(w http.ResponseWriter, r *http.Request) { cookie := &http.Cookie{ Name: "session_id", Value: "123456", Path: "/", HttpOnly: true, // Доступ только через HTTP, защита от XSS Secure: true, // Только HTTPS SameSite: http.SameSiteStrictMode, // Защита от CSRF } http.SetCookie(w, cookie) w.Write([]byte("Cookie set!")) } func main() { http.HandleFunc("/set-cookie", setCookieHandler) http.ListenAndServe(":8080", nil) }
Этот обработчик устанавливает куку session_id с безопасными параметрами:
HttpOnly: true — запретит доступ к куке из JavaScript (защита от XSS-атак).
Secure: true — кука будет передаваться только по HTTPS.
SameSite: Strict — защита от CSRF-атак.
Чтение кук
Куки передаются в заголовке Cookie и доступны в http.Request через метод r.Cookie():
func getCookieHandler(w http.ResponseWriter, r *http.Request) { cookie, err := r.Cookie("session_id") if err != nil { http.Error(w, "Cookie not found", http.StatusNotFound) return } w.Write([]byte("Cookie value: " + cookie.Value)) } func main() { http.HandleFunc("/get-cookie", getCookieHandler) http.ListenAndServe(":8080", nil) }
Удаление кук
Чтобы удалить куку, нужно установить ее с истекшим сроком:
func deleteCookieHandler(w http.ResponseWriter, r *http.Request) { cookie := &http.Cookie{ Name: "session_id", Value: "", Path: "/", MaxAge: -1, // Удаление куки } http.SetCookie(w, cookie) w.Write([]byte("Cookie deleted!")) }
Безопасность кук
HttpOnly и Secure
Использование HttpOnly и Secure предотвращает кражу кук через JavaScript (document.cookie) и защищает их от передачи через HTTP.
SameSite и CSRF
Атрибут SameSite в куках позволяет ограничить отправку кук в межсайтовых запросах, что помогает снизить риск CSRF-атак. Однако, важно понимать, что SameSite не является полной защитой от CSRF и должен использоваться в сочетании с CSRF-токенами.
SameSite=Lax: Куки отправляются при переходах по безопасным HTTP-методам (GET) и в некоторых других случаях, например, при загрузке изображений.
SameSite=Strict: Куки отправляются только при запросах, инициированных с того же домена. Этот режим обеспечивает наиболее сильную защиту от CSRF, но может нарушить удобство использования в некоторых сценариях.
SameSite=None: Куки отправляются всегда, независимо от того, откуда был инициирован запрос. Этот режим требует обязательного использования атрибута Secure=true, так как куки передаются только по HTTPS.
Для надежной защиты от CSRF необходимо использовать CSRF-токены. Это случайные значения, которые сервер генерирует и отправляет клиенту. При каждом запросе, изменяющем состояние сервера, клиент должен отправлять этот токен. Сервер проверяет соответствие токена, чтобы убедиться, что запрос был сделан намеренно.
Подпись и шифрование кук
Для защиты содержимого кук можно использовать gorilla/securecookie:
import ( "encoding/gob" "github.com/gorilla/securecookie" ) var hashKey = []byte("super-secret-key") var s = securecookie.New(hashKey, nil) type SessionData struct { Username string } gob.Register(SessionData{}) func setSignedCookie(w http.ResponseWriter) { value := SessionData{Username: "user123"} encoded, _ := s.Encode("session", value) cookie := &http.Cookie{Name: "session", Value: encoded, Path: "/", HttpOnly: true} http.SetCookie(w, cookie) }
Заключение
Работа с куками в Go требует внимательного отношения к безопасности. Использование атрибутов HttpOnly, Secure и SameSite помогает снизить риск атак, таких как XSS и CSRF. Однако, важно понимать, что SameSite не является полной защитой от CSRF и должен использоваться в сочетании с CSRF-токенами. Для защиты конфиденциальных данных в куках рекомендуется использовать подпись и шифрование.
В зависимости от требований к безопасности и масштабируемости приложения, следует рассмотреть альтернативные методы аутентификации, такие как авторизация через JWT токены или серверные сессии. JWT обеспечивает stateless-аутентификацию и хорошо подходит для микросервисных архитектур, а серверные сессии могут быть предпочтительнее для приложений, требующих более сложного управления состоянием сессии.
Код можно протестировать, запустив сервер на http://localhost:8080 и проверяя установку, получение и удаление кук.
