Fråga:
Varför är det osäkert att lagra sessions-ID i en cookie direkt?
Angular noob
2015-06-21 17:21:25 UTC
view on stackexchange narkive permalink

Jag lär mig om session middleware.

Du har att tillhandahålla en hemlighet eller mellankonverteringen klagar:

  app.use (session ({hemlig : "abc", resave: false, saveUninitialized: false, store: new MongoStore ({mongooseConnection: mongoose.connection})}));  

Jag gjorde en undersökning och det faktiska sessionens ID är

eKeYlF1DR6AtVkeFZK9vEIHSZT8e0jqZ

Men enligt cookien är session-ID

  s% 3AeKeYlF1DR6AtVkeFZK9vEj 

Jag är förvirrad. Varför är det osäkert att lagra session-ID i cookien direkt? Kan jag inte lagra session-ID direkt?

Det ser ut som att hemlighet är en privat nyckel och sessions-ID krypteras?

Som jag förstår det kan angriparen fortfarande kapa sessionen om en angripare kan uppnå denna cookie, kanske via XSS eller social engineering. Jag är inte säker på vad poängen med hemligheten är.

Hej, välkommen till [security.se]. Jag är inte säker på vad som får dig att tro att det alls är osäkert att lagra användarens sessionid i sin cookie (så länge du gör det rätt). Enligt vad jag kan säga fann du att något slumpmässigt js-bibliotek gör något ointuitivt. Det betyder inte att det är osäkert, eller att det är anledningen till det. Du bör inte bli förvånad om det här är en halvbakad idé ...
Hallå. [Jag tror att jag hittade författarens motivering] (https://github.com/expressjs/session/issues/68). Vad tror du @AviD?
"Det verkar som att hemligheten är en privat nyckel och session-ID krypteras?" - troligen inte, med tanke på att det du beskriver som det "faktiska session-ID" visas ordligt i kakan. Det är omedelbart efter "s% 3A", i början.
Tre svar:
AviD
2015-06-21 20:48:08 UTC
view on stackexchange narkive permalink

Författaren till det JS-biblioteket verkar ha gjort ett gemensamt, men ändå felaktigt antagande, dock baserat på tillräckligt med kunskap för att få saker fel.

Du kan inte bara strö magik crypto faeriedamm och förvänta dig att få mer säkerhet, som chokladflis.

Vad författaren saknar är att när du signerar session-id och lägger in det i cookien - är det signerade session-idet sessions-id. Det är bokstavligen identifieraren med vilken slutanvändare kommer att berätta för servern vilken session som tillhör dem. Det spelar ingen roll att servern vill göra en viss intern bearbetning för att associera den faktiska sessionsidentifieraren med den interna representationen av sessionens minne.

För att vara tydlig, om det signerade session-id: t stjäls - på något sätt, antingen via XSS, socialteknik eller något annat - kan angriparen helt enkelt använda det signerade session-idet för att kapa användarsession, intern representation trots.


Som sagt, det finns en nominell fördel med att signera kakavärdet innan det skickas till webbläsaren: upptäckt av manipulering. Det vill säga, efter att ha tagit emot användarens cookie kan webbapplikationen verifiera att kakan inte manipulerades med innan den användes för att slå upp sessionsminnet, nämligen genom att validera signaturen. Detta kan möjligen förhindra vissa avancerade / aktiva attacker på sessionshanteringen, genom att undvika en sessionssökning på ett sessions-ID som aldrig var giltigt.

Den här förmodade fördelen är dock tveksam, eftersom session-id vanligtvis bara är ett id, som används för att slå upp sessionsvariablerna. Även de flesta attacker som riktar sig mot session-id skulle inte stoppas av detta - kapning av sessioner, fixering av sessioner, donation av sessioner, ridning av sessioner osv ...

Hur som helst, om du verkligen vill verifiera att sessionskakan inte har manipulerats innan du använder den, det finns enklare sätt än en digital signatur ...

Vad skulle du föreslå för att undvika manipulation av sessionskakor då?
@gabeio Vilket är hotet du försöker mildra här? En angripare som försöker gissa giltiga sessionids? I så fall är manipulering irrelevant, så länge du inte accepterar ogiltiga ID (även om du kanske vill titta på en viss hastighetsbegränsning). Eller är du orolig för något mer esoteriskt, som SQL-injektion baserat på sessionid? Nåväl bör du förhindra SQLi genom att använda alla rätta begränsningar, och hur som helst sessionid borde bara vara en uppslagning för att hämta sessionsdata (vanligtvis i minnet, även om detta kan vara i något beständigt tillstånd db).
@gabeio Min poäng är att det vanligtvis inte finns något behov av detta, men om du har ett specifikt hot du är orolig för är det det som borde mildras specifikt.
Detta är ett bibliotek, inte ett program som bara handlar om sessionen, butiken ansluter en app till databasen så att butiken måste hantera sqli-begränsning. Det största hotet vid denna punkt för denna modul är manipulering. Hastighetsbegränsning är för utvecklaren att bestämma i huvudapplikationen. Hur är manipulation irrelevant för att blockera gissning av giltiga sessionid? Om de inte känner till signaturen kan de inte ens börja gissa att sessionens ID är att stjäla.
Återigen, om session-id: t är korrekt konstruerat - långt, slumpmässigt, etc - så gissar session-id är irrelevant, och manipuleringsdetektering lägger inte till något signifikant skydd mot detta hot. Jag förstår fortfarande inte varför du är orolig för att manipulera som ett hot - om angriparen manipulerar med sitt sessionid skulle det inte längre vara giltigt ... vilket är precis vad vi vill ha.
Å andra sidan är nackdelen med att bara slänga på någon kryptodamm utan att tänka på sammanhanget och hoten att dessa saker är * känsliga *. Om du kastar på trasig krypto, ovanpå en redan stark sessionid, kan du försvaga den i onödan. (Jag säger inte att bibliotekets krypto är trasig - men jag säger att det är en icke försumbar sannolikhet att det kan vara).
Kom och se biblioteket själv. Det använder ett uid som genereras direkt från node.js kryptobibliotek, bas64'ed för session-id. Signeringen använder node.js kryptobibliotek också för att signera med Hmac-sha256 så om inte node.js kryptobibliotek är trasigt detta bibliotek signerar med node.js kärna. Om node.js kryptobibliotek är trasigt, vänligen meddela dem.
@gabeio 1) Även om jag uppskattar erbjudandet, dess stora uppgift att täcka alla relevanta beroenden och sådant. Så tack, men jag tänker inte granska all relevant kod. 2) Vanligtvis är det inte kryptobiblioteket som går sönder, utan hur det används. 3) HMAC är inte det som vanligtvis kallas "signering", så om devsna är förvirrande mellan känd terminologi, det tvingar bara fram det jag föreslog, chansen att få något fel i implementeringen. 4) allt detta åt sidan, det spelar ingen roll, eftersom vad jag sa fortfarande står: krypto är känslig, kasta inte den kontextlös, om du gör kan du bryta något.
Jag är förvirrad, vad är det för fel? "Användare kan använda vilka session-ID de vill ha. Kanske känner någon att de borde använda ett automatiskt inkrementeringsnummer från SQL-databasen, det spelar ingen roll, för vi skyddar deras oinformerade beslut genom att underteckna värdet och förlänga nyckeln." Låter för mig som om den här funktionen finns för att abstrakt säker säkerhetshantering bort från användaren av biblioteket, för att säkerställa att session-ID: n inte kan förfalskas även om biblioteksanvändaren är oklar och använder en osäker metod för att generera session-id. Verkar rimligt för mig.
@Ajedi32 Det finns inget exakt fel med det om det tas i det begränsade sammanhang du pratar om. Men för mig är det inte det bästa sättet att lita på ett JS-bibliotek för att spara dig från dålig sessionhantering. Det verkar som en ful patch för ett större problem. Oddsen är att din ansökan kommer att använda flera bibliotek som inte gör någon form av sessionssignering. Vad gör man då? Applikationer blir bara större och går vidare till andra människor. Kommer killen som arbetar med den här saken på fem år att förstå vikten av denna patch om din underliggande sessionhantering är osäker?
@SteveSether Nej, som applikationsförfattare är det inte bra att lita på ett bibliotek som detta för säkerhet. Men titta på det från biblioteksförfattarens synvinkel. Detta är ett bibliotek vars syfte är att skicka potentiellt känslig data till en plats utanför servern. Är det bättre praxis att lita på användaren av ditt bibliotek för att få säkerheten rätt eller att göra saker så säkra som möjligt även inför en dåligt skriven applikation?
Eran Hammer
2015-07-09 01:56:45 UTC
view on stackexchange narkive permalink

