Najczęstsze błędy w konfiguracji S3/Azure Blob: publiczne dane, tokeny i logowanie dostępu

Przegląd 7 najczęstszych błędów w S3 i Azure Blob: publiczne buckety, ACL vs RBAC, złe SAS/tokeny, rotacja kluczy, logi, ochrona przed ransomware i CORS.
07 kwietnia 2026
blog

1. Wprowadzenie: dlaczego konfiguracja S3 i Azure Blob najczęściej „psuje” bezpieczeństwo

Object storage (Amazon S3 i Azure Blob Storage) jest fundamentem wielu aplikacji: od statycznych plików WWW i multimediów, przez backupy, po zbiory danych dla analityki i AI. Jednocześnie to jedna z tych usług chmurowych, w których pojedyncza decyzja konfiguracyjna potrafi niepostrzeżenie zamienić prywatny zasób w publicznie dostępny lub „pół-publiczny” (dostępny dla szerokiej grupy tożsamości, usług albo sieci). W efekcie wyciek danych w object storage zwykle nie wynika z „hakerskiego włamania”, tylko z błędnego dopasowania mechanizmów dostępu do realnych potrzeb.

Problem jest szczególnie częsty, bo S3 i Azure Blob są zaprojektowane tak, aby były elastyczne i łatwe do integracji. Ta elastyczność oznacza wiele równoległych sposobów kontroli dostępu (różne warstwy uprawnień, różne typy tożsamości i różne modele udostępniania), które mogą się nakładać. Jeśli zespół nie ma spójnej strategii, to nawet dobrze wyglądające ustawienia w jednym miejscu mogą zostać „przebite” w innym — albo spowodować niezamierzone obchodzenie polityk przez obejścia używane w pośpiechu.

W praktyce bezpieczeństwo „psuje się” najczęściej w trzech sytuacjach:

  • Gdy storage jest traktowany jak prosty hosting plików — a potrzeby biznesowe (np. publiczne zasoby dla strony) mieszają się z danymi wewnętrznymi w tych samych kontach, kontenerach lub bucketach.
  • Gdy mechanizmy dostępu są źle rozumiane lub mylone — zwłaszcza różnica między ustawieniami „na obiekcie” a politykami na poziomie zasobu/tożsamości oraz to, co faktycznie decyduje o tym, kto ma dostęp.
  • Gdy udostępnianie realizuje się skrótami — poprzez linki z podpisem lub tokeny, które łatwo skopiować, wysłać dalej, wkleić w ticketa lub przypadkiem zapisać w logach.

Warto też pamiętać o podstawowych różnicach podejścia w obu chmurach. Amazon S3 jest zorientowany na polityki i uprawnienia przypięte do tożsamości oraz zasobów (z dodatkowymi historycznymi mechanizmami na poziomie obiektów), podczas gdy Azure Blob Storage mocno integruje się z modelem tożsamości w Microsoft Entra ID oraz warstwą uprawnień i ustawień na poziomie konta storage. W obu przypadkach łatwo przeoczyć, że na końcowy efekt składa się więcej niż jeden „przełącznik” — a konfiguracja bezpieczeństwa to suma decyzji: kto, skąd, jakim mechanizmem i na jak długo uzyskuje dostęp.

Konfiguracja object storage bywa też „krucha” operacyjnie: zmiany są często wprowadzane pod presją czasu, a zasoby żyją latami i przechodzą między projektami. To sprawia, że ryzyko nie wynika wyłącznie z błędów początkowych, ale także z dryfu konfiguracji, dziedziczenia ustawień, niejednolitego stosowania standardów oraz braku pełnej obserwowalności tego, kto i kiedy pobiera dane.

Najczęstsze kategorie potknięć w S3 i Azure Blob dotyczą: niezamierzonej publiczności danych, niewłaściwego modelu uprawnień, niebezpiecznego udostępniania przez tokeny/URL-e, słabego zarządzania sekretami oraz niewystarczającego logowania i monitoringu. Dodatkowym elementem jest odporność na incydenty takie jak ransomware — bo nawet jeśli dostęp jest poprawnie ograniczony, brak mechanizmów odzysku i niezmienności danych potrafi zamienić błąd operacyjny w katastrofę.

Błąd 1: niezamierzony publiczny dostęp do bucketów/kontenerów (Block Public Access, Public Access Level)

Najczęstszy i zarazem najbardziej kosztowny błąd w storage’ach obiektowych to sytuacja, w której dane stają się dostępne publicznie „przy okazji”: przez pojedyncze ustawienie w konsoli, odziedziczoną konfigurację, automatyczny deployment albo domyślne opcje narzędzia. Problem jest podstępny, bo publiczność nie zawsze oznacza widoczność w przeglądarce — często chodzi o możliwość pobrania obiektu przez każdego, kto zna adres URL lub potrafi go odgadnąć. Podczas szkoleń Cognity ten temat wraca regularnie – dlatego zdecydowaliśmy się go omówić również tutaj.

