Go: Безопасность

8 вопросов

1 OWASP Top 10 и актуальность для Go.

OWASP Top 10 - основные риски веб-приложений: инъекции, сломанная аутентификация, чувствительные данные, XXE, сломанный контроль доступа, неверная конфигурация, XSS, небезопасная десериализация, уязвимые компоненты, недостаточное логирование. В Go: защита от SQL-инъекций (prepared statements), валидация ввода, HTTPS, хранение секретов вне кода, безопасные заголовки, санитизация вывода.

Открыть отдельно →
2 Защита от SQL-инъекций в Go.

Никогда не подставлять пользовательский ввод в строку запроса. Использовать плейсхолдеры: db.QueryContext(ctx, "SELECT * FROM users WHERE id = $1", id). Параметры передавать как аргументы Exec/Query; драйвер экранирует. Проверять и валидировать типы (например, id - целое). ORM и query builder с параметризацией тоже защищают при правильном использовании.

// плохо: "SELECT * FROM users WHERE id = " + id
// хорошо:
db.QueryRowContext(ctx, "SELECT * FROM users WHERE id = $1", id)
Открыть отдельно →
3 XSS в Go. Предотвращение при выводе в шаблонах.

XSS - внедрение скриптов через контент страницы. В Go при выводе в HTML экранировать данные: template пакет по умолчанию экранирует {{ }}; при ручной сборке HTML использовать html.EscapeString. Не выводить непроверенный пользовательский ввод без экранирования. Content-Type и заголовки (X-Content-Type-Options, CSP) снижают риски.

import "html"
safe := html.EscapeString(userInput)
// в шаблоне: {{ . }} уже экранируется
Открыть отдельно →
4 CSRF в Go. Токены и SameSite.

CSRF - запрос с другого сайта с cookie пользователя. Защита: CSRF-токен в форме и проверка на сервере; SameSite cookie (Strict/Lax) ограничивает отправку cookie при cross-site запросах. В Go генерируют токен при отдаче формы, сохраняют в сессии, при POST проверяют. Для API - не полагаться на cookie; использовать Bearer token или проверять Origin/Referer.

cookie := &http.Cookie{
    Name:     "session",
    Value:    token,
    SameSite: http.SameSiteLaxMode,
    Secure:   true,
}
http.SetCookie(w, cookie)
Открыть отдельно →
5 Хеширование паролей в Go. bcrypt, scrypt.

Пароли не хранить в открытом виде; только хеш с солью. В Go: golang.org/x/crypto/bcrypt (GenerateFromPassword, CompareHashAndPassword). Cost задает сложность (10-12 типично). scrypt - альтернатива (более устойчив к ASIC). Не использовать обычный SHA без соли; не использовать MD5. При аутентификации сравнивать хеш с введенным паролем через Compare.

hash, _ := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
err := bcrypt.CompareHashAndPassword(storedHash, []byte(password))
Открыть отдельно →
6 RBAC в Go. Реализация проверки ролей.

RBAC - доступ по ролям и разрешениям (роль имеет набор прав). В Go: middleware извлекает пользователя из контекста (после auth), проверяет роль/право для ресурса; при отсутствии права возвращает 403. Хранение: таблица ролей, связь пользователь-роли, роль-разрешения; или кеш в памяти. Проверка: hasRole(user, "admin") или hasPermission(user, "order:write").

func requireRole(role string) func(http.Handler) http.Handler {
    return func(next http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            if getUser(r).Role != role { http.Error(w, "Forbidden", 403); return }
            next.ServeHTTP(w, r)
        })
    }
}
Открыть отдельно →
7 Безопасность API в Go. Аутентификация и авторизация.

Аутентификация: JWT в заголовке Authorization, или API key, или OAuth2. Проверка в middleware; контекст с user ID/ролями. Авторизация: проверка прав на ресурс (владелец или роль). HTTPS обязательно; rate limiting от злоупотреблений. Не логировать токены и пароли. В Go: извлечь токен, проверить подпись и exp, положить claims в context. Для каждого эндпоинта проверять право доступа.

func authMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        token := extractBearer(r)
        claims, err := validateToken(token)
        if err != nil { http.Error(w, "Unauthorized", 401); return }
        next.ServeHTTP(w, r.WithContext(context.WithValue(r.Context(), "user", claims)))
    })
}
Открыть отдельно →
8 Управление секретами в Go-приложении.

Секреты не в коде и не в репозитории. В проде: переменные окружения (env), файлы (смонтированные в K8s из Secret), внешние хранилища (HashiCorp Vault, AWS Secrets Manager). В Go читать из os.Getenv или из файла при старте; не логировать. В разработке - .env (в gitignore) или default-значения. Ротация секретов без перезапуска - через периодическое чтение или callback при изменении.

secret := os.Getenv("DB_PASSWORD")
if secret == "" { log.Fatal("DB_PASSWORD required") }
Открыть отдельно →
🧠Квиз 🏆Лидеры 🎯Собесед. 📖Вопросы 📚База зн.