Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
Geen idee wat 'mt_rand' precies gebruikt. Maar puur statistisch klopt het ook gewoon dat we collisions krijgen, het is hetzelfde als dat er maar een heel klein aantal mensen nodig is om er twee te hebben die op dezelfde dag jarig zijn..oisyn schreef op woensdag 17 juni 2009 @ 12:57:
Wat is de bron van je RNG? Of gebruik je daarvoor iets als /dev/random?
[edit]
Blijkbaar klopt het niet helemaal meer wat ik stelde. Vroeger kregen we nog wel collisions, toen we minder actief de sessie-ids opruimden en tegelijk blijkbaar een wat minder randomized functie gebruikten om de id's te produceren. Maar zo te zien loggen we die eventuele pk-violations en ik kan me niet herinneren er een in de logs gezien te hebben.
[ Voor 30% gewijzigd door ACM op 17-06-2009 14:15 ]
Maar mijn punt was meer dat, ondanks je 128 bits resultaat, mt_rand niet een voldoende hoge-resolutie seed gebruikt waardoor collisions al veel eerder optreden.
[ Voor 8% gewijzigd door .oisyn op 17-06-2009 14:06 ]
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
Dat zou goed kunnen, zie ook mijn edit. Ik kan me herinneren dat we in de "Topix tijd" wel redelijk vaak meldingen kregen van mensen die een sessie van een ander kregen, maar daar is met React toen met wat fatsoenlijke checks naar gekeken..oisyn schreef op woensdag 17 juni 2009 @ 14:05:
Maar mijn punt was meer dat, ondanks je 128 bits resultaat, mt_rand niet een voldoende hoge-resolutie seed gebruikt waardoor collisions al veel eerder optreden.
En toen we uiteindelijk met de merge onze eigen id's overal gebruikten, hebben we zowel voor de FP als het forum dezelfde, volledig random string ipv iets gebaseerd op "md5(uniqid(mt_rand(), true))" (of vast nog slechter bij Topix). Bovendien ruimen we sessies sindsdien beter op
Waar precies de kans op collisions tot nagenoeg nul is gereduceerd weet ik eigenlijk niet eens zeker
- persoon a krijgt sessie, wordt opgeslagen in db
- na x tijd wordt sessie verwijderd uit db vanwege opschoning
- persoon b krijgt sessie, wordt opgeslagen in db, toevallig hetzelfde als persoon a zn oude sessie
- persoon a komt op site en is ingelogd als persoon b vanwege (extreem?) oude cookie
[ Voor 27% gewijzigd door .oisyn op 17-06-2009 16:34 ]
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
Dan ben je er toch niet? Want de sessionid is een random string en in de DB hou je bij welk userid daarbij hoort. Zou je het kunnen toelichten?.oisyn schreef op woensdag 17 juni 2009 @ 16:32:
user-id of sessie-tijd opnemen in de sessie-id / cookie.
Als je de volgende gegevens in je request meestuurtCartman! schreef op zondag 21 juni 2009 @ 16:20:
[...]
Dan ben je er toch niet? Want de sessionid is een random string en in de DB hou je bij welk userid daarbij hoort. Zou je het kunnen toelichten?
SessionId=Unique ID
UserId = User ID
en in de database staat een ander UserId gekoppeld aan dat session id, dan weet je dus dat het niet klopt, en kun je het SessionId dus niet accepteren. Op die manier kan het niet zo zijn dat iemand per ongeluk inlogt op een ander account
“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”
Ik zie op T.net niet een cookie met userid overigens, hoe wordt dat hier opgelost?
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
Maar zelfs met birthday paradox en een goed gevulde sessietabel mag je enorm je best gaan doen. Er is een zeer kleine slagingskans en je weet bovendien niet of je een interessante gebruiker overneemt - een login bruteforcen zal een vele malen eenvoudiger en lonender aanval zijn.
{signature}
Euhm, birthday paradox is niet van toepassing bij het vinden van een al bestaand sessie-id.Voutloos schreef op dinsdag 23 juni 2009 @ 07:11:
Maar zelfs met birthday paradox en een goed gevulde sessietabel mag je enorm je best gaan doen.
Desalniettemin, sessie-id's zijn vaak niet goed uniform gedistribueerd. Met een id op basis van mt_rand zonder zelf te seeden adhv een fatsoenlijke entropy source ben je sowieso slechts gelimiteerd aan 232 verschillende random sequences. Sterker nog, de default seed in PHP is (volgens mij per request) gebaseerd op de huidige tijd in microseconden en het huidige proces-id. Als je weet in welke minuut iemand zijn sessie heeft gestart hoef je dus in feite maar 216 * 6e7 =~ 1012 verschillende sessies te genereren om een match te vinden. Da's niet heel erg veel.
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
1] Je weet het tijdstip van inloggen wellicht niet.oisyn schreef op dinsdag 23 juni 2009 @ 12:26:
Als je weet in welke minuut iemand zijn sessie heeft gestart hoef je dus in feite maar 216 * 6e7 =~ 1012 verschillende sessies te genereren om een match te vinden. Da's niet heel erg veel.
2] Als client kan je niet zelf het sessie id forceren. Als dat wel kon, had je net zo goed een session fixation attack kunnen doen en veel eerder resultaat boeken.
Je hebt overigens wel gelijk voor wat betreft de seeding in PHP, daar zitten her en der wat rare dingetjes in.
{signature}
Ons id wordt gebaseerd op 32 losse random gegenereerde hex-getallen, dus in principe gewoon een adresruimte van 16^32. Hoe goed php's random-generator daarmee werkt, icm de tijd etc weet ik uiteraard niet. Binnenkort gaan we er weer wat aan veranderen, dus ik gok dat we dan de adresruimte ook gelijk maar wat oprekken, naar bijvoorbeeld base64 ipv hex..oisyn schreef op dinsdag 23 juni 2009 @ 12:26:
Desalniettemin, sessie-id's zijn vaak niet goed uniform gedistribueerd. Met een id op basis van mt_rand zonder zelf te seeden adhv een fatsoenlijke entropy source ben je sowieso slechts gelimiteerd aan 232 verschillende random sequences. Sterker nog, de default seed in PHP is (volgens mij per request) gebaseerd op de huidige tijd in microseconden en het huidige proces-id. Als je weet in welke minuut iemand zijn sessie heeft gestart hoef je dus in feite maar 216 * 6e7 =~ 1012 verschillende sessies te genereren om een match te vinden. Da's niet heel erg veel.
Overigens heeft men blijkbaar wat aan de seeding aangepast, maar of er dan ook veel gewijzigd is tov jouw brute-force voorstel is natuurlijk maar de vraag:
Since 5.2.1 The Mersenne Twister implementation in PHP now uses a new seeding algorithm by Richard Wagner. Identical seeds no longer produce the same sequence of values they did in previous versions. This behavior is not expected to change again, but it is considered unsafe to rely upon it nonetheless.
[ Voor 3% gewijzigd door ACM op 23-06-2009 12:59 ]
“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”
Duh, ik zei ook als je het weet, het was een voorbeeld waarbij ik liet zien dat het systeem zwaar compromised is als je het wél weetVoutloos schreef op dinsdag 23 juni 2009 @ 12:52:
[...]
1] Je weet het tijdstip van inloggen wellicht niet