W praktyce do wycieku dochodzi najczęściej na dwa sposoby: (1) cały bucket/kontener zostaje wystawiony na odczyt listy i/lub obiektów, albo (2) tylko wybrany prefiks lub pojedyncze obiekty stają się publiczne, a zespół traci nad tym kontrolę wraz z rozrostem danych. Z perspektywy atakującego oba scenariusze są atrakcyjne: pierwszy ułatwia masowe pobieranie, drugi bywa wystarczający, jeśli publiczne są pliki z danymi wrażliwymi, backupy, eksporty lub artefakty aplikacyjne.

AWS S3 kładzie nacisk na centralne „bezpieczniki” blokujące publiczność niezależnie od tego, co ustawiono niżej. Kluczową rolę pełni Block Public Access (na poziomie konta i bucketu), który ma zapobiegać temu, by ACL-e lub polityki mogły przypadkowo udostępnić zasoby wszystkim. Nawet jeśli ktoś spróbuje ustawić publiczny dostęp, właściwie skonfigurowany mechanizm blokady powinien to zneutralizować albo wymusić świadomą, audytowalną decyzję o jego wyłączeniu.

Azure Blob Storage operuje pojęciem publiczności bardziej „kontenerowo”: istotne jest ustawienie Public Access Level na kontenerze (brak publicznego dostępu, publiczny dostęp do blobów, lub – historycznie – także listowanie kontenera, zależnie od opcji i zasad w organizacji). Publiczność w Azure bywa też kontrolowana na poziomie konta poprzez polityki/ustawienia, które mogą całkowicie blokować możliwość nadawania publicznego dostępu kontenerom. W efekcie najczęstsza pomyłka to pozostawienie kontenera z publicznym poziomem dostępu po testach lub migracji, a następnie traktowanie go jak prywatnego repozytorium plików.

Typowe źródła niezamierzonej publiczności w obu chmurach:

  • „Szybkie” obejścia pod presją czasu — ktoś udostępnia bucket/kontener „na chwilę”, żeby pobrać pliki lub zweryfikować integrację, a potem nikt nie wraca do ustawień.
  • Nieintuicyjne dziedziczenie i rozproszone miejsca konfiguracji — część ustawień jest na poziomie konta, część na bucketu/kontenera, a część na obiektach; łatwo przeoczyć, że istnieje drugi przełącznik blokujący lub dopuszczający publiczność.
  • Środowiska testowe użyte produkcyjnie — kontenery/buckety tworzone dla developmentu z luźniejszymi zasadami zaczynają przechowywać realne dane.
  • Automatyzacja bez guardrail’i — szablony IaC lub pipeline’y powielają ustawienia z przykładu, a publiczny dostęp staje się „domyślny” dla nowych zasobów.
  • Mylenie publiczności z „dostępem z internetu” — zasób może być osiągalny sieciowo, ale nadal prywatny; odwrotnie, może być publiczny logicznie, nawet jeśli zespół zakładał, że kontrola sieciowa wszystko załatwia.

Skutki publicznego dostępu rzadko ograniczają się do samego wycieku danych. Pojawiają się ryzyka wtórne: łatwiejsze profilowanie infrastruktury (nazwy plików, struktura katalogów), ujawnienie artefaktów wdrożeniowych, konfiguracji, eksportów baz danych czy logów aplikacyjnych, a także ryzyko reputacyjne i regulacyjne. W dodatku wykrycie incydentu bywa opóźnione, bo publiczność może dotyczyć tylko fragmentu danych, a brak konsekwentnych blokad powoduje, że zmiana „gdzieś” omija lokalne kontrole.

Jak ograniczać ten błąd na poziomie podstawowej higieny konfiguracji:

  • Traktuj publiczny dostęp jako wyjątek i wymagaj świadomej decyzji: jeżeli coś ma być publiczne (np. statyczne zasoby strony), wydziel to do osobnego bucketu/kontenera i pilnuj minimalnego zakresu ekspozycji.
  • Włącz globalne blokady publiczności tam, gdzie to możliwe, i zdejmuj je tylko w kontrolowany sposób. W AWS rolę „bezpiecznika” pełni Block Public Access; w Azure warto stosować ustawienia/polityki ograniczające możliwość nadawania Public Access Level.
  • Rozdziel dane wrażliwe i niewrażliwe — osobne zasoby i osobne reguły; nie mieszaj backupów, eksportów i plików aplikacyjnych w jednym miejscu, które „czasem” bywa publiczne.
  • Weryfikuj publiczność cyklicznie — przeglądy konfiguracji zasobów storage powinny być stałym elementem utrzymania, bo ryzyko rośnie wraz z liczbą obiektów i zmian.
💡 Pro tip: Włącz globalne „bezpieczniki” przeciw publiczności (S3 Block Public Access / polityki blokujące Public Access Level w Azure) i traktuj publiczny dostęp jako wyjątek wymagający świadomego, audytowalnego wyłączenia. Jeśli coś ma być publiczne, wydziel to do osobnego bucketu/kontenera i cyklicznie skanuj konfiguracje pod kątem przypadkowych ekspozycji.

Błąd 2: mylenie ACL z policy/RBAC (S3 ACL vs Bucket Policy/IAM; Azure ACL vs RBAC/Access Policies)

