{"id":41,"date":"2026-04-19T18:00:00","date_gmt":"2026-04-19T16:00:00","guid":{"rendered":"https:\/\/airex.se\/blogg\/identitetsforvaxling-oauth\/"},"modified":"2026-04-19T18:00:00","modified_gmt":"2026-04-19T16:00:00","slug":"identitetsforvaxling-oauth","status":"publish","type":"post","link":"https:\/\/airex.se\/blogg\/identitetsforvaxling-oauth\/","title":{"rendered":"Han loggade in med sitt konto och landade p\u00e5 n\u00e5gon annans"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">En anv\u00e4ndare loggade in p\u00e5 en tj\u00e4nst jag driver, med sitt eget konto, och landade p\u00e5 n\u00e5gon annans.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Inte en felaktig namnvisning. Han s\u00e5g den andra personens sida, den andras uppgifter, den andras projekt. Rapporten kom som ett meddelande p\u00e5 en minut: &#8221;loggar in med mitt konto men hamnar hos n\u00e5gon annan&#8221;.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Det tog tio minuter att hitta orsaken, tre till att \u00e5tg\u00e4rda den, och resten av dagen att sluta m\u00e5 illa. Det h\u00e4r \u00e4r vad som hade h\u00e4nt.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Tv\u00e5 register \u00f6ver samma m\u00e4nniskor<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Tj\u00e4nsten hade vuxit fram i tv\u00e5 omg\u00e5ngar och sl\u00e4pade p\u00e5 en historisk skavank: <strong>anv\u00e4ndarna fanns i tv\u00e5 separata databaser.<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Inloggningsfl\u00f6det skrev till den ena. De inloggade sidorna l\u00e4ste fr\u00e5n den andra. Kopplingen dem emellan var ett l\u00f6pnummer \u2014 och ingen hade n\u00e5gonsin sagt \u00e5t de tv\u00e5 databaserna att dela numrering.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">S\u00e5 l\u00e4nge samma personer skapades i samma ordning i b\u00e5da register r\u00e5kade numren st\u00e4mma \u00f6verens. Systemet fungerade perfekt i m\u00e5nader, av ren tur.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u00d6gonblicket d\u00e5 turen tog slut<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">En ny anv\u00e4ndare registrerade sig. Hon hamnade i det ena registret men inte i det andra. Fr\u00e5n och med den sekunden var numreringen f\u00f6rskjuten med ett steg.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">N\u00e4sta person som loggade in fick en session m\u00e4rkt med sitt nummer ur det ena registret. Sidorna slog upp det numret i det andra registret \u2014 och fick fram en helt annan m\u00e4nniska.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Det som g\u00f6r det obehagligt \u00e4r att <em>varje enskilt steg var korrekt<\/em>. Inloggningen verifierade r\u00e4tt person mot r\u00e4tt leverant\u00f6r. Sessionen skapades korrekt. Uppslaget gjordes korrekt. Felet fanns bara i antagandet att tv\u00e5 nummer fr\u00e5n tv\u00e5 oberoende k\u00e4llor betydde samma sak.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ingen data l\u00e4ckte i praktiken \u2014 de ber\u00f6rda kontona var i stort sett tomma. Men det var tur, inte konstruktion, och tur \u00e4r inte en s\u00e4kerhetsmodell.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u00c5tg\u00e4rden, och en stunds f\u00f6rnedring<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Fixen var att sluta anv\u00e4nda ett internt l\u00f6pnummer som brygga mellan systemen och i st\u00e4llet knyta sessionen till en identitet som betyder samma sak i b\u00e5da \u2014 och sedan ogiltigf\u00f6rklara samtliga aktiva sessioner, eftersom vilken som helst av dem kunde peka fel.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Tv\u00e5 minuter efter att r\u00e4ttningen g\u00e5tt live kraschade inloggningen med ett nytt fel: en variabel som bytt namn i st\u00e4dningen och som jag missat p\u00e5 ett st\u00e4lle. Ytterligare en r\u00e4ttning, ytterligare en drifts\u00e4ttning, och sedan fungerade fl\u00f6det.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Den detaljen tar jag med av en anledning: <strong>br\u00e5ttom-r\u00e4ttningar har en egen felfrekvens.<\/strong> Jag stod inf\u00f6r valet att l\u00e5ta ett identitetsfel ligga kvar i tio minuter till f\u00f6r att hinna granska ordentligt, eller att st\u00e4nga h\u00e5let direkt och riskera f\u00f6ljdfel. Jag valde det senare och skulle v\u00e4lja det igen \u2014 men man ska veta att man valt.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">S\u00e5 vet du att du inte har samma fel<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>R\u00e4kna dina anv\u00e4ndarregister.<\/strong> \u00c4r svaret fler \u00e4n ett har du det h\u00e4r felet latent, oavsett hur s\u00e4ker du \u00e4r p\u00e5 att de h\u00e5lls i synk.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Fr\u00e5ga vad sessionen egentligen pekar p\u00e5.<\/strong> Ett internt l\u00f6pnummer \u00e4r ingen identitet \u2014 det \u00e4r en position i en tabell. Identiteten ska vara n\u00e5got som betyder samma sak \u00f6verallt.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Testa med tv\u00e5 konton samtidigt<\/strong>, i tv\u00e5 webbl\u00e4sare, efter att en tredje anv\u00e4ndare skapats. Det \u00e4r precis det scenariot som avsl\u00f6jar f\u00f6rskjutningen, och precis det man aldrig testar.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Vad jag tar med mig<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Det farligaste felet \u00e4r inte det som kraschar. Det \u00e4r det som fungerar l\u00e4nge, av en slump, och slutar fungera vid en h\u00e4ndelse som ingen kopplar till felet \u2014 h\u00e4r: att en ny anv\u00e4ndare registrerade sig.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Och det som g\u00e4ller alla system jag byggt det h\u00e4r \u00e5ret: <strong>identitet t\u00e5l inte tv\u00e5 sanningar.<\/strong> Inventarium t\u00e5l det inte, n\u00e4tverkskonfiguration t\u00e5l det inte, och anv\u00e4ndare allra minst \u2014 f\u00f6r d\u00e4r heter konsekvensen inte avdrift utan att n\u00e5gon ser n\u00e5gon annans uppgifter.<\/p>\n\n","protected":false},"excerpt":{"rendered":"<p>Varje enskilt steg var korrekt. Felet fanns i antagandet att tv\u00e5 l\u00f6pnummer fr\u00e5n tv\u00e5 oberoende register betydde samma person \u2014 och det h\u00f6ll i m\u00e5nader, av ren tur.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[],"class_list":["post-41","post","type-post","status-publish","format-standard","hentry","category-nat-och-sakerhet"],"_links":{"self":[{"href":"https:\/\/airex.se\/blogg\/wp-json\/wp\/v2\/posts\/41","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/airex.se\/blogg\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/airex.se\/blogg\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/airex.se\/blogg\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/airex.se\/blogg\/wp-json\/wp\/v2\/comments?post=41"}],"version-history":[{"count":0,"href":"https:\/\/airex.se\/blogg\/wp-json\/wp\/v2\/posts\/41\/revisions"}],"wp:attachment":[{"href":"https:\/\/airex.se\/blogg\/wp-json\/wp\/v2\/media?parent=41"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/airex.se\/blogg\/wp-json\/wp\/v2\/categories?post=41"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/airex.se\/blogg\/wp-json\/wp\/v2\/tags?post=41"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}