Цей документ описує аспекти безпеки системи замовлення кави та рекомендації щодо її захисту.
На даний момент система замовлення кави має наступні обмеження з точки зору безпеки:
- Відсутність автентифікації: API не вимагає автентифікації, що означає, що будь-хто може розміщувати замовлення.
- Відсутність авторизації: Немає механізму контролю доступу для обмеження того, хто може розміщувати замовлення.
- Відсутність шифрування: Комунікація між клієнтом і сервером, а також між сервером і Kafka не шифрується.
- Відсутність валідації вхідних даних: Хоча система перевіряє, чи є вхідні дані дійсним JSON, вона не виконує детальну валідацію полів.
-
Додати автентифікацію:
- Реалізувати автентифікацію на основі JWT (JSON Web Tokens)
- Додати ендпоінт для входу в систему, який видає JWT
- Вимагати JWT для всіх API-запитів
// Приклад middleware для перевірки JWT func JWTMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { tokenString := r.Header.Get("Authorization") if tokenString == "" { http.Error(w, "Unauthorized", http.StatusUnauthorized) return } // Перевірити JWT // ... next.ServeHTTP(w, r) }) }
-
Додати авторизацію:
- Визначити ролі (наприклад, "customer", "barista", "admin")
- Реалізувати перевірку ролей для різних ендпоінтів
// Приклад middleware для перевірки ролей func RoleMiddleware(role string) func(http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Отримати роль з JWT userRole := getUserRoleFromJWT(r) if userRole != role { http.Error(w, "Forbidden", http.StatusForbidden) return } next.ServeHTTP(w, r) }) } }
-
Додати HTTPS:
- Налаштувати TLS для HTTP-сервера
- Отримати сертифікат від надійного центру сертифікації або використовувати Let's Encrypt
// Приклад налаштування HTTPS func main() { // ... serverAddr := ":" + strconv.Itoa(cfg.Server.Port) fmt.Printf("Starting server on %s\n", serverAddr) log.Fatal(http.ListenAndServeTLS(serverAddr, "cert.pem", "key.pem", handler)) }
-
Налаштувати шифрування для Kafka:
- Налаштувати SSL/TLS для з'єднання з Kafka
- Налаштувати SASL для автентифікації в Kafka
// Приклад налаштування SSL для Kafka func NewProducer(config *config.Config) (Producer, error) { saramaConfig := sarama.NewConfig() // ... // Налаштувати SSL saramaConfig.Net.TLS.Enable = true saramaConfig.Net.TLS.Config = &tls.Config{ // ... } // ... }
-
Додати детальну валідацію:
- Перевіряти довжину полів
- Перевіряти формат полів
- Перевіряти допустимі значення
// Приклад валідації func (h *Handler) PlaceOrder(w http.ResponseWriter, r *http.Request) { // ... // Валідація if len(order.CustomerName) == 0 || len(order.CustomerName) > 100 { http.Error(w, "Invalid customer name", http.StatusBadRequest) return } if len(order.CoffeeType) == 0 || len(order.CoffeeType) > 50 { http.Error(w, "Invalid coffee type", http.StatusBadRequest) return } // ... }
-
Використовувати бібліотеку для валідації:
- Використовувати бібліотеку, таку як
go-playground/validator, для валідації структур
// Приклад використання validator type Order struct { CustomerName string `json:"customer_name" validate:"required,max=100"` CoffeeType string `json:"coffee_type" validate:"required,max=50"` } func (h *Handler) PlaceOrder(w http.ResponseWriter, r *http.Request) { // ... // Валідація validate := validator.New() if err := validate.Struct(order); err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } // ... }
- Використовувати бібліотеку, таку як
-
Обмеження швидкості:
- Реалізувати обмеження швидкості для запобігання DoS-атакам
// Приклад middleware для обмеження швидкості func RateLimitMiddleware(next http.Handler) http.Handler { limiter := rate.NewLimiter(rate.Limit(10), 30) // 10 запитів в секунду, бакет на 30 запитів return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if !limiter.Allow() { http.Error(w, "Too Many Requests", http.StatusTooManyRequests) return } next.ServeHTTP(w, r) }) }
-
Логування безпеки:
- Логувати всі спроби автентифікації та авторизації
- Логувати всі підозрілі дії
// Приклад логування безпеки func JWTMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { tokenString := r.Header.Get("Authorization") if tokenString == "" { log.Printf("Security: Unauthorized access attempt from %s", r.RemoteAddr) http.Error(w, "Unauthorized", http.StatusUnauthorized) return } // ... }) }
-
Сканування вразливостей:
- Регулярно сканувати код на наявність вразливостей
- Використовувати інструменти, такі як
gosec
# Приклад використання gosec gosec ./...
-
Короткострокові дії:
- Додати валідацію вхідних даних
- Налаштувати HTTPS
- Додати обмеження швидкості
-
Середньострокові дії:
- Реалізувати автентифікацію на основі JWT
- Налаштувати шифрування для Kafka
-
Довгострокові дії:
- Реалізувати авторизацію на основі ролей
- Впровадити регулярне сканування вразливостей
- Розробити політику безпеки
Хоча поточна система замовлення кави має обмеження з точки зору безпеки, впровадження рекомендацій, описаних у цьому документі, значно покращить її безпеку. Важливо розглядати безпеку як постійний процес, а не одноразове завдання.