Jednym z najczęstszych źródeł „cichych” luk w bezpieczeństwie storage’u jest założenie, że ACL i policy/RBAC to to samo. W praktyce są to różne mechanizmy, działające na innym poziomie (obiekt vs zasób) i często oceniane równolegle. Skutek? Dostęp bywa przyznany (lub odebrany) inaczej niż oczekiwano, a audyt staje się nieczytelny.

S3: ACL a Bucket Policy/IAM

W Amazon S3 spotkasz dwa główne style kontroli dostępu:

  • ACL (Access Control Lists) – historyczny, „lekki” mechanizm przypisywania uprawnień głównie na poziomie obiektu (i czasem bucketa), używany m.in. do kontroli właścicielstwa i prostego udostępniania.
  • Bucket Policy / IAM – mechanizmy „policy-as-code”, które opisują kto może wykonać jaką akcję na jakich zasobach, często z dodatkowymi warunkami (np. źródło żądania, wymagane szyfrowanie).

Typowe pomyłki polegają na tym, że zespół ustawia restrykcyjną Bucket Policy, ale zostawia ACL-e w stanie umożliwiającym niepożądane scenariusze (np. wynikające z dziedziczenia właścicielstwa lub specyfiki uploadu), albo odwrotnie — próbuje „zarządzać bezpieczeństwem” samymi ACL-ami, przez co reguły stają się rozproszone i trudne do przeglądu.

Azure Blob: ACL (ADLS) a RBAC / Access Policies

W Azure rozróżnienie jest równie ważne, ale dotyczy nieco innych warstw:

  • RBAC (Azure role-based access control) – przyznaje uprawnienia na poziomie subskrypcji, resource group, konta storage, kontenera (warstwa zarządzania i dane, zależnie od roli). To podstawowy sposób zarządzania dostępem dla tożsamości w Entra ID.
  • ACL-e (w kontekście Data Lake Storage Gen2) – bardziej „system plików”: uprawnienia na poziomie folderów i plików (POSIX-like), potrzebne gdy kontrolujesz dostęp wewnątrz hierarchii danych.
  • Access Policies (Stored Access Policy) – mechanizm wspierający zarządzanie parametrami dostępu dla tokenów (np. w obrębie kontenera), używany jako „kotwica” do centralniejszego odwoływania/ograniczania udostępnień.

Błąd pojawia się, gdy RBAC jest traktowany jako zamiennik ACL-i (albo odwrotnie). W efekcie ktoś ma rolę na poziomie konta, ale nie ma uprawnień do ścieżki w ADLS (albo ma dostęp do ścieżki przez ACL, mimo że RBAC miał to ograniczać w innym miejscu). Dodatkowo, mieszanie „data plane” i „management plane” w rozumieniu uprawnień potrafi prowadzić do nadawania zbyt szerokich ról „na wszelki wypadek”.

Szybkie porównanie: do czego co służy

PlatformaMechanizmNajczęstsze zastosowanieRyzyko przy myleniu
AWS S3ACLUprawnienia/ownership na obiekcie, proste udostępnianieRozproszone reguły, trudny audyt, nieoczekiwane efekty przy uploadach i właścicielstwie
AWS S3Bucket Policy / IAMCentralne zarządzanie dostępem i warunkamiPoczucie kontroli mimo „dziur” zostawionych w ACL lub błędnych założeń o ich roli
Azure BlobRBACNadawanie ról tożsamościom na zasobachNadmiarowe role, brak precyzji na poziomie ścieżek, błędne założenia co do działania na danych
Azure ADLS Gen2ACLPrecyzyjne prawa do folderów/plików w hierarchiiNieczytelna matryca uprawnień, konflikty z RBAC, przypadkowe „szerokie” dostępy w drzewie
Azure BlobAccess PoliciesUłatwienie kontroli i wycofywania udostępnień opartych o tokenyUtrata kontroli nad realnym zakresem dostępu, gdy tokeny żyją „poza” politykami

Jak rozpoznać, że to ten błąd

  • Uprawnienia „na papierze” wyglądają poprawnie, ale użytkownik/aplikacja nadal ma (albo nie ma) dostępu.
  • Dostęp jest przyznawany w kilku miejscach naraz, a nikt nie potrafi wskazać jednego źródła prawdy.
  • Audyt wymaga przeglądania wielu warstw: list ACL + policy + role, a wynik zależy od szczegółów ścieżki/obiektu.

Minimalna zasada porządku

ACL traktuj jako mechanizm specyficzny dla poziomu obiektu/ścieżki (i kompatybilności), a policy/RBAC jako centralny, główny model nadawania dostępu. Najgorsze konfiguracje powstają wtedy, gdy oba mechanizmy są używane równolegle bez jasnej reguły: który ma być nadrzędny i w jakim zakresie.

4. Błąd 3: błędnie skonfigurowane SAS/tokeny i URL-e z podpisem

Mechanizmy „tymczasowego dostępu” do obiektów w storage (S3 i Azure Blob) są wygodne, bo pozwalają udostępnić plik bez nadawania stałych uprawnień użytkownikowi czy aplikacji. Jednocześnie są też częstym źródłem wycieków, bo token lub podpisany URL staje się w praktyce hasłem: kto go ma, ten ma dostęp — często szerszy i dłuższy, niż zakładano.

