Att gråta eller skratta, det är frågan

Just nu cirkulerar referenser till CakePHP unserialize sårbarheten i många forum. Det hyllas lite ironiskt som ett hysteriskt #FAIL eftersom man har sårbarheten i en anti-XSRF-biljett, dvs sårbarheten ligger i en säkerhetsmekanism. Men varför har man över huvudtaget serialiserad data i biljetten?

Jag har haft den här debatten med diverse java-utvecklare flera gånger. Även långt innan Java deserialization exploitet. Det som är så skrämmande är att flera är så fast i fint pattern tänk och njuter av de korta vinsterna med fula genvägar att tydligen all rim och reson lämnat dem. Det är så komplett djäkla fel på det mind-set folk har när de tänker ”jag tar mitt program minne här, och så öser jag in gud vet vad från nätverket in i mitt program, och så kommer allt gå bra”.

Att använda serialisering för temporär datasparning, där datat automatiskt tas bort vid t.ex. omstart, är i vissa specialfall okej.

Viss typ av kortlivad kommunikation där du kan till 100% garantera att ingen ”elak” person kommunicerar kanske också är nästan okej. Finns bara jehovas vittnen på ditt nätverk så kanske det har något hopp för sig.

Att göra det på permanent datalagring (jepp – det förekommer!) är att skjuta sig själv i foten med älgstudsare – du har nu bland annat försatt dig i versionshanteringshelvete som förmodligen kommer förstöra produktiviten och skapa buggar i många år framöver.

Att använda serialisering för kommunikation med externa partner är en katastrof av guds nåde. Behöver man egentligen förklara? Är inte detta en uppenbar naturlag? Dels har du problemen du hade med persistent lagring. Men så har du massvis med roliga säkerhetshål också.

  • Säkerhetshål 1: Deserialisering är en komplex process. Genom att deserialisera öppnar du för attacker mot deserialisering-koden.
  • Säkerhetshål 2: Det finns förmodligen objekt som kan representera bilder, komprimerad data med mera, som kanske kör native-kod. Genom att deserialisera har du potentiellt exponerat dig mot lib-buggar i t.ex. libz eller exif-biblioteken.
  • Säkerhetshål 3: Många java-programmerare förstår inte vad en konstruktor är för något och hur de skall användas. Det är mycket sannolikt att det som finns i din JVM innehåller klasser som börjar exekvera kod om objekt av den klasstypen skickas upp.
  • Säkerhetshål 4: OutOfMemoryError / StackOverflowException / YouFrakkingNameItException. Här, ta emot den datastrukturen. Va? Råkade det ha oändliga loopar i sig? Vad synd 🙂
  • Säkerhetshål 5: någon fyller ditt Integer-fällt med Integer.MAX_INTEGER. Din for-loop är ägd.
  • osv osv osv osv.

Någon vän av dåliga idéer kanske vill hänvisa till att köra alternativa ramverk som Hessian. Jag tror inte det väsentligen löser speciellt många av problemen, det är fortfarande en dum idé att lita på serialiserade objekt från nätverk. Vill du hantera data så är det egentligen väldigt enkelt:

  • Innan du använder opålitlig data måste du validera det.
  • Serialisering bygger som idé på att du istället ger datat i det närmaste oändliga frihetsgrader – och dessutom kör det kod, vilken har du ingen som helst aning om, eftersom du inte har översikt över objektrymden eller vilka libbar som är inbland.
  • Jämför serialisering med normal nätverksspecifikation: det är helt uppenbart att detta är två helt olika världar. Att försöka använda serialisering som ett nätverksprotokoll borde få dig att instinktivt känna oro, illamående, rädsla, misstänksamhet. Gör det inte det, så är något mycket fel.
  • Jämför serialisering med imunförsvaret: du har ingen som helst kontroll på vad du får i dig, och sannolikt har du inte ens kod för att utvärdera det du fick in i efterhand. Någon räcker fram en macka med mystiska krälande radioaktiva larver, och du äter det utan att bry dig om vad du får för något.

Med risk för att vara lite väl elak: den dagen någon föreslår serialsering som en lösning på ett problem, så är det dags att undra om personen avser att skämta eller fråga om han missförstått problemet.

Om man skall vara realist – jag tror de flesta utvecklare faktiskt förstod att de gjorde ett fel när de valde serialisering som nätverksprotokoll eller persistent lagring. Förutom några få personer som snurrat helt bortanför kontakt med jorden, så är det nog uppenbart för de flesta att man bygger in en enorm teknisk skuld och massvis med problem.

Förklaringen är nog enkel: det var väldigt bråttom, och det var snabbaste sättet att snabbt nå resultat. Om produkten/projektet aldrig blir en framgång, så behöver man ju inte ens leva med synden. Någon kanske till och med är så cynisk att den tänker när problemen börjar hopa sig, så är den förmodligen på en helt annan position eller arbetsplats, och inte behöver ta ansvar.

Lämna en kommentar