» »

REST API in Authorization (PHP)

REST API in Authorization (PHP)

cheetah2 ::

Naredil sem REST API webservice in ga zaščitil tako, da sem dodelil vsaki stranki unikaten 32 znakov dolg token (ga lahko poljubno spremenijo). Če stranka želi dostopati do webservice-a, mora token v requestu poslati preko header polja Authorization, server pa nato preko funkcije apache_request_headers() preveri, če se ta ujema s tistim v bazi. Zadeva deluje ampak imam pomisleke glede varnosti. Kolikor berem na internetu, to naj ne bi bila najboljša praksa in bi bilo bolje uporabiti OAUTH 2.0 o katerem pa nimam pojma. Mogoče kdo ve za kakšen dober vodič in ali je vse skupaj sploh vredno zakomplicirati, ker bom tako ali tako uporabil https protokol (tako da predvidevam, da če bo webservice deloval preko njega, da ne bo težav ali se motim?). Bi se pa v vsakem primeru rad naučil, kako bi se lahko uporabnik prijavil preko OAUTH 2.0 in tako varneje dostopal do API-ja, tako da bi prosil za kakšno pomoč, namige, da bi mi vse skupaj čimprej postalo jasno :)

cheetah2 ::

Pa trenutno mora stranka dobesedno poslati takšen zahtevek v headerju "Authorization: token" kar mislim, da tudi ni najboljša praksa ali se motim?

k--p ::

Kako pa dobi uporabnik token? Najprej prijava na določen endpoint z username/password, nato pa se generira unikaten token za tega userja? Ta del mora biti vsekakor pod https. Priporočjivo je, da tokenu poteče rok trajanja. Takrat mora zahtevati nov token. Če namesto navadnih tokenov uporabljaš JWT, tokenov tudi ne rabiš nujno shranjevati v bazi, saj so podatki shranjeni v tokenu in zakriptirani (recimo username, expiration date). V grobem oauth2 deluje tako. Kako uporabnik pošlje token nima veze, je pa header v Authorization headerju standardna praksa (vrednost pa v obliki Bearer user_token). Vsekakor pa je pa zelo dobro, če povsod uporabljaš SSL.

Zgodovina sprememb…

  • spremenilo: k--p ()

cheetah2 ::

Token se generira ob registraciji uporabnika in se shrani v bazo. Generiram ga s pomočjo spodnje kode (pobrana iz neta, zaradi random_int() je potrebna PHP verzija 7+).

function random_str($length, $keyspace = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
{
	$str = '';
	$max = mb_strlen($keyspace, '8bit') - 1;
	for ($i = 0; $i < $length; ++$i) {
		$str .= $keyspace[random_int(0, $max)];
	}
	return $str;
}


Če registracija poteka preko https (še nisem delal s tem protokolom zato niti ne vem, kako točno vse skupaj deluje, tako da malo ugibam), potem zakaj bi jaz sploh še potreboval neko spreminjanje tokenov ali ta oauth2? Saj si verjetno client in strežnik že prej izmenjata ključe, da lahko potem ustrezno zavarujeta podatke, ki se nato prenašajo, vključno z glavo zahtevka/odgovora, torej tudi podatek o "Authorization: token", ki ga pošlje client in podatek "Set-Cookie: ..." s katerim na primer dobimo ID seje, ki ga v odgovoru takoj na začetku pošlje strežnik. Torej zakaj bi se zdaj še nekaj trudil, da bi znotraj že tako kriptiranih podatkov, kriptiral še podatke za Authorization? Če pa prenos poteka po http, pa seveda lahko nastopijo težave ampak, če se ne motim, če že nekako zaščitim Authorization, ne zaščitim pa "Set-Cookie" oz. nato client requesta s podatkom o Cookie spet nisem naredil nič, ker če mi kdo prestreže pakete in dobi podatek o ID seje in teoretično, da sem takrat ravno prijavljen tudi sam, se lahko v aplikcijo prijavi tudi sam, kar je pa še slabše kot če bi dobil dostop le do api-ja :) Ok, če uporabljam http, bodo pač težave, če mi kdo prestreza promet :) Vprašanje pa je ali se lahko s https rešim vseh teh problemov in drugo, kako zelo, se je sploh vredno za običajne strani sekirati, v primeru, da poteka komunikacija preko http, na primer, ravno sem preveril bolha.com. :P Komunikacija poteka preko http, podatek o ID seje se nahaja v cookie BOLHA_SSID, če mi nekdo prisluškuje in dobi ta podatek, se lahko hitro prijavi v mojem imenu, preko kakšnega cookie managerja spremeni podatek za cookie in je notri, sem preveril pri bolhi in gre, torej nimajo nobene zaščite. Če bi prav čas začel prisluškoval, bi pa tako lahko dobil podatke o geslu in uporabniškem imenu iz POST, recimo. Malo sem zašel ampak s tem OAUTH2 bi se lahko pred vsem tem zaščitil tudi že pri dostopu preko http? Takole malo na blef bi se verjetno res dalo rešiti (zdaj spet malo ugibam, ker je moje kriptografsko znanje bolj kilavo) s simetrično kriptografijo (če se sploh tako imenuje), kjer bi potem bil en skupen token, ki bi ga imela server in client in bi z njim kodirala/odkodirala sporočila ali asimetrično kripografijo (RSA), kjer bi imel strežnik svoj privatni in javni ključ, client pa prav tako svoja dva, izmenjala bi si le javna ključa in potem bi client kriptiral requeste z javnim ključem od serverja, odgovore pa bi odkriptiral pač s svojim zasebnim ključem (podatke bi mu jasno strežnik zakodiral z njegovim javnim ključem), strežnik pa bi počel pač enako le da s svojimi ključi. A je to potem ta https://jwt.io/ (prvič slišim zanj)? Samo za implementacijo se mi zdi to strašno komplicirano.