Typowe formy:

  • AWS S3: pre-signed URL (podpisany URL do konkretnej operacji, np. GET/PUT).
  • Azure Blob: SAS (Shared Access Signature) w kilku wariantach (np. na obiekt, kontener lub konto), zwykle jako parametry zapytania w URL.
Obszar ryzyka S3 (pre-signed URL) Azure Blob (SAS)
Zakres (scope) Zwykle 1 obiekt + 1 operacja (GET/PUT), ale często generowany bez ograniczeń kontekstowych Może obejmować obiekt/kontener/konto; łatwo niechcący udzielić dostępu do wielu blobów
Czas życia Ustalany podczas generowania URL Ustalany w parametrach SAS; często spotykane zbyt długie okna ważności
Uprawnienia Wynikają z podpisanej operacji i parametrów żądania Jawnie deklarowane (np. odczyt/zapis/listowanie/usuwanie)
Forma „sekretu” Pełny URL (z parametrami podpisu) Najczęściej URL z parametrami SAS (query string)

Najczęstsze błędne założenia

  • „To tylko link” — w praktyce to pełnoprawny nośnik uprawnień. Jeśli link trafi do osób postronnych, dostęp jest realny.
  • „Wygasa, więc jest bezpieczny” — jeśli ważność ustawiono na godziny/dni/tygodnie, to okno ataku bywa większe niż przy klasycznych poświadczeniach.
  • „Dotyczy jednego pliku” — szczególnie w Azure SAS nietrudno omyłkowo dać uprawnienia na kontener lub nawet szerzej (np. listowanie), co zwiększa skutki wycieku.

Typowe błędy konfiguracji: zakres, czas, uprawnienia

  • Zbyt szeroki zakres: token/URL wygenerowany dla kontenera zamiast pojedynczego obiektu, lub dopuszczający enumerację (np. listowanie), co ułatwia masowe pobranie danych.
  • Zbyt długi czas ważności: linki „na wszelki wypadek” ważne wiele dni/tygodni; często pozostają w mailach, ticketach i repozytoriach znacznie dłużej niż potrzeba.
  • Nadmierne uprawnienia: dodanie zapisu/usuwania, gdy potrzebny jest tylko odczyt; w skrajnych przypadkach pozwala to na podmianę pliku (integrity) lub usunięcie danych (availability).
  • Brak ograniczeń kontekstowych: udostępnienie bez zawężenia do konkretnego zastosowania (np. jednorazowy upload) i bez jasnej ścieżki unieważnienia.

Wyciek w logach i telemetryce: najczęstsza przyczyna „niewidzialnych” incydentów

Podpisane URL-e i SAS-y najczęściej podróżują jako query string w adresie. To sprawia, że łatwo wyciekają do miejsc, które nie są traktowane jak magazyn sekretów:

  • Logi aplikacji (np. logowanie pełnego request URL przy błędach 4xx/5xx).
  • Logi reverse proxy / WAF / CDN (standardowe formaty logów często zapisują pełny URL z parametrami).
  • Narzędzia APM i trace (automatyczne zbieranie parametrów żądań HTTP).
  • Systemy ticketowe i komunikatory (wklejony link zostaje w historii).
  • Nagłówek Referer (gdy link jest użyty w przeglądarce i aplikacja odsyła do zasobów zewnętrznych, URL może „wypłynąć” jako referer).

Minimalna zasada operacyjna: traktuj podpisany URL/SAS jak sekret i projektuj procesy tak, jakby mógł zostać skopiowany do logów lub przechwycony przez osobę niepowołaną. Zespół trenerski Cognity zauważa, że właśnie ten aspekt sprawia uczestnikom najwięcej trudności — bo wiele narzędzi domyślnie zbiera i zapisuje URL-e, a „sekret” w query string potrafi przejść przez organizację niezauważony.

Dobre praktyki (wysoki poziom, bez wchodzenia w detale)

  • Najmniejszy możliwy zakres: preferuj dostęp do pojedynczego obiektu i tylko do potrzebnej operacji.
  • Krótki czas życia: dopasuj do realnego okna użycia (np. minuty, nie dni), a nie „na zapas”.
  • Minimalne uprawnienia: read-only, jeśli to możliwe; unikaj uprawnień destrukcyjnych w linkach dystrybuowanych szeroko.
  • Higiena logów: nie loguj pełnych URL-i z query string; maskuj/wycinaj parametry podpisu w logach i telemetryce.
  • Separacja kanałów: nie wysyłaj tokenów w miejscach, które trudno kontrolować (publiczne repo, komentarze w kodzie, ogólnodostępne wiki).
// Przykład: defensywne logowanie - bez query string
// Zamiast logować request.originalUrl / full URL
log.info({
  path: req.path,               // bez ?sig=... / ?X-Amz-Signature=...
  method: req.method,
  status: res.statusCode
});