Ett mer fullständigt svar från http://hueniverse.com/2015/07/08/on-securing-web-session-ids/

Ansvarsfriskrivning: som alla säkerhetsråd från någon som inte känner till detaljerna i ditt eget system, detta är endast för utbildningsändamål. Säkerhet är ett komplext och mycket specifikt område och om du är orolig för säkerheten i ditt system bör du anställa en expert som kan granska ditt system tillsammans med en hotanalys och ge lämplig rådgivning.

Brute Force

Brute force-attacker är de där angriparen försöker få tillgång till systemet genom att göra upprepade förfrågningar med olika referenser (tills en fungerar). Det vanligaste exemplet är en angripare som försöker gissa ett användarlösenord. Det är därför lösenord bör vara långa och undvika att använda ordboksord för att göra det svårare att gissa. Korrekt utformade system håller reda på misslyckade autentiseringsförfrågningar och eskalerar problemet när det verkar som om en attack pågår.

Lösenord är inte den enda referensen som används vid webbautentisering. Den vanligaste implementeringen inkluderar en inloggningssida som vid framgångsrik autentisering sätter en sessionscookie på klienten. Sessionscookien fungerar som bärartoken - den som dyker upp med token anses vara den autentiserade användaren. Att ställa in en sessionskaka tar bort behovet av att ange ditt användarnamn och lösenord på varje sida. Denna session cookie fungerar dock nu som den enda autentiseringsnyckeln och alla som får tillgång till den här nyckeln kommer att få åtkomst till systemet. Cookies är trots allt bara en enkel teckensträng.