Za na konec pa še tole čisto mimogrede, sem videl, da praviloma nekateri pod "Authorization: token" pišejo "Authorization: Basic token" ali "Authorization: Bearer token". A to je kak dogovor ali kaj? Ta beseda mi potem pri apache_request_headers() samo v napoto hodi, ker mene tako zanima le vrednost za token.

Zgodovina sprememb…

  • spremenilo: cheetah2 ()

k--p ::

Sem podal samo nekaj napotkov, nisem security expert, ampak da, s HTTPS se rešiš skoraj vseh težav, tudi v tvoji implementaciji. Podobno namreč deluje tudi "basic authentication" protokol, kjer z vsakim requestom pošlješ v headerju username + password (tukaj je zgolj dogovor oblika Authorization: Basic hash(username:password, ker to browserji znajo interpretirati, kar tudi odgovori tvoje zadnje vprašanje).
Je pa potrebno nujno uporabiti https in je stvar varna.
Je pa vsekakor še korak dalje v varnosti token, ki se se spreminja s časom, saj je ponovljivost pošiljanja istega tokena (ali username+password) šibkost. Ponovljivost pa olajša napade. Tukaj si predstavljaj, da napadalec vseeno pride nekako do tokena (npr. zvabi uporabnika, da pošlje request kam drugam).

Potem je pa tu še en vidik, predstavljaj si npr. da gre za spletno aplikacijo (tipa bolha, čeprav ta ni restful in uporablja seje), ki uporablja RESTful backend. V tvojem primeru, gre zgolj za api (ki ga kliče nek sistem) in to ni problem, v aplikaciji pa mora biti na voljo tudi logout (to se doseže tako, da token poteče ali pa se ga izbriše). Potem pa spet rabiš postopek za pridobivanje novega tokena, kar ti v bistvu oauth2 omogoča.

Z oauth2 se IMO ne moreš izogniti https, saj v prvem koraku, za pridobivanje tokena, vedno pošlješ credentials (username in password), to pa mora biti kriptirano. Pa tudi za naprej, da ne more napadalec prestreči tokena. Čeprav je huje, da dobi username+password kot pa token. Vsekakor je HTTPS obvezen za VSE oblike avtentikacije, če želimo, da je stvar res varna.

JWT so zgolj priročno orodje, saj namesto navadnega tokena (random string) pošlje uporabne podatke (ki pa jih zna samo server razbrat (v kodi ima definiran ima svoj "secret" v obliki nekega stringa, s pomočjo katerega dekriptira token in pobere ven podatke)). Za delo z njim se uporabi kaka knjižnica in zadeva potem ni tako zakomplicirana. Omogočajo pa to, da kar iz tokena pobereš ven username in nato recimo preveriš, katere pravice so vezane na username, če ta sploh obstaja itd. Samega tokena pa ne rabiš shranit. V tvojem primeru verjetno to ne pride toliko v poštev, ker ne gre za spletno aplikacijo z userji oz. ne preverjaš, na katerega uporabnika je vezan token. To je bolj odvisno od same poslovne logike api-ja.


Fajn bi bilo, če še kdo drug kaj napiše, zgoraj sem podal zgolj moje razumevanje in izkušnje.

Zgodovina sprememb…

  • spremenilo: k--p ()


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

Seznam Airdropov! Free crypto (strani: 1 2 3 424 25 26 27 )

Oddelek: Kriptovalute in blockchain
1348161688 (411) error7891
»

skripta za pošiljanje brezplačnih sms sporočil (strani: 1 2 3 4 )

Oddelek: Programiranje
19544571 (9811) AštiriL
»

ID key (ključ) v url-ju - varnost?

Oddelek: Izdelava spletišč
81297 (1022) arjan_t
»

Facebook publish

Oddelek: Izdelava spletišč
131271 (792) user4683
»

Nezaželeno odtekanje podatkov s Facebooka tretjim stranem

Oddelek: Novice / Zasebnost
146718 (5409) Ramon dekers

Več podobnih tem