Zaštitite svoju web stranicu od vrlo uobičajene sigurnosne rupe s Djangovom ugrađenom CSRF obradom.
Django je Python web framework koji možete koristiti za izradu sigurnih web aplikacija. Nudi mnoge značajke koje pomažu programerima sa sigurnošću. Jedna od tih značajki su CSRF tokeni, bitni u zaštiti obrazaca od Cross-Site Request Forgery napada.
Što je CSRF token?
CSRF token je sigurnosna značajka koja štiti web aplikacije od Cross-Site Request Forgery (CSRF) napadi. Omogućuje aplikacijskom poslužitelju da provjeri je li podnošenje obrasca došlo iz autentičnog preglednika ili ga je haker krivotvorio.
CSRF tokeni su unosi obrazaca koji prate korisničku sesiju. Web stranica okvir web aplikacije na strani poslužitelja obično generira CSRF tokene za svaku jedinstvenu korisničku sesiju. Poslužitelj provjerava je li token ispravan kad god korisnik podnese obrazac. CSRF tokeni općenito se sastoje od nasumičnih nizova i brojeva, što njihove vrijednosti čini nepredvidivim.
Generiranje CSRF tokena u Djangu
Djangov get_token() funkcija nasumično generira CSRF tokene. Da biste pronašli ovu funkciju, idite na csrf.py datoteku unutar vašeg Python virtualno okruženje. Struktura mape trebala bi izgledati ovako:
env/
└── Lib/
└── web-paketi/
└── django/
└── međuprogram/
└── csrf.py
Unutar ove datoteke pronaći ćete get_token() funkcija koja vraća token. Django koristi maskiranje podataka kako bi zaštitili vrijednost tokena od hakera.
Prema zadanim postavkama, Django omogućuje CSRF zaštitu za vašu stranicu dodavanjem django.middleware.csrf. CsrfViewMiddleware u MIDDLEWARE popis vaših postavke.py datoteka. Sve što trebate učiniti je dodati {% csrf_token %} vašem POST oblicima. Bez dodavanja {% csrf_token %}, dobit ćete a 403 Zabranjeno) greška kada pošaljete obrazac.
Kada dodate {% csrf_token %} na vaš obrazac, automatski stvara skriveno polje za unos s imenom csrfmiddlewaretoken, koji sadrži vrijednost maskiranog CSRF tokena. Poslužitelj koristi ovu vrijednost za utvrđivanje je li predaja obrasca autentična. Možete provjeriti vrijednost ovog skrivenog polja pregledom izvora stranice ili pomoću značajke alata za razvojne programere vašeg preglednika.
Kako CSRF tokeni rade u Djangu
Kada pokrenete svoje web mjesto s obrascem, Django automatski kreira a kolačić preglednika nazvao csrftoken. Ovaj kolačić prati aktivnosti korisnika na stranici i jedinstveno identificira svakog korisnika.
Kada korisnik pošalje obrazac, poslužitelj uspoređuje vrijednost kolačića s vrijednošću kolačića csrfmiddlewaretoken u skrivenom polju za unos. Ako se te vrijednosti podudaraju, poslužitelj će uspješno obraditi obrazac, u suprotnom će proizvesti pogrešku.
Na prvi pogled, vrijednosti kolačića i csrfmiddlewaretoken izgledaju drugačije. Ovo je namjerno i dodaje dodatni sloj zaštite CSRF tokenu. CSRF token uspoređuje se s kolačićem ovako:
- The get_token() funkcija maskira CSRF token prije nego što ga proslijedi u polje za unos.
- Kada se obrazac pošalje, CSRF token se demaskira uz pomoć tajnog ključa u datoteci postavki.
- Nemaskirani token uspoređuje se s kolačićem sesije.
- Ako su vrijednosti iste, obrazac se obrađuje. Ako nije, poslužitelj vraća pogrešku.
Kako bi spriječio hakere da vam ukradu CSRF token, Django ga obnavlja svaki put kada pokrene korisničku sesiju.
Stvaranje prilagođenih CSRF tokena
Iako Django olakšava zaštitu vaših obrazaca jednostavnim dodavanjem {% csrf_token %}, moguće je i generiranje CSRF tokena i njihovo ručno dodavanje u vaše obrasce. Da biste to učinili, uvezite get_token() funkcija:
iz django.middleware.csrf uvoz get_token
Po vašem mišljenju, CSRF token možete generirati ovako:
defnaziv_pogleda(zahtjev):
csrf_token = get_token (zahtjev)# izvođenje logike pogleda
kontekst = {
"csrf_token": csrf_token
}
povratak prikazati (zahtjev, 'naziv_aplikacije/predložak.html', kontekst=kontekst)
U svoj HTML predložak možete ručno uključiti svoju ulaznu oznaku i dodati csrf_token na to ovako:
<oblikmetoda="POST" >
<ulaznitip="skriven"Ime="csrfmiddlewaretoken"vrijednost="{{ csrf_token }}">
{{form.as_p}}
<dugmetip="podnijeti"razreda="btn btn-outline-secondary">Dodaj knjigudugme>
oblik>
Alternativno, možete generirati skriveno polje za unos iz svojih prikaza ovako:
deftvoj_pogled(zahtjev):
csrf_token = get_token (zahtjev)
csrf_token_html = ''.format (csrf_token)# izvođenje logike pogleda
kontekst = {
"csrf_token": csrf_token_html
}
povratak prikazati (zahtjev, 'naziv_aplikacije/predložak.html', kontekst=kontekst)
Zatim ga možete dodati u svoj HTML predložak ovako:
<oblikmetoda="POST" >
{{ csrf_token_html|siguran }}
{{form.as_p}}
<dugmetip="podnijeti"razreda="btn btn-outline-secondary">Dodaj knjigudugme>
oblik>
Ako želite potpuno kontrolirati CSRF zaštitu svog obrasca, to možete učiniti usporedbom svog CSRF tokena s kolačićem pohranjenim u pregledniku. Na temelju rezultata usporedbe, možete rukovati slanjem obrasca kako god želite. Evo primjera:
iz django.prečaci uvoz prikazati
iz django.middleware.csrf uvoz get_token, _demask_cipher_token
iz django.utils.crypto uvoz konstantno_vrijeme_usporeditideftvoj_pogled(zahtjev):
# Generirajte prilagođeni CSRF token
csrf_token = get_token (zahtjev)
csrf_cookie = zahtjev. KOLAČIĆI.get('csrftoken')# demaskirajte csrf token
unmasked_csrf_token = _demask_cipher_token (csrf_token)
# Usporedite žetone
akone konstantno_vrijeme_usporedbe (unmasked_csrf_token, csrf_cookie):
# Postupite u slučaju kada se tokeni ne podudaraju
proći
drugo:
# Obradite slučaj kada se tokeni podudaraju
proći
# Renderirajte predložak
kontekst = {
'csrf_token': csrf_token,
}
povratak prikazati (zahtjev, 'naziv_aplikacije/predložak.html', kontekst=kontekst)
Ovaj isječak koda dohvaća csrf_kolačić iz objekta HTTP zahtjeva. Zatim koristi _unmask_cipher_token() funkcija razotkrivanja csrf_token.
Uvjetna izjava uspoređuje vrijednosti dohvaćenih csrf_kolačić i nemaskiranog csrf_token. Ova usporedba koristi konstantno_vrijeme_usporediti funkcija zaštite od vremenskih iskorištavanja. Možete napisati svoju logiku na temelju rezultata usporedbe.
Onemogućavanje CSRF zaštite u Djangu
Iako Django postavlja zadanu odredbu za CSRF zaštitu, možete je onemogućiti u svom projektu ako želite. Postoje dva načina za to:
- Onemogućavanje CSRF zaštite na cijeloj web stranici.
- Onemogućavanje CSRF zaštite na određenom prikazu.
Onemogućavanje CSRF zaštite na vašoj cijeloj web stranici
Da biste onemogućili Djangovu CSRF zaštitu na svojoj web stranici, jednostavno morate ukloniti CSRF međuware iz svoje datoteke postavki. U datoteci postavki pronađite popis pod nazivom MIDDLEWARE. Unutar popisa potražite ovo:
'django.middleware.csrf. CsrfViewMiddleware',
Kada ga pronađete, trebali biste ga ukloniti iz svog koda kako bi ga Djangova zadana CSRF zaštita onemogućila.
Onemogućavanje CSRF zaštite na određenom prikazu
Ako samo želite onemogućiti CSRF zaštitu na određenom Django prikazu, koristite @csrf_izuzeto dekorater. Evo isječka koda za demonstraciju:
iz django.views.decorators.csrf uvoz csrf_izuzeto
@csrf_izuzeto
defnaziv_pogleda(zahtjev):
# izvođenje logike pogleda
proći
The @csrf_izuzeto dekorater je samo jedan od nekoliko povezanih sa CSRF zaštitom u Djangu. O ostalom možete čitati na Djangova CSRF referenca.
Nemojte onemogućiti CSRF zaštitu na svojoj web stranici
Iako Django to omogućuje, ne preporučuje se onemogućavanje Djangovog ugrađenog CSRF mehanizma zaštite. Ako to učinite, vaša će stranica postati ranjiva na CSRF napade i u konačnici negativno utjecati na korisnike vaše aplikacije.
Osim ako niste iskusni programer koji zna kako implementirati prilagođeni CSRF zaštitni mehanizam, trebali biste raditi s alternativom koju nudi Django.