Unix vremenski označaji u sigurnosti i autentifikaciji — istjecanje tokena, sesije i ograničenje brzine zahtjeva

Vrijeme je osnovna sigurnosna primitiva. Istjecanje tokena, istek sesija, vremenski prozori ograničenja brzine i sprječavanje napada ponavljanjem — sve ovise o preciznom mjerenju vremena, a u suvremeним sustavima to mjerenje gotovo uvijek koristi Unix vremenske označaje.

Razumijevanje kako Unix vremenski označaji funkcioniraju u sigurnosnim kontekstima pomaže vam da ispravite greške pri autentifikaciji, ispravno dizajnirate sustave sesija i izbjegnete česte ranjivosti koje nastaju iz pogrešaka pri rukovanju vremenskim označajima.

Koristite Unix Timestamp Converter kako biste pregledali određene vrijednosti vremenskih označaja i pretvorili ih u čitljive datume.

Što čini Unix vremenske označaje dobrim za sigurnost

Unix vremenski označaj je cijeli broj koji predstavlja sekunde protekle od 1. siječnja 1970. UTC. Ova jednostavna reprezentacija ima nekoliko svojstava relevantnih za sigurnost:

Neovisnost o vremenskoj zoni. Vremenski označaj 1720000000 predstavlja isti trenutak svugdje na Zemlji, bez obzira na lokalnu vremensku zonu. Formatiran datumski niz poput "2024-07-03 14:00:00" je nejasniji — 14:00 u kojoj vremenskoj zoni? Unix vremenski označaji potpuno eliminiraju ovu nejasninu. Sigurnosne provjere koje uspoređuju vremenske označaje među sustavima u različitim vremenskim zonama ne mogu se razilaziti zbog razlika u interpretaciji vremenske zone.

Lagana aritmetika. Provjera je li token izdan u vremenu iat istekao u vremenskom prozoru od 1 sata jednostavna: current_timestamp > iat + 3600. Bez kalendarske matematike, bez parsiranja datuma, bez prilagodbe ljetnog računanja vremena. Aritmetika je točna i brza.

Kompaktno pohranjevanje. 32-bitni ili 64-bitni cijeli broj je mnogo manji od formatiranog datumskog niza. Za sustave koji generiraju i pohrane milione tokena, sesija ili unosa u zapisnik, to je važno.

JWT istjecanje tokena: iat, exp i nbf zahtjevi

JSON Web Tokeni (JWTs) koriste Unix vremenske označaje za njihove zahtjeve vezane uz vrijeme:

  • iat (issued at): Unix vremenski označaj kada je token kreiram. Koristi se za mjerenje starosti tokena i otkrivanje tokena kreiranih daleko u prošlosti.
  • exp (expiration time): Unix vremenski označaj nakon kojega token ne smije biti prihvaćen. Validacijski server provjerava current_time > exp — ako je istinito, token je istekao i odbijen je.
  • nbf (not before): Unix vremenski označaj prije kojega token ne smije biti prihvaćen. Rjeđe korišten, ali koristan za tokene koji su unaprijed generirani i trebali bi biti valjani tek u određenoj budućoj vremenu.

Tipični JWT payload izgleda ovako:

{
  "sub": "user_12345",
  "iat": 1720000000,
  "exp": 1720086400,
  "nbf": 1720000000
}

U ovom primjeru, exp - iat = 86400, što znači da je token valjan točno 24 sata (86 400 sekundi).

Česta greška: postavljanje istjecanja u milisekundama. Budući da Date.now() u JavaScriptu vraća milisekunde, programeri ponekad izračunaju exp kao Date.now() + 86400000 (dodavajući milisekunde vremenskom označaju u milisekundama). Ako JWT biblioteka očekuje sekunde, to kreira token s istjecanjem 1000 godina u budućnosti umjesto 24 sata. Uvijek podijelite s 1000 kada radite u JavaScriptu: Math.floor(Date.now() / 1000) + 86400.