Ett session-ID-gissningsattack är en typ av brute force-attack. I stället för att försöka gissa lösenordet försöker angriparen gissa sessionens id och smida autentiseringscookien. Angriparen genererar session-id: n och försöker göra förfrågningar med hjälp av dessa id: er, i hopp om att de kommer att matcha faktiska aktiva sessioner. Till exempel, om ett webbapplikationssession-ID genereras i följd, kan en angripare slå upp sitt eget sessions-id och baserat på smidda förfrågningar med närliggande session-id-värden. För att skydda mot denna attack måste vi göra gissnings-session-ID opraktiskt. Obs! Jag säger "opraktiskt", inte "omöjligt".

Opraktiskhet

Det första steget är att se till att sessions-ID: n är tillräckligt långa och inte sekventiella. Precis som lösenord, ju längre session-id är, desto svårare är det att hitta ett giltigt genom att gissa. Det är också viktigt att session-ID inte genereras med hjälp av en förutsägbar algoritm, såsom en räknare, för om sådan logik existerar, gissar inte angriparen längre utan genererar sessions-ID. Att använda en kryptografiskt säker slumptalsgenerator för att producera tillräckligt långa session-ID är den bästa vanliga praxisen. Vad är "tillräckligt långt"? Det beror på ditt systems natur. Storleken måste översättas till ett opraktiskt försök att gissa ett giltigt session-id.

Ett annat sätt att förhindra att en angripare gissar session-id: n är att bygga integritet i token genom att lägga till en hash eller signatur till sessionskakan. Hur Express-sessionens mittprogram gör detta är genom att beräkna en hash över kombinationen av sessions-id och en hemlighet. Eftersom beräkning av hash kräver hemligheten kan en angripare inte generera giltiga session-ID utan att gissa hemligheten (eller bara försöka gissa hash). Precis som starka slumpmässiga session-id: ar måste hashstorleken matcha säkerhetskraven för den specifika applikationen som den är avsedd att skydda. Detta beror på att sessionskakan i slutet fortfarande bara är en sträng och öppen för gissningsattacker.

Sessions-id: n måste vara tillräckligt långa och opraktiska för att gissa. Det finns några sätt att uppnå detta. Slumpmässigheten och hashteknikerna ovan är de två vanligaste sätten men inte de enda.

Lager

Om vi ​​genererar starka slumpmässiga sessions-ID: ar, behöver vi fortfarande hash? Absolut!