Jeśli potrzebujesz udostępniać obiekty w sposób powtarzalny (np. stałe integracje systemów), podpisane URL-e i SAS-y nadal mogą być właściwym narzędziem, ale tylko wtedy, gdy są wydawane celowo, krótko i z minimalnym zakresem — oraz gdy organizacja ma świadomość, że najczęstszy „atak” to po prostu ich niekontrolowane rozpowszechnienie.

💡 Pro tip: Traktuj pre-signed URL/SAS jak sekret: dawaj minimalny zakres (najlepiej 1 obiekt i 1 operacja), minimalne uprawnienia i jak najkrótszy czas życia (minuty, nie dni). Wytnij/maskuj query string w logach i telemetryce, bo to najczęstsza droga „niewidzialnego” wycieku tokenów.

5. Błąd 4: brak rotacji kluczy i złe zarządzanie sekretami (Access Keys/Shared Key, Managed Identity, Key Vault/Secrets Manager)

W praktyce wiele wycieków danych ze storage’u nie zaczyna się od „hakowania” samej usługi, tylko od przejęcia długowiecznych sekretów: kluczy dostępowych, connection stringów czy tokenów zapisanych w kodzie, pipeline’ach CI/CD albo w zmiennych środowiskowych bez kontroli. Jeśli taki sekret nie jest rotowany i nie ma ograniczonego zakresu, staje się stałą przepustką do bucketów/kontenerów – często z uprawnieniami większymi niż potrzeba.

Ten błąd ma dwie warstwy:

  • Brak rotacji – klucze żyją miesiącami/latami, a ich kompromitacja oznacza długi „czas niejawnego dostępu”.
  • Złe przechowywanie i dystrybucja sekretów – sekrety lądują w repozytoriach, plikach konfiguracyjnych, obrazach kontenerów, logach, ticketach lub są współdzielone między systemami bez możliwości szybkiego odcięcia.

Jakie sekrety są najczęściej problemem?

W kontekście S3 i Azure Blob typowe „trudne” sekrety to:

  • AWS Access Keys (Access Key ID + Secret Access Key) używane przez aplikacje lub użytkowników IAM.
  • Azure Storage Shared Key oraz connection string do konta Storage (często z pełnym dostępem do całego konta).
  • Pośrednio: hasła/sekrety do narzędzi, które mają dostęp do storage’u (np. agent backupu, job ETL, narzędzia administracyjne).

Wspólny problem: są to długoterminowe poświadczenia, które łatwo skopiować i trudno wykryć ich użycie bez dodatkowych mechanizmów.

Lepszy wzorzec: tożsamość zamiast klucza

Najbezpieczniejsza praktyka w obu chmurach to minimalizowanie (a idealnie eliminowanie) stałych kluczy na rzecz mechanizmów opartych o tożsamość i krótkotrwałe poświadczenia:

  • AWS: role (IAM Role) i tymczasowe poświadczenia (STS) zamiast kluczy użytkownika IAM w aplikacjach.
  • Azure: Managed Identity + RBAC do Blob Storage zamiast Shared Key/connection stringów w aplikacjach.

Praktyczna korzyść: nie „rozdajesz” sekretów do środowisk uruchomieniowych; dostępy są wydawane dynamicznie i łatwiej je odciąć.

Gdzie trzymać sekrety, jeśli muszą istnieć?

Czasem klucze są potrzebne (integracja legacy, narzędzia zewnętrzne, migracje). Wtedy kluczowe jest użycie dedykowanych usług do zarządzania sekretami, zamiast plików i zmiennych środowiskowych bez kontroli:

ChmuraUsługa na sekretyTypowe zastosowanie
AWSAWS Secrets Manager (lub SSM Parameter Store)Przechowywanie i dystrybucja kluczy, rotacja, kontrola dostępu
AzureAzure Key VaultPrzechowywanie kluczy/sekretów/certyfikatów, kontrola dostępu, wersjonowanie

To nie tylko „sejf na hasła”. Dobra praktyka to także:

  • Ścisłe uprawnienia: tylko konkretna aplikacja/usługa ma prawo odczytu konkretnego sekretu.
  • Wersjonowanie sekretów i możliwość szybkiego przełączenia na nową wersję.
  • Audyt dostępu do sekretu (kto i kiedy pobrał) – szczególnie istotny przy incydentach.

Rotacja: proste zasady, które redukują ryzyko

Rotacja nie musi oznaczać skomplikowanych procesów. Najważniejsze jest wprowadzenie przewidywalnego cyklu i „bezpiecznego przełączenia”:

  • Ustal interwał rotacji (np. 30/60/90 dni) dla długoterminowych kluczy, które nadal istnieją.
  • Stosuj model dwukluczowy, gdzie to możliwe (generujesz nowy klucz, aktualizujesz konsumentów, dopiero potem wycofujesz stary).
  • Oddziel konta/tożsamości: osobne poświadczenia dla różnych aplikacji/środowisk (dev/test/prod), aby rotacja i kompromitacja nie miały „efektu domina”.
  • Minimalny zakres (least privilege): jeśli klucz musi istnieć, niech ma dostęp tylko do niezbędnych zasobów i operacji.