Za inspekciju istjecanja JWT tokena: dekodirajte base64 payload i pogledajte exp. Zalijepite vremenski označaj u Unix Timestamp Converter kako biste vidjeli čitljivo vrijeme istjecanja.

Istek sesija i klizavi prozori

Web aplikacijske sesije koriste vremenske označaje kako bi implementirale dva tipa isteka:

Apsolutni istek: Sesija istječe u fiksnom vremenu nakon kreiranja, bez obzira na aktivnost. Implementacija: pohranite created_at vremenski označaj kada se sesija kreira. Na svakom zahtjevu provjerite current_time - created_at > max_session_seconds. Ako je istinito, poništite sesiju i zahtijevajte prijavu.

Klizavi istek (istek zbog neaktivnosti): Sesija istječe nakon razdoblja neaktivnosti. Svaki zahtjev produžuje prozor. Implementacija: pohranite last_active vremenski označaj, ažuriran na svakom zahtjevu. Provjerite current_time - last_active > idle_timeout_seconds. Ako je istinito, sesija je bila neaktivna previše dugo i istekla je.

Većina aplikacija trebam oboje: klizavi prozor radi pogodnosti (nema odjave tijekom aktivne upotrebe) i apsolutni maksimum (sesija nikad ne ostaje valjana beskonačno čak i s kontinuiranom aktivnosti). Tipična kombinacija: 30-minutni istek zbog neaktivnosti, 8-satni apsolutni maksimum.

Implementacija: `python if current_time - session["last_active"] > 1800: # 30 min neaktivnosti invalidate_session() if current_time - session["created_at"] > 28800: # 8 h apsolutno invalidate_session() session["last_active"] = current_time `

Vremenski prozori ograničenja brzine

Ograničenje brzine zahtjeva obično funkcionira u fiksnim vremenskim prozorima mjerenim u sekundama. Česte implementacije:

Fiksni prozor: Dopustite N zahtjeva po prozoru. Prozor je razdoblje poput "po minuti" ili "po sati," definirano kao raspon Unix vremenskih označaja. Prozor za trenutnu minutu je floor(current_time / 60) * 60 do te vrijednosti plus 60. Kada zahtjev stigne, povećajte brojač ključan za trenutni vremenski označaj prozora. Ako je brojač > N, odbijte.

Klizavi prozor: Precizniji od fiksnog prozora. Pratite vremenski označaj svakog zahtjeva u zadnjih N sekundi. Na svakom novom zahtjevu, prebrojite koliko pohrajenih vremenskih označaja pada u current_time - window_seconds do current_time. Ako je broj >= granica, odbijte; inače zabilježite novi vremenski označaj.

Klizavi prozor sprječava problem na granici s fiksnim prozorima (korisnik bi mogao napraviti N zahtjeva u 11:59 i N zahtjeva u 12:00, dobivajući 2N zahtjeva u dvije uzastopne minute).

Za distribuirane sustave s više poslužitelja, ograničenje brzine zahtjeva trebam zajedničku pohranu (Redis je čest). Brojač ili popis vremenskih označaja pohranjena je s TTL-om koji se poklapa s prozorom, tako da se automatski istječe. Ključ je obično ratelimit:{user_id}:{window_start_timestamp}.

Sprječavanje napada ponavljanjem s vremenskim označajima

Napad ponavljanjem je kada napadač presreće validan zahtjev i ponovno ga pošalje kako bi uzrokovao istu radnju. Vremenski označaji koriste se kako bi se to otežalo.

Vremenski označaj temeljem nonce: Uključite trenutni Unix vremenski označaj u potpis zahtjeva. Primajući server provjerava je li vremenski označaj u prihvatljivom prozoru (npr. ±5 minuta od trenutnog vremena servera). Zahtjevi s vremenskim označajima izvan prozora odbijeni su, čak i ako je potpis validan. To ograničava prozor ponavljanja na 5 minuta — nije savršeno, ali sprječava neograničene napade ponavljanjem.