Kärnsäkerhetsprincipen är lager. Detta är också känt som att inte lägga alla dina ägg i en korg. Om du litar på en enda säkerhetskälla får du ingen säkerhet alls om den enda källan misslyckas. Till exempel, om någon hittar ett fel i din slumptalsgenerator? Vad händer om de hittar ett sätt att hacka den delen av ditt system och ersätta det? Det finns otaliga kända attacker som utnyttjar exakt detta - genereringen av slumpmässiga siffror som trots allt inte visar sig vara så slumpmässiga.

Att kombinera ett starkt slumpmässigt session-ID med hash för integritet skyddar mot brister i slumptalsgeneratorn. Det kommer också att skydda mot utvecklarfel som att använda fel funktion för slumptalsgenerator (t.ex. den inte så slumpmässiga metoden som varje system erbjuder tillsammans med den starka metoden). Vi skriver alla dålig kod oavsett hur bra vår process är eller hur erfaren vi är. Det är en del av programvaruteknik. Det är därför det är så viktigt att lagra din säkerhet. En vallgrav räcker inte, du vill också ha en mur bakom den, och förmodligen några vakter bakom muren.

Om du tror att du använder fel slumpmässig funktion eller ett djupt fel i OpenSSL är de enda två frågorna här den vanliga praxis för apa-lappkod i JavaScript och andra dynamiska språk. Om någon någonstans i en hel applikationsdistribution trasslar med de globala slumpmässiga faciliteterna (för testning, loggning, etc.) och bryter den (eller det är en del av en skadlig kodinjektion), är session-id: er som enbart är beroende av slumpmässighet inte längre säkra.

Larm

En viktig skillnad mellan gissningslösenord och gissnings-id: er är att lösenord är associerade med ett konto (t.ex. användarnamn). Kontolösenordsparet gör det lättare att hålla reda på brute force-attacker eftersom det ger ett relativt enkelt sätt att hålla reda på misslyckade försök. Men när det gäller session-ID är det inte så enkelt eftersom sessioner löper ut och inte inkluderar ett kontokontext. Det betyder att ett ogiltigt session-ID kan komma från en utgången session eller från en angripare, men utan ytterligare data (t.ex. IP-adress) skulle det vara svårt att se skillnaden i ett storskaligt system.

Genom att inkludera en integritetskomponent i sessionens id (via en hash eller signatur) kan servern omedelbart se skillnaden mellan en utgången session, en otilldelad session-id och en ogiltig session. Även om du bara loggar in ogiltiga autentiseringsförsök (och det borde du göra) vill du logga en utgången session annorlunda än en ogiltig. Förutom säkerhetsvärdet av att känna till skillnaden, kommer det också att ge användbar inblick i hur dina användare beter sig.

Hygien

Inloggningsuppgifterna ska upphöra och därför ska sessions-ID ha en begränsad livslängd (där varaktighet är mycket ett systemspecifikt värde). Medan cookies har en utgångspolicy finns det inget sätt att säkerställa att de faktiskt följs. En angripare kan ställa in kakans utgång till något värde utan att servern kan upptäcka det. En vanlig bästa praxis är att inkludera en tidsstämpel i varje utfärdad referens, vilket kan vara så enkelt som att lägga till ett tidsstämpelsuffix i det slumpmässigt genererade session-id. För att förlita oss på den här tidsstämpeln måste vi kunna verifiera att den inte har tempererats och sättet att åstadkomma är med en hash eller signatur.

Om du lägger till en tidsstämpel till sessionens id kan server för att snabbt hantera utgångna sessioner utan att behöva göra en dyr databasuppsökning. Även om detta kanske låter oberoende av säkerhet, är det faktiskt väldigt viktigt för att upprätthålla en säker applikation. att konsumera för mycket resurser på servern och antingen stänga av den eller göra den otillgänglig för andra. Om varje begäranverifiering kräver en fullständig databasuppslagning i applikationsnivån, kan en angripare använda förfalskade sessions-ID för att enkelt göra en DoS-attack. Genom att inkludera en integritetskomponent i kakan kan servern omedelbart identifiera förfalskade eller upphörda autentiseringsuppgifter utan någon sökningskostnad för backend.