Najczęstsze antywzorce (które „działają”, ale są ryzykowne)

  • Jeden wspólny klucz do konta storage’u używany przez wiele aplikacji i skryptów.
  • Klucze wpisane w kod (repo), obrazy kontenerów lub pliki konfiguracyjne wdrażane razem z aplikacją.
  • Connection string z pełnym dostępem przekazywany do narzędzi analitycznych „na chwilę” i zostający na stałe.
  • Brak procedury „odcięcia” poświadczeń po odejściu osoby z zespołu lub po incydencie.

Minimalny przykład: pobranie sekretu zamiast trzymania go w kodzie

Poniżej uproszczony przykład pokazujący kierunek: aplikacja pobiera sekret z menedżera sekretów, zamiast przechowywać go na stałe w konfiguracji aplikacji.

# Pseudokod – idea: sekret jest w menedżerze sekretów, a nie w repozytorium
secret = secrets_manager.get("storage-credentials")
client = StorageClient(credentials=secret)

Kluczowe jest nie samo API, tylko centralizacja, kontrola dostępu i możliwość wymiany sekretu bez przebudowy całego łańcucha wdrożeniowego.

Wniosek

Stałe klucze do S3/Azure Blob są wygodne, ale z perspektywy bezpieczeństwa są jedną z najdroższych „oszczędności”. Najlepszy efekt daje podejście: tożsamość (role/managed identity) > krótkotrwałe poświadczenia > menedżer sekretów > dopiero na końcu długoterminowe klucze, które i tak muszą mieć rotację oraz minimalny zakres.

6. Błąd 5: brak logów dostępu i monitoringu (S3 Server Access Logging/CloudTrail; Azure Storage logging, Diagnostic settings, Sentinel)

Nawet najlepiej ustawione uprawnienia do S3/Azure Blob nie dają pełnego bezpieczeństwa, jeśli nie potrafisz odpowiedzieć na podstawowe pytania: kto uzyskał dostęp, do czego, kiedy i w jaki sposób. Brak logów dostępu oraz monitoringu sprawia, że wycieki danych, nadużycia tokenów czy nieautoryzowane operacje na obiektach mogą pozostać niewykryte tygodniami. W praktyce to częsty „cichy” błąd: wszystko działa, koszty są niskie, ale organizacja traci zdolność szybkiej detekcji i reakcji.

Co realnie tracisz bez logów i monitoringu

  • Wykrywalność incydentów – nie zobaczysz nietypowych wzorców (np. masowych odczytów, skoków pobrań, podejrzanych listowań).
  • Ścieżkę audytu – trudno ustalić, czy dostęp był autoryzowany, czy wynikał z błędnej konfiguracji.
  • Dowody – bez danych telemetrycznych analiza powłamaniowa jest niepełna, a często niemożliwa.
  • Kontrolę zgodności – wymagania regulacyjne i audytowe zwykle oczekują rejestrowania operacji na danych i tożsamościach.

Podstawowe kategorie logów: „kto zmienił konfigurację” vs „kto dotknął danych”

W kontekście storage warto rozróżnić dwa typy obserwowalności:

  • Logi kontroli (control plane) – operacje na konfiguracji i uprawnieniach (np. zmiana policy/RBAC, włączenie/wyłączenie publicznego dostępu, modyfikacja ustawień kontenera/bucketu).
  • Logi danych (data plane) – operacje na obiektach (np. GET/PUT/DELETE, listowanie, odczyty metadanych).

Częsty błąd polega na włączeniu tylko jednego z nich. Same logi „konfiguracyjne” nie pokażą exfiltracji danych, a same logi „dostępu do obiektów” nie wyjaśnią, skąd wzięła się luka w uprawnieniach.

S3: Server Access Logging vs CloudTrail (kiedy czego używać)

W AWS najczęściej spotkasz dwa mechanizmy:

  • S3 Server Access Logging – klasyczne logi żądań do bucketu (dostęp do obiektów). Przydatne do analizy ruchu i tego, co faktycznie było pobierane/wysyłane.
  • AWS CloudTrail – dziennik zdarzeń API dla usług AWS, w tym operacji administracyjnych oraz (po odpowiedniej konfiguracji) zdarzeń związanych z danymi. Kluczowe do audytu zmian i śledzenia, kto wykonał akcję w API.

Pułapka: organizacje często zakładają, że „CloudTrail już wszystko loguje”. W praktyce bez świadomego podejścia łatwo mieć luki w widoczności (np. brak śladu dla niektórych operacji na obiektach albo brak korelacji z tożsamością/źródłem).

Azure Blob: Storage logging, Diagnostic settings i Sentinel

W Azure obserwowalność storage opiera się zwykle o:

  • Azure Storage logging – rejestrowanie operacji na usłudze storage (w zależności od ustawień i typu konta/usługi). Pomaga w analizie dostępu do danych.
  • Diagnostic settings – mechanizm wysyłania logów/metryk do docelowych miejsc (np. Log Analytics Workspace, Event Hub, Storage). To fundament centralizacji i retencji.
  • Microsoft Sentinel – warstwa SIEM/SOAR do korelacji zdarzeń, alertowania i automatyzacji reakcji (np. wykrywanie anomalii, łączenie zdarzeń storage z tożsamościami i innymi sygnałami).

