Powrót do strony głównej

Bezpieczny file upload w Go: 7 ataków

Artykuł opisuje ochronę file upload w Go przed 7 atakami: podmiana typu magic bytes, DoS przez MaxBytesReader+sloty, path traversal stałymi ścieżkami. Użyta ECDSA-identyfikacja urządzeń bez kont dla rozszerzenia przeglądarki.

7 ataków na file upload w Go i ich ochrona
Advertisement 728x90

Ochrona przesyłania plików w Go: ochrona przed 7 typowymi atakami

W systemach bez tradycyjnego uwierzytelniania, przesyłanie plików wymaga niezawodnej identyfikacji źródła żądań. Dla rozszerzenia przeglądarkowego PDF-to-Markdown zaimplementowano model oparty na ECDSA P-256 przez WebCrypto API. Podczas pierwszego uruchomienia generowana jest nieeksportowalna para kluczy:

const keyPair = await crypto.subtle.generateKey(
  { name: 'ECDSA', namedCurve: 'P-256' },
  false,  // extractable = false
  ['sign', 'verify']
);

Klucz publiczny rejestrowany jest na serwerze, a użytkownik otrzymuje device_id i device_token. Każde żądanie API zawiera:

  • Authorization: Bearer <token>
  • X-Timestamp (±5 minut)
  • X-Nonce (przeciwdziałanie replay)
  • X-Body-SHA256
  • X-Signature (podpis ECDSA nad METHOD+PATH+TIMESTAMP+NONCE+BODY_HASH)

Serwer weryfikuje podpis za pomocą klucza publicznego. Zapewnia to:

Google AdInline article slot
  • Limitowanie szybkości na urządzenie
  • Ochronę przed atakami replay
  • Kontrolę slotów (maks. 3 aktywne zadania)
  • Ograniczenie rejestracji (5/IP/godzina)

Model zwiększa koszt ataku: emulacja wymaga pełnej implementacji podpisów ECDSA.

Atak 1: Fałszowanie typu pliku

Atakujący maskuje plik wykonywalny jako PDF. Ochrona działa na trzech poziomach.

Frontend: Sprawdzenie MIME i rozszerzenia:

Google AdInline article slot
const ALLOWED_TYPES = ['application/pdf'];
const ALLOWED_EXTENSIONS = ['.pdf'];

function validateFile(file) {
  const isPdf = ALLOWED_TYPES.includes(file.type) ||
                ALLOWED_EXTENSIONS.some(ext =>
                  file.name.toLowerCase().endsWith(ext));
  if (!isPdf) return { valid: false, error: 'Tylko PDF' };
}

Backend: Routing na podstawie Content-Type. Kluczowe: Magic bytes:

pdfMagicBytes := "%PDF"
header4 := make([]byte, 4)
_, err := file.Read(header4)
if string(header4) != pdfMagicBytes {
    respondError(w, http.StatusBadRequest,
        models.ErrCodeValidationError,
        "Plik nie jest poprawnym PDFem")
}
file.Seek(0, 0)

Sprawdzenie pierwszych bajtów ignoruje nagłówki i rozszerzenia. Pliki poliglotyczne (poprawne PDF + szkodliwe) wymagają dodatkowych sygnatur.

Atak 2: Przepięcie dysku

DoS przez duże pliki. Ograniczenia:

Google AdInline article slot
  • http.MaxBytesReader(w, r.Body, MaxFileSize + 1MB) — przerwanie odczytu przy limicie.
  • Sloty na urządzenie: maks. 3 aktywne zadania (queued, processing, ready, error).
  • Limity szybkości dla rejestracji i żądań.

Identyfikacja urządzenia sprawia, że zmiana IP/tokena jest bezcelowa.

Atak 3: Przejście przez ścieżkę (Path Traversal)

Atakujący używa ../../../etc/passwd. Rozwiązanie: Stała nazwa {UUID}/input.pdf. Wprowadzane dane użytkownika w ścieżce są całkowicie ignorowane.

Sanitizacja frontendu (dodatkowo):

function sanitizeFileName(name) {
  return name
    .replace(/[/\\?%*:|"<>]/g, '-') 
    .replace(/^\.+/, '')
    .replace(/\.+$, '')
    .substring(0, 255)
    .trim();
}

Backend generuje ścieżkę niezależnie od nazwy pliku.

Atak 4: SSRF przez pobieranie z URL

Dla kanału "pobieranie z URL" blokowane są:

  • Rozwiązywanie DNS przed pobraniem
  • Przekierowania
  • Prywatne adresy IP (denylist: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16)

Atak 5: Ataki replay

X-Nonce + X-Timestamp + podpis. Nonce przechowywane per urządzenie, timestamp w oknie ±5 minut.

Atak 6: Fałszerstwo urządzenia

extractable: false sprawia, że klucz prywatny nie może zostać wyeksportowany. Zabranie device_token jest bezużyteczne bez podpisu.

Atak 7: Nadużycie na poziomie aplikacji

Limity szybkości + sloty + podpis. Maks. 3 sloty, 5 rejestracji/IP/godzina.

Co ważne

  • Kryptograficzna identyfikacja per urządzenie zastępuje konta dla limitów.
  • Magic bytes (%PDF) to jedyna wiarygodna weryfikacja typu pliku.
  • MaxBytesReader + sloty chronią przed DoS.
  • Stałe ścieżki eliminują przejścia.
  • ECDSA P-256 + nonce/timestamp blokują replay i fałszerstwo.

— Editorial Team

Advertisement 728x90

Czytaj dalej