Kill Switch

Ibland går det fel. Och när de går väldigt fel måste du ha ett sätt att omedelbart ogiltigförklara hela klasser av sessioner. Eftersom att generera en hash eller signatur kräver en hemlighet eller nyckel på serversidan kommer alla session-id: er att omedelbart ersätta hemligheten att valideringen misslyckas. Genom att använda olika hemligheter för olika typer av sessions-ID kan hela klasser av sessioner separeras och hanteras. Utan en sådan mekanism måste själva applikationen fatta ett beräknat beslut om tillståndet för varje session eller utföra massdatabasuppdateringar.

Dessutom i stora distribuerade system med databasreplikering över olika geografiska platser, ogiltigt sessionsposten på en plats kan ta sekunder och till och med minuter att replikera. Det betyder att sessionen förblir aktiv tills hela systemet är synkroniserat igen. Jämfört med ett självbeskrivande och självvaliderande session-ID är fördelarna uppenbara.

Allmänt syfte

En viktig egenskap hos Express-sessionens mellanprogram är dess stöd för användargenererad session id. Detta gör det möjligt för utvecklare att distribuera mellanvaran i en befintlig miljö där sessions-ID skapas av en befintlig enhet som kan finnas på en helt annan plattform. Utan att lägga till en hash till användar-tillhandahållna session-id: er, flyttas bördan med att bygga ett säkert system från experten (modulförfattaren) till användaren (vilket sannolikt kommer att vara en säkerhetsnybörjare). Att använda en hash är ett mycket bättre tillvägagångssätt än att tvinga en intern session-ID-generator.

Krokodiler

Att lägga till en hash till ett starkt slumpmässigt session-ID är inte allt du borde göra. Om din vallgrav kan dra nytta av krokodiler är återigen ett slottsspecifikt beslut. Utan att gå för långt från ämnet finns det många andra lager som du kan lägga till i ditt sessionhanteringsnivå. Du kan till exempel använda två sessioners referenser, en långlivad (varar så länge som sessionen) och en annan kortlivad (bra i minuter eller timmar). För att uppdatera den kortlivade använder du den långlivade men genom att göra det minskar du exponeringen för den långlivade referensen i nätverket (särskilt när du inte använder TLS).

En annan vanlig praxis är att ha en cookie med allmän information om användaren (t.ex. förnamn, nyligen visade objekt etc.) vid sidan av sessionen och för att sedan inkludera något från den cookien i hash för att skapa en bindning mellan användarens aktiva tillstånd till autentiseringen. Det är ett sätt att få tillbaka "användarnamnet" i arbetsflödet.

För att gå ännu längre kan hashing ersättas med signaturer och cookieinnehåll kan krypteras (och sedan hashas eller signeras ovanpå). Säkerhetsnivån måste matcha hotet.

Jag tror att du har baserat ditt avsnitt "lager" på felaktiga antaganden. Att hasa ett slumpmässigt nummer är faktiskt inte ett ytterligare "säkerhetslager" och mer av en svagaste länk. Om basen av CSPRNG går sönder kommer inga mängder hashing att förbättra dess resultat (alltid utvärdera degenererade fall för intuitioner; säg att en PRNG har 0,99 sannolikhet att mata ut bit 1, du bör snabbt komma till en annan slutsats). Att säga "absolut gör alltid hash" låter lite som säkerhetsteater IMHO, och det kan leda till en falsk känsla av säkerhet, vilket utan tvekan är värre än ingen säkerhet.
Vad är några exempel på klasser av sessioner för Kill Switch?
Ajedi32
2015-06-22 22:59:14 UTC
view on stackexchange narkive permalink

Eran Hammer, en av underhållarna av yar session management module för NodeJS, hade detta att säga i frågan:

Ansvarsfriskrivning: som alla säkerhetsråd från någon som inte känner till specifikationerna för ditt eget system, är detta endast för utbildningsändamål. Säkerhet är ett komplext och mycket specifikt område och om du är orolig för säkerheten i ditt system bör du anställa en expert som kan granska ditt system längs dess hotanalys och ge lämplig rådgivning.

[...] Att underteckna en bärartoken för intern integritet och validering är vanlig säkerhetspraxis. Även om jag inte anser att det är tillräckligt med expressionssessionen är det absolut det minsta som krävs.