Pułapka: samo włączenie logowania „gdzieś” nie rozwiązuje problemu, jeśli dane nie trafiają do centralnego miejsca analizy, nie mają sensownej retencji albo nikt nie ma ustawionych alertów.

Porównanie w skrócie

ObszarAWS (S3)Azure (Blob)Typowy błąd
Logi operacji na danychS3 Server Access Logging / (opcjonalnie) zdarzenia danych w CloudTrailStorage logging + Diagnostic settingsBrak rejestracji odczytów/listowań lub brak centralizacji
Logi zmian konfiguracjiCloudTrailActivity Log + (w praktyce) wysyłka przez Diagnostic settingsBrak audytu zmian uprawnień/polityk
Alerty i korelacjaCloudWatch/GuardDuty (w zależności od podejścia)Sentinel (lub alerty w Azure Monitor)Logi są, ale brak reguł i reakcji
Retencja i dostępnośćDocelowo centralne konto/log bucketLog Analytics / Storage z polityką retencjiZbyt krótka retencja albo logi w tym samym miejscu co dane produkcyjne

Minimum, które warto mieć od razu

  • Centralizacja: wysyłka logów do oddzielnego miejsca (organizacyjnie i uprawnieniowo) niż dane aplikacyjne.
  • Retencja: okres dopasowany do potrzeb bezpieczeństwa i wymagań audytowych (zwykle dłuższy niż „kilka dni”).
  • Alertowanie: reguły na zdarzenia wysokiego ryzyka (np. masowe odczyty, nietypowe źródła, gwałtowny wzrost błędów autoryzacji, próby listowania wielu obiektów).
  • Korelacja z tożsamością: możliwość powiązania operacji z użytkownikiem/rolą/aplikacją (bez tego log jest mało użyteczny operacyjnie).

Krótki przykład: logi są, ale „nic nie widać”

Klasyczny scenariusz: logowanie włączone, lecz trafia do tego samego konta/projektu i może zostać skasowane przez atakującego mającego nadmiarowe uprawnienia. Albo logi są rozproszone w wielu miejscach, bez wspólnego widoku i bez alertów. Efekt jest ten sam: incydent wykrywasz dopiero po fakcie (np. gdy ktoś zgłosi wyciek lub gdy rachunek za transfer gwałtownie rośnie).

7. Błąd 6: brak versioning/immutability i ochrony przed ransomware (S3 Versioning/Object Lock; Azure Versioning/Immutability/Soft delete)

Wiele incydentów z danymi w S3 i Azure Blob nie polega na „wycieku”, tylko na zniszczeniu lub podmianie obiektów: zaszyfrowaniu przez ransomware, masowym usunięciu, nadpisaniu plików lub celowym sabotażu konta. W praktyce sama kontrola dostępu (kto może czytać/zapisywać) to za mało, jeśli środowisko nie ma wbudowanych mechanizmów odtwarzania i niezmienności.

Ten błąd ma dwa typowe źródła: po pierwsze, zespoły zakładają, że „chmura to backup” i nie planują odzyskiwania po nadpisaniu/usunięciu; po drugie, obawiają się kosztów i złożoności, więc odkładają wersjonowanie, retencję i blokady. Efekt jest taki, że pojedyncza pomyłka lub przejęcie uprawnień może doprowadzić do nieodwracalnej utraty danych.

  • Versioning chroni przed przypadkowym nadpisaniem i pomaga wrócić do poprzedniej wersji obiektu, ale nie gwarantuje odporności na złośliwe działanie, jeśli atakujący ma uprawnienia do kasowania wersji.
  • Soft delete / undelete (mechanizmy „kosza”) daje szansę na odzyskanie usuniętych obiektów w określonym czasie, lecz również może zostać obejściowy przy zbyt szerokich uprawnieniach lub niewłaściwej konfiguracji retencji.
  • Immutability / WORM (niezmienność) to warstwa kluczowa w scenariuszach ransomware: uniemożliwia modyfikację i usunięcie danych przez czas retencji, nawet gdy ktoś ma wysokie uprawnienia administracyjne w zakresie zapisu.

Amazon S3 najczęściej opiera ochronę na połączeniu Versioning oraz Object Lock (model WORM). Wersjonowanie daje „historię” obiektu, a Object Lock dokłada politykę retencji i blokadę usuwania/modyfikacji w czasie obowiązywania retencji. To rozwiązanie jest szczególnie istotne dla repozytoriów logów, archiwów, danych regulowanych oraz wszędzie tam, gdzie wymagane jest udowodnienie integralności.

Azure Blob Storage oferuje analogiczne klocki, zwykle zestawiane jako Blob versioning, soft delete (dla blobów/kontenerów) oraz immutability policies (retencja WORM na poziomie kontenera). Wersjonowanie i soft delete adresują typowe pomyłki operacyjne, a immutability pomaga spełnić wymagania odporności na modyfikacje i stanowi mocną barierę przed ransomware.