Waar heb je dat voor nodig dan? Je kunt als client wel proberen in te loggen met een geforceerd sessie-id. Als dat sessie-id bestaat, dan log je dus in onder een andere user. Ik snap niet waarom je zelf een sessie zou willen starten met een geforceerd sessie-id eigenlijk...2] Als client kan je niet zelf het se ssie id forceren.
Onjuist. Met een vaste seed krijg je een vaste sequence van waarden. Dus al genereer je sessie-ids van 10100 digits, als de seed maar 4 bits is heb je in totaal 16 verschillende sequences en hoeft een attacker dus ook maar max 16 verschillende sequences te proberen voor hij een match heeft gevonden (vooropgesteld dat hij het algo kent natuurlijk!). Sowieso is de parameter voor mt_srand() van het type int, dus je kunt met mt_srand() alleen nooit meer dan 232 verschillende sequences genereren. Wat je natuurlijk wel kunt doen is op basis van een goede entropy source een hele hoop bits van mt_rand() discarden, zodat je sequence niet afhangt van de seed alleen.ACM schreef op dinsdag 23 juni 2009 @ 12:57:
[...]
Ons id wordt gebaseerd op 32 losse random gegenereerde hex-getallen, dus in principe gewoon een adresruimte van 16^32
Dat heeft alleen te maken met het seeding algoritme zelf, dus hoe de MT wordt geïnitialiseerd adhv een bepaalde seed (bijvoorbeeld door te zorgen voor een betere uniforme distributie). Het zegt compleet niets over de daadwerkelijke seed zelf waarmee PHP de eerste keer mt_srand() aanroept. Mijn claim in mijn vorige post is gebaseerd op de 5.2.9 sourcecodeOverigens heeft mijn blijkbaar wat aan de seeding aangepast
[ Voor 4% gewijzigd door .oisyn op 23-06-2009 13:24 ]
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
Ach, je komt natuurlijk een heel eind met educated guesses in sommige gevallen. Echt heel praktisch zal de aanval nou ook weer niet zijn..oisyn schreef op dinsdag 23 juni 2009 @ 13:07:
Duh, ik zei ook als je het weet, het was een voorbeeld waarbij ik liet zien dat het systeem zwaar compromised is als je het wél weet
Hmm, nooit bij stil gestaan... Ik heb nu op mijn testsysteem een versie gemaakt die gebruik maakt van de linux systeem random generator, /dev/urandom, die zou het dan toch weer een stuk lastiger moeten maken om de boel te voorspellen en de kans op dubbelen, ook in het geval van verwijderde id's, nog weer een stuk kleiner moeten maken.Onjuist. Met een vaste seed krijg je een vaste sequence van waarden. Dus al genereer je sessie-ids van 10100 digits, als de seed maar 4 bits is heb je in totaal 16 verschillende sequences en hoeft een attacker dus ook maar max 16 verschillende sequences te proberen voor hij een match heeft gevonden (vooropgesteld dat hij het algo kent natuurlijk!). Sowieso is de parameter voor mt_srand() van het type int, dus je kunt met mt_srand() alleen nooit meer dan 232 verschillende sequences genereren. Wat je natuurlijk wel kunt doen is op basis van een goede entropy source een hele hoop bits van mt_rand() discarden, zodat je sequence niet afhangt van de seed alleen.
Tenzij ik het natuurlijk weer helemaal mis heb
* ACM heeft de indruk dat we een beetje afgedwaald zijn hier.
Daarmee ga je er direct vanuit dat sessie-id niet gekoppeld is aan bepaalde user kenmerken. Een check op IP adres is bijvoorbeeld extreem simpel en dan heb je al nagenoeg niets meer aan dat hele sessie-ID (tenzij je beide via dezelfde proxy inlogt, maar ok). Ben het met je eens dat het colission-wise niet optimaal is, maar daar houdt het ook wel mee op.oisyn schreef op dinsdag 23 juni 2009 @ 13:07:
Als dat sessie-id bestaat, dan log je dus in onder een andere user.
Een langdurige sessie koppelen aan een ip vind ik persoonlijk erg ruk, zeker als je ip niet vast is. Daarom selecteer ik die optie op t.net ook vrijwel nooit als ik in moet loggen (is alleen aangevinkt op m'n thuis-desktop en werk-desktop)
[ Voor 80% gewijzigd door .oisyn op 23-06-2009 23:32 ]
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
Is dat niet voor "multi-server" omgevingen om zo makkelijk load-balanced sessies te gebruiken enzo? En daar zijn toch ook wel weer manieren op te vinden om "dicht" te timmeren. Koppel zo'n sessie meteen na login aan IP en een cookie ofzo en je bent al een heel eind.Zoijar schreef op woensdag 24 juni 2009 @ 10:12:
Nog iets over session collisions. Ik heb een tijd geleden naar ASP.NET gekeken en IIS, en het blijkt dat daar standaard een optie aanstaat waar session-ids worden overgenomen als je ze meestuurt. Onbegrijplijk. Wat je daar dus kan doen is een link posten naar een site met een sessie-id erin, wachten tot er iemand die link volgt en inlogt, en dan zelf naar die site gaan op dat id.
There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.
Je eigen tweaker.me redirect
Over mij
Maar dan is het wel gek dat dat het default behavior is, uit veiligheids overwegingen zou je het standaard niet willen, als je er bewust voor kiest dan moet je er inderdaad maar maatregelen voor nemen.RobIII schreef op woensdag 24 juni 2009 @ 10:37:
[...]
Is dat niet voor "multi-server" omgevingen om zo makkelijk load-balanced sessies te gebruiken enzo? En daar zijn toch ook wel weer manieren op te vinden om "dicht" te timmeren. Koppel zo'n sessie meteen na login aan IP en een cookie ofzo en je bent al een heel eind.
“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”
Verkeerde oplossing.RobIII schreef op woensdag 24 juni 2009 @ 10:37:
Koppel zo'n sessie meteen na login aan IP en een cookie ofzo en je bent al een heel eind.
De echte oplossing tegen session fixation is het opnieuw genereren van een session key op kritieke punten (inloggen/uitloggen bijv.). Dan kan je nooit de session key van een later in te loggen sessie van tevoren weten.
{signature}
Weet je misschien ook nog waar je dat gelezen hebt? Niet dat ik je niet geloof, maar standaard aan zou ik echt heel vreemd vinden.Zoijar schreef op woensdag 24 juni 2009 @ 10:12:
Nog iets over session collisions. Ik heb een tijd geleden naar ASP.NET gekeken en IIS, en het blijkt dat daar standaard een optie aanstaat waar session-ids worden overgenomen als je ze meestuurt. Onbegrijplijk. Wat je daar dus kan doen is een link posten naar een site met een sessie-id erin, wachten tot er iemand die link volgt en inlogt, en dan zelf naar die site gaan op dat id.
Never attribute to malice that which can be adequately explained by stupidity. - Robert J. Hanlon
60% of the time, it works all the time. - Brian Fantana
Uiteraard; ik bedoelde alleen dat ik me er wel wat bij voor kan stellen dat er ondersteuning voor aanwezig is. Dat het vreemd is dat het default behaviour is (als dat zo is) en sowieso wat ranzige mogelijkheden biedt staat buiten kijf.Voutloos schreef op woensdag 24 juni 2009 @ 10:49:
[...]
Verkeerde oplossing.
De echte oplossing tegen session fixation is het opnieuw genereren van een session key op kritieke punten (inloggen/uitloggen bijv.). Dan kan je nooit de session key van een later in te loggen sessie van tevoren weten.
There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.
Je eigen tweaker.me redirect
Over mij
Ik zie nu dit voor cookieless sessions. Met cookies werkt het anders, maar als je die uitzet in je browser heb je weer kans dat hij toch terug valt op cookieless.
Dit is ook wel interessant: How and why session IDs are reused in ASP.NETRegenerating Expired Session Identifiers
By default, the session ID values that are used in cookieless sessions are recycled. That is, if a request is made with a session ID that has expired, a new session is started by using the SessionID value that is supplied with the request. This can result in a session unintentionally being shared when a link that contains a cookieless SessionID value is used by multiple browsers. (This can occur if the link is passed through a search engine, through an e-mail message, or through another program.) You can reduce the chance of session data being shared by configuring the application not to recycle session identifiers. To do this, set the regenerateExpiredSessionId attribute of the sessionState configuration element to true. This generates a new session ID when a cookieless session request is made with an expired session ID.
source
[ Voor 9% gewijzigd door Zoijar op 24-06-2009 12:18 ]
Is dat niet cookieless sessions (of dat de echte naam is weet ik niet) dit kon volgens mij je in de config van een asp.net applicatie instellen. Dan staat er in je URL een sessie key.Cloud schreef op woensdag 24 juni 2009 @ 10:53:
[...]
Weet je misschien ook nog waar je dat gelezen hebt? Niet dat ik je niet geloof, maar standaard aan zou ik echt heel vreemd vinden.
Naast het feit dat het lelijk is kan het dus ook gevaarlijk zijn. Maar voor zover ik weet is een asp.net sessie gebaseerd op een session op de server. Aan de hand van je cookie of url wordt die sessie aan jouw request gehangen. Ik neem aan dat het wel afgeschermd zal zijn op de een of ander manier, maar zeker weten doe ik dat niet.
[ Voor 9% gewijzigd door .Gertjan. op 24-06-2009 12:10 ]
The #1 programmer excuse for legitimately slacking off: "My code's compiling"
Firesphere: Sommige mensen verdienen gewoon een High Five. In the Face. With a chair.
Het probleem zit hem dus niet in het feit dat de SessionId in de url zit ( al maakt dat het wel makkelijker om per ongeluk je session weg te geven ), maar in het feit dat als je een niet bestaand ( of expired wat in princiepe hetzelfde is ) SessionId meegeeft, dat hij dan gewoon een Session start met dat ID..Gertjan. schreef op woensdag 24 juni 2009 @ 12:09:
[...]
Is dat niet cookieless sessions (of dat de echte naam is weet ik niet) dit kon volgens mij je in de config van een asp.net applicatie instellen. Dan staat er in je URL een sessie key.
Naast het feit dat het lelijk is kan het dus ook gevaarlijk zijn. Maar voor zover ik weet is een asp.net sessie gebaseerd op een session op de server. Aan de hand van je cookie of url wordt die sessie aan jouw request gehangen. Ik neem aan dat het wel afgeschermd zal zijn op de een of ander manier, maar zeker weten doe ik dat niet.
Als iemand dus een linkje op zijn site zet van http://mijndomein.nl/MijnFakeSessionID/ en iemand volgt die, dan weet degene die de link geplaatst heeft het session id van de persoon die op de link geklikt heeft, en kan die dus ook overnemen
“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”
Nou is het wel wat lastiger om een cookie van te voren te maken en de gebruiker zover te krijgen dat hij dat cookie gebruikt; met een link is dat veel makkelijker. Het is echter niet ondenkbaar dat er malware bestaat die voor alle belangrijke domeinen asp.net session id cookies plaatst met een bekend id. Maar toegegeven, dan is het systeem al lek, dat is niet echt de schuld van asp.net. Is hier een andere attack mee te bedenken?When you abandon a session, the session ID cookie is not removed from the browser of the user. Therefore, as soon as the session has been abandoned, any new requests to the same application will use the same session ID but will have a new session state instance. At the same time, if the user opens another application within the same DNS domain, the user will not lose their session state after the Abandon method is called from one application.
Ik snap wat je bedoelt, maar het leek mij dat de sessie tegen meer dingen wordt gechecked, zoals bijvoorbeeld de browser waarmee je inlogt ofzo? Maar nu ik er over na denk, als ik mijn persoonlijke folder van Firefox overzet naar een andere PC heb ik ook mijn cookies (waardoor ik bijvoorbeeld meteen op tweakers ben ingelogd). Dus eigenlijk is sessie sowieso al een gevaarlijk verhaal. Ongeacht of je cookies of url strings gebruikt.Woy schreef op woensdag 24 juni 2009 @ 12:21:
[...]
Het probleem zit hem dus niet in het feit dat de SessionId in de url zit ( al maakt dat het wel makkelijker om per ongeluk je session weg te geven ), maar in het feit dat als je een niet bestaand ( of expired wat in princiepe hetzelfde is ) SessionId meegeeft, dat hij dan gewoon een Session start met dat ID.
Als iemand dus een linkje op zijn site zet van http://mijndomein.nl/MijnFakeSessionID/ en iemand volgt die, dan weet degene die de link geplaatst heeft het session id van de persoon die op de link geklikt heeft, en kan die dus ook overnemen
Mmm dit is wel een boeiend probleem eigenlijk, sessies zijn dus helemaal nooit veilig...
Hoe moet je dit dan veiliger maken?
The #1 programmer excuse for legitimately slacking off: "My code's compiling"
Firesphere: Sommige mensen verdienen gewoon een High Five. In the Face. With a chair.
Sessies zijn veilig zolang je je SessionId geheim kunt houden. Zo gauw als iemand toegang heeft tot je cookies is je Sessie inderdaad niet veilig meer..Gertjan. schreef op woensdag 24 juni 2009 @ 12:48:
[...]
Ik snap wat je bedoelt, maar het leek mij dat de sessie tegen meer dingen wordt gechecked, zoals bijvoorbeeld de browser waarmee je inlogt ofzo? Maar nu ik er over na denk, als ik mijn persoonlijke folder van Firefox overzet naar een andere PC heb ik ook mijn cookies (waardoor ik bijvoorbeeld meteen op tweakers ben ingelogd). Dus eigenlijk is sessie sowieso al een gevaarlijk verhaal. Ongeacht of je cookies of url strings gebruikt.
Mmm dit is wel een boeiend probleem eigenlijk, sessies zijn dus helemaal nooit veilig...
Hoe moet je dit dan veiliger maken?
“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”
100% veilig krijg je het nooit, omdat in principe een session-id gewoon een wachtwoord is. Als je toegang hebt tot dat wachtwoord heb je ook toegang tot de site..Gertjan. schreef op woensdag 24 juni 2009 @ 12:48:
Hoe moet je dit dan veiliger maken?
Iets wat je kan doen... De cookies encrypt en sign je op de server, dus je kan ook controleren of er niet met je cookies is gerommeld. Het enige wat je dan nog kan doen is zo'n cookie hergebruiken, een replay attack zeg maar. Om dat moeilijker te maken kan je bij elk request een nieuwe session cookie genereren. Je krijgt dan een ketting van bruikbare IDs. Als er een van die IDs in de ketting wordt overgenomen, dan klopt de volgende cookie van de echte gebruiker niet meer. Zodra je detect dat er een session cookie niet klopt, dan beeindig je de complete sessie en invalidate je alle IDs. Een replay attack kan dan nog maar heel kort duren; je moet je aanval uitvoeren tussen de tijd dat een gebruiker twee opvolgende paginas aanroept (en ook net dat session id kapen). Bovendien weet de gebruiker dan dat er iets raars aan de hand is.
Sessies bij elke hit regenereren levert echter gegarandeerd problemen op bij mensen die parallel in meerdere tabjes op je site iets doen, of de back button gebruiken en opnieuw een linkje volgen.
Een ketting van bruikbare IDs gaat niet werken, enkel het laatste ID doet er toe. Hergebruik op wat voor manier dan ook van de eerdere IDs kan niet, want dan heb je een security probleem.
{signature}
Het probleem dat iemand je sessionid weet blijft bestaan nog steeds maar ik zie nog steeds geen methode om dit tegen te gaan.