Ograničenje: prozor od 5 minuta još uvijek dopušta neko ponavljanje. Kako bi se ponavljanje potpuno eliminiralo, trebate pohraniti i provjeriti da se specifična kombinacija timestamp+nonce nije prethodno koristila (obično u kratkotranoj memoriji s TTL-om jednakim prozoru ponavljanja).

TOTP (Time-based One-Time Passwords): Aplikacije poput Google Authenticatora koriste Unix vremenske označaje za generiranje vremenski temeljenih kodova. Trenutni 30-sekundni prozor (floor(current_time / 30)) koristi se kao ulaz za HMAC funkciju zajedno sa zajedničkom tajnom. Kod se mijenja svakih 30 sekundi, čineći napade ponavljanjem izvan tog prozora nemogućima.

Pomak sata i sinkronizacija vremena

Sigurnost temeljena na Unix vremenskim označajima funkcionira samo ako su satovi sinkronizirani. Ako je sat klijenta 10 minuta ispred servera, klijent generiram JWT exp koji server mislim da je već u budućnosti — ili token s nbf koji na klijentu nije još valjan.

U praksi:

  • Serveri trebaju koristiti NTP (Network Time Protocol) kako bi satovi bili sinkronizirani na nekoliko milisekundi
  • JWT validatori trebali bi dozvoljeti male tolerancije pomaka sata (1–5 minuta) pri provjeravanju exp i nbf
  • Ne vjera vremenskim označajima koje dostavi klijent za sigurnosne odluke — uvijek koristite vremenski označaj na strani servera za iat, exp i zapise revizije

Unix Timestamp Converter prikazuje trenutni vremenski označaj kako ga vidi vaš preglednik. Ako debug-irate nepodudarnost, usporedite ovo s date +%s na serveru kako biste provjerili pomak sata.

HMAC potpisi i zahtjevi temeljeni na vremenskom označaju

Mnogi webhook sustavi i sheme autentifikacije API-ja (AWS Signature Version 4, Stripe webhook verifikacija, Shopify webhooks) uključuju trenutni vremenski označaj u potpisani sadržaj. Potpis pokriva i payload i vremenski označaj, i primatelj provjerava da:

1. Potpis se poklapa (payload + vremenski označaj nisu tamponirani) 2. Vremenski označaj je u prihvatljivom prozoru (zahtjev nije zastario ili ponavljanje)

AWS SigV4 koristi formatni format datuma (YYYYMMDDTHHMMSSZ) umjesto Unix vremenskog označaja, ali temeljna logika je ista — vrijeme je dio onoga što se potpisuje, i primatelj odbija zahtjeve s vremenskim označajima izvan 15-minutnog prozora.

Pri debug-iranju kvarova u verifikaciji webhook potpisa, česta greška je zastari vremenski označaj — sat webhook pošiljaoca je pogrešan ili postoji značajna kašnjenja u dostavi (message queues, ponovni pokušaji) koja gura vremenski označaj izvan prihvatljivog prozora.

Debug-iranje neuspješnih autentifikacija vezanih uz vremenske označaje

Najčešće greške pri autentifikaciji vezane uz vremenske označaje:

1. Token istekao: Provjerite exp dekodiranjem JWT-a i konverzijom exp u datum. Unix Timestamp Converter to radi u jednom koraku. 2. Token još nije valjan: nbf je u budućnosti. Provjerite je li token generiram s budućim vremenom početka. 3. Pomak sata: Satovi servera i klijenta nisu sinkronizirani za više od tolerancijskog prozora. Provjerite oba sata naspram referentne točke. 4. Milisekunde naspram sekundi: 13-znamenkasti vremenski označaj proslijeđen gdje se očekuje 10-znamenkasti, ili obrnuto. Token s exp: 1720086400000 (milisekunde) nikad neće istjeći — predstavlja datum za 56 000 godina. 5. Zbunjenost vremenske zone u zapisu: Unosi u zapisnik pokazuju vremenski označaj koji izgleda pogrešno jer zapisi koriste lokalno vrijeme, a usporedba vremenskog označaja koristi UTC. Unix vremenski označaji su uvijek UTC; eksplicitno ih formatujte pri prikazu.

Povezani članci