Du vill inte att folk ska kunna gissa en session för att få tillgång till någon annans konto. [...] Att förhindra att gissa ett session-id genom att inkludera [sic] en kryptografisk komponent [sic] är rätt sätt att uppnå detta. Det är branschstandarden.

Sessionscookies är bärartoken vilket betyder att den som har dem kan få full åtkomst som rättmätig ägare. Du vill kunna göra några saker för att minska risken. Att se till att ingen annan än servern kan utfärda giltiga referenser är det minsta och det är vad som görs i express-session.

Jag anser inte att en enkel signatur är tillräckligt skydd för hantering av sändning, varför detta modul [yar] använder järn -kodning som både krypterar innehållet och signerar det för integritetsvalidering. Detta gör det praktiskt taget omöjligt för någon att temperera med staten (såväl som ger möjlighet att bibehålla ett visst tillstånd i kakan själv), men ännu viktigare, det gör att du kan ange ett utgångsdatum för referenser.

Medan cookies kommer med utgångsinstruktioner, en angripare är inte skyldig att lyda. Detta innebär att om någon stjäl en kaka, om det inte finns något sätt att tvinga den kakan att vara kortlivad, kommer den att lämna systemet exponerat under lång tid. Att hålla kakans utgångsstrategi synkroniserad med serversidespolicyn är ett annat komplexitetsskikt och ett som inte bör ingå i systemets säkerhetsprofil.

Det finns många andra attackvektorer här att tänka på. Till exempel, om varje förfrågan utlöser en lagringssökning för sessionen, blir det enklare att DOS inom giltiga session-id: n. Om du har ett snabbt sätt att upptäcka att en förfrågan kommer från en angripare kan du båda blockera den men också vidta åtgärder för att bekämpa den. En ogiltig cookiesignatur kan bara komma från en skadlig källa (såvida du inte har ändrat dem som du genererar kakor i vilket fall du vet det och kan hantera det).

På samma sätt, att kunna berätta när ett session-id är smiddvs. utgången är avgörande för att upprätthålla ett säkert system. Om du bara genererar slumpmässiga id: er, förutsatt att de är tillräckligt långa och tillräckligt slumpmässiga, har du inget sätt att veta om du inte håller reda på varje session-ID som någonsin genererats vilket skulle göra skalning av ditt system dyrt och smärtsamt. Och det borde vara ganska uppenbart att berätta varför du vill veta om en dålig cookiebegäran inte kommer från en angripare.

(Visa fullständig kommentar)

Så, i princip, medan lagring av ett slumpmässigt session-ID i en cookie direkt inte nödvändigtvis är osäkert (så länge som ID är oförutsägbart och tillräckligt långt), erbjuder kryptering och signering av sessionsinformationen ett antal ytterligare funktioner (som förmågan att lagra utgångsinformation i själva kakan och förmågan att identifiera försök att skapa ett sessions-ID) som kan användas för att förbättra säkerheten.

I synnerhet för expressjs tillhandahåller nuvarande underhållare också följande motivering:

Användare kan använda vilka session-ID de vill ha. Kanske någon tycker att de ska använda ett automatiskt inkrementeringsnummer från SQLdatabasen, det spelar ingen roll, för vi skyddar deras oinformerade beslut genom att signera värdet, förlänga nyckeln.

Med andra ord skyddar signering av session-ID användare av biblioteket som kan (felaktigt) använda förutsägbara eller otillräckligt långa session-ID i sina applikationer (istället för att låta biblioteket hantera generering av sessions-ID: n). Uppenbarligen är denna anledning inte tillämplig om användaren använder säkert valda session-ID: n, men detta bibliotek valde att inte göra det antagandet.

Hammer upprepar denna punkt:

Detta är också en generisk modul förutsatt att det är kärnkravet inom ett stort antal användare. Det måste absolut anta att vissa människor kommer att använda det dåligt (t.ex. öka ID) och tillgodose det. Detta är också vanligt när man bygger moduler för en bred publik.



Denna fråga och svar översattes automatiskt från det engelska språket.Det ursprungliga innehållet finns tillgängligt på stackexchange, vilket vi tackar för cc by-sa 3.0-licensen som det distribueras under.
Loading...