Najczęstsze nieporozumienie polega na tym, że organizacja włącza tylko wersjonowanie lub soft delete i uznaje temat za zamknięty. Tymczasem w scenariuszu ataku liczy się odporność na celowe kasowanie: jeśli napastnik uzyska uprawnienia do usuwania wersji albo skrócenia retencji, środki „odtwarzalne” przestają działać. Dlatego mechanizmy niezmienności oraz właściwie dobrane okresy retencji są fundamentem ochrony przed destrukcją danych.

Warto też pamiętać o konsekwencjach operacyjnych: włączenie wersjonowania zwiększa zużycie przestrzeni, a retencja i niezmienność wymagają wcześniejszego zaplanowania cyklu życia danych. To nie są jednak koszty „opcjonalne”, tylko element minimalnego poziomu bezpieczeństwa tam, gdzie utrata lub manipulacja obiektami ma realny wpływ na ciągłość działania.

8. Błąd 7: błędne CORS i nadmiernie liberalne reguły (źródła, metody, nagłówki, cache)

CORS (Cross-Origin Resource Sharing) w kontekście S3 i Azure Blob jest często traktowany jako „ustawienie pod frontend”, a nie jako element kontroli ryzyka. To błąd, bo CORS nie daje uwierzytelnienia ani autoryzacji, ale może umożliwić przeglądarkom wykonywanie żądań do zasobów z innych domen w sposób, który ułatwia nadużycia, wycieki danych i automatyzację ataków. Najczęściej problemem nie jest samo włączenie CORS, tylko zbyt szerokie reguły, które później zostają na stałe.

W praktyce CORS dotyczy przede wszystkim scenariuszy, w których aplikacja webowa pobiera lub wysyła obiekty bezpośrednio do storage (np. upload plików z przeglądarki, pobieranie obrazów, plików lub danych JSON). Jeśli konfiguracja jest zbyt liberalna, przeglądarka użytkownika może stać się „pośrednikiem” w dostępie do danych lub wykonywaniu operacji, które powinny być ograniczone do konkretnego originu i zestawu metod.

  • Zbyt szerokie originy: używanie wildcardów (np. dopuszczenie dowolnego originu) albo dopuszczenie całych domen nadrzędnych bez potrzeby. Skutkiem bywa możliwość odczytu odpowiedzi przez skrypt uruchomiony na nieautoryzowanej stronie, jeśli inne mechanizmy (np. token w URL, ciasteczko, nagłówki auth) pozwolą na wykonanie żądania.
  • Nadmierny zestaw metod: dopuszczanie metod „na wszelki wypadek” (np. PUT/DELETE) zamiast ograniczenia do rzeczywiście wymaganych operacji. CORS nie decyduje o uprawnieniach, ale poszerza powierzchnię operacji możliwych z poziomu przeglądarki, co zwiększa ryzyko nadużyć i błędów po stronie aplikacji.
  • Nadmiernie liberalne nagłówki: akceptowanie dowolnych nagłówków lub wprost dopuszczanie wrażliwych nagłówków autoryzacyjnych, gdy aplikacja nie musi ich wysyłać z przeglądarki. To ułatwia obejścia założeń projektowych i zwiększa konsekwencje wycieku tokenów.
  • Nieprzemyślany cache (max-age): długi czas cache’owania preflight może utrwalić błędną konfigurację i utrudnić szybkie odcięcie niepożądanego zachowania po zmianach w aplikacji lub incydencie. Z kolei zbyt krótki może generować dużo preflightów i skłaniać zespoły do „poluzowania” reguł, by pozbyć się problemów wydajnościowych.
  • Mylenie CORS z kontrolą dostępu: częsty antywzorzec to traktowanie CORS jako „zabezpieczenia przed obcymi stronami”. CORS to mechanizm przeglądarkowy; nie chroni przed żądaniami wykonywanymi poza przeglądarką (np. skrypty, narzędzia CLI, serwery), więc nie może zastąpić polityk dostępu.

Różnice między platformami są istotne z punktu widzenia operacyjnego: w S3 reguły CORS konfiguruje się na poziomie bucketu i są one typowo dopasowywane do wzorców żądań S3; w Azure Blob analogicznie definiuje się CORS dla usług storage i kontenerów, ale często dochodzi do tego ekosystem narzędzi (np. portale, SDK), które potrafią wprowadzić ustawienia „na szybko”, a potem nikt do nich nie wraca. Niezależnie od chmury, problemem jest zwykle brak minimalizmu i brak okresowej weryfikacji.

Bezpieczna praktyka na tym etapie to konsekwentne podejście „tyle, ile trzeba”: wskazywać konkretne originy (najlepiej wprost), ograniczać metody i nagłówki do używanych, oraz dobierać cache tak, aby równoważyć wydajność z możliwością szybkiej korekty. CORS powinien wspierać działanie aplikacji, ale nie zastępować mechanizmów kontroli dostępu i nie poszerzać ich skutków ubocznych.

W Cognity łączymy teorię z praktyką – dlatego ten temat rozwijamy także w formie ćwiczeń na szkoleniach.

icon

Formularz kontaktowyContact form

Imię *Name
NazwiskoSurname
Adres e-mail *E-mail address
Telefon *Phone number
UwagiComments