onsdag 16 september 2009

Domändriven säkerhet / Domain-Driven Security

Jag och en kollega på Omegapoint, Dan Bergh Johnsson, har myntat designmetoden Domain-Driven Security (domändriven säkerhet) -- ett arbetssätt i skärningspunkten mellan domändriven design (DDD) och applikationssäkerhet.

Vårt intresse väcktes när Dan höll föredrag om DDD och jag kommenterade dess bärighet på indatavalidering. Sen dess har vi stött och blött olika exempel från verkligheten och inte minst DDD och OWASP topp tio.

Idag lanserar vi begreppet i varsitt blogginlägg med synkroniserade klockor. Läs Dans inlägg här.

Domändriven design
Domändriven design utgår från modellering av den aktuella domänen, dvs värdebärande informationsobjekt och kärnan av domänlogik. Inom sjukvård så är patient, läkemedel och samtycke del av den domänspecifika modellen. Inom e-handel hittar vi modellobjekt som vara, pris och valuta. DDD innebär att mycket tid och kraft läggs på att få domänmodellen rätt och att låta den driva systemutvecklingen.

Indatavalidering
Indatavalidering brukar (i alla fall av mig) kallas applikationssäkerhetens heliga graal. Varhelst applikationen tar emot data -- nätverk, filsystem, omgivningsvariabler, formulär -- så måste dessa data valideras. Attacker tar nämligen samma väg in.

Valideringen ska så långt det är möjligt utgå från positiva modeller, dvs modeller av hur korrekt indata ser ut. Inom säkerhet kallas det vitlistning. Genom att bara acceptera indata som stämmer med den positiva modellen så kommer applikationen automatiskt avvisa felaktig indata.

Domändriven säkerhet
Skärningspunkten mellan domändriven design och applikationssäkerhet handlar för mig mycket om just indatavalidering. De värdebärande objekt som driver applikationens logik måste vara korrekta, dvs ha tillstånd som den övriga applikationen kan lita på.

I konkreta objektorienterade termer innebär det att domänobjekt aldrig ska kunna konstrueras eller populeras med felaktiga data -- objektfabrikerna måste validera indata så att resten av logiken kan förutsätta att konstruerade objekt har kompletta och korrekta tillstånd.

Något nytt under solen?
OK, säger det här oss något nytt? Ja, det finns ett gammalt problem inom just indatavalidering -- var i arkitekturen ska den placeras och hur förhindrar vi att valideringsmodellen blir inkonsistent om den finns i flera lager?
  • Klassisk säkerhet säger att indatavalidering ska ske så tidigt som möjligt, gärna som ett skalskydd i form av brandväggar och applikationsbrandväggar men åtminstone direkt i den kod som tar emot indata, t ex i dina servlets. Problemet med det är att man får en komplex koppling mellan brandväggsregler/protokollparsning och applikationslogik.
  • Databasfolket anser att databasmodellen är sanningen och att det är där datats korrekthet ska avgöras. Problemet med det är databasers undermåliga programmeringsförutsättningar (jämför med en modern IDE) och svårigheten att skriva applikationslogik som felfritt kan hantera elaka indata tills databasen kan validera dem.
  • Säkerhet a la domändriven design anser alltså att indatavalidering ska göras i värdeobjekten, relativt djupt inne i applikationen. Problemen, eller utmaningarna, är att hålla indatalogiken enkel fram till domänobjektens validering och att hålla domänmodell och databasmodell i synk. En stor fördel är att valideringen då fungerar oavsett varifrån data kommer. Om någon lyckats få in skadlig kod i den bakomliggande databasen eller en bakomliggande web service så kommer applikationen klaga på samma sätt som om den skadliga koden kom från ett webbformulär.

2 kommentarer:

Martin Holst Swende sa...

Om jag förstår dig korrekt, vilket inte är helt säkert, så innebär det att datavalideringen sker av Objekt i typiska OO-applikationer. Det kan jag hålla med om - men är inte problemet ofta att OO inte används i tillräcklig utsträckning?

Om fler appar, ex webappar, hade byggts upp med objektmodeller istället för strängkonkatenering hade indatavalidering och korrekt utdata-kodning varit en non-issue...

John Wilander sa...

Ja, antingen validering i objekt eller i objektfabriker som ofta används i DDD.

Och visst är det ett problem att objektorientering och dess naturliga abstraktion och inkapsling inte används tillräckligt. Men minnesregeln att lägga tid på att modellera domänen och att lägga valideringen i värdeobjekten tycker jag känns bra.

En kollega under forskningstiden i Linköping sa en gång bittert: "Allt blir ändå bara strängar till slut". En annan kollega hade undersökt hur många gånger en sifferparameter konverterades mellan sträng/heltal/flyttal i deras administrativa system för offentlig sektor. 32 gånger från skal till datalager om jag minns rätt.