Tiszteletem a fórumozóknak!
Előzetesen, nem mondanám magam totál kezdőnek, de profil szakértőnek se a témában. megpróbálom pontosan körül írni a helyzetet, ha valahol rosszul fogalmaztam akkor kérném javítani.
Szerintem nem én vagyok az egyetlen aki ezzel küdz, vagy hozzám hasonlóan nem is tudja hogy pontosan mivel küzd (maximum heélyes, vagy téves sejtései vannak róla)
Van egy Angular 6 kliens ami a példa kedvéért http://www.domain.hu, https://www.domain.hu-n van elhelyezve.
Adott egy typescriptben megírt Nodejs backend, ExpressJs, MongoDb, szokásos, aminek a https://api.domain.hu/v1 a kiindulási pontja.
Az Api és a webserver nem egy és ugyanaz a szerver, lokális hálózaton két külön vas.
A teljességhez hozzátartozik még, hogy egy nginx proxy fowrawrdolja az api felé a kéréseket, ami a webszerveren van beállítva, mert maga az api nincs kirakva a nagyplénum elé,
az nginx fogadja internet felöl, és forwardol proxy_pass alapján.
Na most szeretnék beállítani egy CSRF tokenes védelmet...ha kell egyáltalán, mert olyant is olvastam, hogy nem is kell, ha van rendes CORS.
Minnél többet olvasok a témában, annál inkább kezdek elveszni a rengetegben, és nem bírom működésre bírni a CSRF-Token cserét.
A CORS beállítás megvan az api esetében, az origin kizárólag http://www.domain.hu, https://www.domain.hu van engedélyezve, megy is,
máshonnan hívva az apit egyből jön a preflight check error, allow access control hiba...ami rendben is van (vagy legalábbis eddig úgy tűnik, rendben van)
Hozzáteszem ennek se feltétlen ismerem 100%ra a pontos működését, csak nagyságrendileg.
Api esetén telepítve van npm-mel a cookie-parser, meg csurf nevű library, ami azt ígéri, majd mindent megold.
Megnézve az api response-t a set-cookie benne is van, de...még át is tudom nevezni, XSRF-TOKEN-re mert az angular.io ide vágó részében leírják, hogy ha így nevezem el, az angular okos, és intéz mindent.
Ennek ellenére...röviden...nem megy.
( Őszinte legyek, kezd is elmenni tőle a kedvem, mert sosem értettem igazán mire jók a cookie-k egyáltalán. Key, Value tárolásra? Arra ott van session, meg local storage..akkor mire jó még mindig a cookiezás?)
Tehát ha jól értem, az egész CSRF lényege az lenne, hogy az api response headerbe tesz egy set-cookie-t, benne csrf-token=xxxxxxxxxx, path: "/", meg ami kell.
Aztán a következő alkalommal, amikor a kliens api hívást intéz, akkor ezt az azonosítót kiolvassa a cookieból, berakja a request headerbe, és elküldi cookieval együtt az api felé...
az api meg összehasonlítja a két értéket, ha egyezik, a az api kérés oké, generál egy másik tokent, és választban újra beleteszi az új tokent a response headerbe, és így tovább mint a ringispil..
A kliensnek ez alapján a respone headerben található set-cookie csrf=xxxxxxxxxxx alapján nem kellene elmentenie egy cookiet a gépre?
csrf néven, benne a tokennel? mert ez nem történik meg, ha kellene egyáltalán.
Az Api olyan tüneteket produkál, mintha ott minden rendben lenne...kérdés, hogy a kiadott token-t illik-e elmenteni valahol api szinten, mondjuk adatbázisban?
Nem gondolnám, hiszen úgyis a requestben együtt jön a cookie, meg a request headerben a token, tehát minden adott az ellenőrzéshez.
Lehet e probléma, hogy a kliens http is, és nem csak és kizárólag https en érhető el?
Lehet-e baj az, hogy az api meg a kliens két külön aldomain?
ugye www.domain.hu, és api.domain.hu a felállás..érdemes-e áttenni az api-t, ww.domain.hu/api ra? vagy ez maga minden baj forrása? :)
ezt még nem próbáltam ki, bár nem örülnék ha ezt át kellene variálni, de mindent a cél érdekében...
Esetleg Angular bug? olvastam hogy elég érdekesen van megcsinálva Angular alatt a dolog...elvileg automatikusan megold mindent..aztán jönnek a stackoverflow-k, hogy nem megy, mert...
..a kiadott cookie beállításai..
httpOnly: false nak kell lennie, és path="/"..megpróbáltam..nem lett jó...
aztán jött olyan, hogy a post requestnél withCredentials: true,t kell állítani...
Jó lenne olyan angularos hozzászólás aki ezt már meg tudta ugrani angular 4-5-6-tal...az "új" angular/common/http...HttpClient-jével...mert az előd Angularoknál ez másképp volt.
huh...röviden tömören ennyi? :)
- 1354 megtekintés
Hozzászólások
Hali!
SPA esetében mindenhol azt írják hogy session-t nem ajánlott. A local storage meg nem biztonságos, mert azt meg rossz fiúk is ki tudják olvasni egy egyszerű js kóddal. Ezért igaziból marad a cookie és ha secure adatot akarsz benne tárolni pl. tokent akkor httpOnly a biztonságos. Kezdésnek az mondanám hogy a kliensről inditott requestekbe rakd bele az Access-Control-Allow-Origin headert ha még nincs.
Amúgy az api nálad nincsen biztositva hogy Authorization headerben küldött jwt tokennel?
Elméletileg az angularban van beépitett xsrf bár ahogy kollégám a belső confluencen irta ez csak local környezetben megy szóval vegyük úgy hogy meg kell irnod magadnak.
Ez a link talán segít
- A hozzászóláshoz be kell jelentkezni
Hali penztar!
Van JWT, headerben BEARER token, ha sikeres a két faktoros beléptetés...az egész JWT 2FA-t magam implementáltam, élveztem is:)
Ezt a tokent kliens oldalon localstorage-ben tárolom, és szükség esetén onnan olvassa ki a kliens, és küldi headerben Authorization: BEARER token.
Api oldalon meg ha a user loginja sikeres, akkor létrehozok neki egy "session" bejegyzést az adatbázisban, ami összeköti a tokent a user id-val.
Így magában a kiadott JWT-ben nincs semmilyen releváns infó a rendszerről, csak egy random generált adattal van feltöltve, a payloadja nem is érdekes.
A kliens felöl érkező request headerben található token alapján tudom kikeresni a felhasználót az apin, onnan meg már minden van.
Tehát akkor ha jól értemezem amit írtál, kliens oldalon, ha set-cookie-t látok az api response headerben, akkor az alapján létrehozom a cookiet manuálisan. Majdan a következő requesthez pedig felhasználom...manuálisan...őrület.
A kollegád mit értett az alatt, hogy az angular xsrf csak lokál környezetben megy?...Arra gondolok, hogy ha az angular kliens-t is az API, azaz az expressjs szolgálja ki, pl express static-kal? (ez csak egy tipp...)...mondjuk ezt nehezen képzelném el..
Meg picit pislogok is most, hogy ha nekem kell implementálnom....oké, hát legyen....
az éjjel megpróbáltam kilistázni konzolra az elérhető cookie-kat....
jön a response api felöl...chrome devben network fülön, szépen ott a kilens request, api response, benne headerben set-cookie...és a cookie is látszik, a cookie tab-on...csodás...aztán document.cookie val megpróbáltam hozzáférni, és lássék....mint ahogy egyébként az angular is a document.cookie()-t használja...nem is létezik az a cookie amit keresek.
Létezhet az, hogy a cookiemat a kliens, és itt most a böngészőre gondolok, visszautasítja? mert ha nem utasítja vissza, akkor az applikációban már document.cookieval hozzá kéne férjek...
A kliens requestbe jelenleg nincs Access-Control-Allow-Origin, beletehetem, meglátjuk mi lesz.
- A hozzászóláshoz be kell jelentkezni
Jol ertem, hogy elkuldod a JWT-t a headerben, majd meg egy session cookiet is akarsz valamiert kuldeni?
Miert hasznalsz JWT-t? Miert hasznalsz cookiet? Tudod mi az a CSRF (es miert kell ellene vedekezni, es milyen esetekben lehet kihasznalni)? Ha ezekre tudsz valaszolni, szerintem kozelebb kerulsz a megoldashoz :)
- A hozzászóláshoz be kell jelentkezni
Én is némi keveredést érzek az OP-nál
- A hozzászóláshoz be kell jelentkezni
Hali!
A kollégám, hogy pontosan mire gondolt azt csak tippelni tudom most maximum. Azt mondanám, ez akkor megy gond nélkül ha az api és a kliens is ugyanazon a gépen van hostolva csak eltérő porttal, de hangsúlyozom ez csak tipp.
Amúgy ennek az egész történetnek az lenne a lényege, hogy a man in the middle attackokat lehet ezekkel elkerülni, hogy a szerver és a kliens oldal is tudja hogy honnan jön vagy megy az adat.
Ahogy olvastam az általad fejlesztett authentikációt érdemes lenne átgondolni a konvencióknak megfelelően.
Ezt érdemes elolvasni
A cookie visszautasítós kérdésedre visszatérve, szerintem azért nem látod mert másik originből jön a response, mint ahol a kliens alkalmazásod van.
Abban az esetben ha a responseban látod hogy ott még meg van akkor egy http interceptorral meg tudod oldani hogy te magad mented el.
- A hozzászóláshoz be kell jelentkezni
Kedves Soyer, és Mico!
Kérnélek benneteket, hogy akkor tegyétek rendbe a keveredést, hogy megértsem, hol van valójában...
Tudomásom szerint, illetve mire használom...
A JWT-t arra, hogy be tudjam azonosítani a felhasználókat a login után, és el tudja dönteni az API, hogy kinek milyen engedélye van, vagy az API kinek mire, és milyen módon válaszoljon.
A tokenhez meg társítok az API-n egy session szerűséget, azaz az adatbásiban elmentem, a felhasználót, a kiadott tokent, a user-agent-et, stb, amit csak tudok...és minden szükséges esetben amikor kérés jön az API-hoz...ez alapján egy csomó ellenőrzést el tudok végezni. Pl user-agent..ami nyilván nem világmegváltó védelem, de pont egyel több mintha nem ellenőrizném az egyezőségét.
CORS..tudomásom szerint ezzel tudom szabályozni, hogy az adott origin requestjét elfogadom, vagy élből elutasítom...
A CSRF-fel meg kezdek gondban lenni...mert mindenki mást ír róla, hogy mire jó vagy nem jó..
Nekem eddig az csapódott le belőle, hogy a POST requesteket lehet vele biztonságosabbá tenni, meg magát az egész api-kliens kommunikációt.
penztar:
Invalid domain miatt utasítódik el a cookie..és sose fogok hozzáférni, mert maga a böngésző dobja el, így az Angularig el sem jut...tehát jelenleg az biztos probléma, hogy külön aldomain a kliens, és az api..jelen pillanatnyi tudásom szerint itt tartok :) Aztán hogy ezt valami beállítással lehet orvosolni-e vagy sem, azt még nem tudom.
- A hozzászóláshoz be kell jelentkezni
Szia!
Talán segítenek az alábbiak:
Cookie:
- set cookie-nál tegyél egy pontot a domain elejére, így a cookie elérhető lesz az aldomaineken is: ".domain.tld"
- ne felejtsd el mindig megadni a path-t is: "/", különben mindig ahhoz az oldalhoz fog tartozni a cookie, ahol éppen létrehozod
- ha https-t használsz, front és backend oldalon is secure = true legyen
- a cookie azért "jó", mert mindig automatikusan utazik a böngésző és a backend között, még API lekérés esetén is ha létrehozol a nodejs-ben egy megfelelő cookie-t, el fogod érni a front oldali angularban
- amennyiban a weboldalad egy SPA (Single Page Application), akkor nem is szükséges cookie, mert minden esetben tudod küldeni a header-ben a JWT tokent (amit a localStorage-ban tárolsz sikeres bejelentkezés után)
CSRF:
- ez akkor szükséges, ha olyan publikus form-ot használsz, ami nincs védve pl. reCaptcha-val
- ha az összes API végpontod csak hiteles authentikáció után érhető el, mert JWT tokent validálsz a backend-en
akkor nincs szükséged CSRF-re
CSP (Content Security Policy):
- ha növelni akarod a front oldal védelmét, akkor érdemes CSP-t is beállítani az nginx-ben
Remélem tudtam segíteni.
Üdv!
- A hozzászóláshoz be kell jelentkezni
Kedves rascy!
Köszönöm hogy rendbe tetted a dolgot!
az elmúlt 2 napban rengeteget olvastam még utánna a témának, és igen, valójában nem is szükséges a CSRF jelenleg.
A rendszerben összesen 2 olyan POST van, ami nem követel meg előzetes authentikációt, de ezek védve vannak recaptchával.
Így átmentetileg fel is függesztem a CSRF beállítását.
Mindenkinek köszönöm a válaszokat!
- A hozzászóláshoz be kell jelentkezni