måndag 27 april 2009

Vitlistor och policies mot XSS

Computer Swedens Jenny Stadigs intervjuade mig förra veckan efter forskningsseminariet i Tyskland. Artikeln publicerades idag under rubriken "Inför vitlistning på webben".

För er som är intresserade av lite kringläsning rekommenderar jag följande:

BEEP, Browser-Enforced Embedded Policies, (AT&T Research och University of Maryland)
Servern skickar med en policy för vilka skript som får köras i sidan

ECMAscript, det officiella JavaScript/JScript
Edition 5 (tidigare 3.1) har precis kommit i "final draft"
Edition 6 "Harmony" är framtiden

FBJS, Facebook JavaScript
Facebooks dialekt av JavaScript som hindrar att inbäddade skript körs automatiskt

Caja
Googles dialekt av JavaScript som gömmer känsliga data och funktioner

torsdag 23 april 2009

CSSLP-uppsats 3: Secure Software Implementation/Coding

Här kommer min tredje uppsats för CSSLP-certifieringen. Ämnesområdet är Secure Software Implementation/Coding. Mer specifikt om buffer overflow.


The devil is in the details – an idiom suitable for secure coding. To build a secure system it doesn’t suffice with a good design. Many notorious security problems are coding errors such as a buffer overflow, a format string bug or a double free. To write secure code a developer needs to know how security attacks against these bugs work.

We will here briefly explain what a buffer overflow is and how an attack works.

The Basic Problem
The underlying reason that intrusions ”executing arbitrary code” are possible is that computers are general machines built to execute the instructions in memory whether these instructions do good or bad. An attacker’s goal is often to inject his/her own code and redirect the execution flow to the attack code instead of the original code. These kinds of attacks are known as code injection attacks.

Overflowing a Buffer
Simple, linear sets of data are called arrays or buffers. They are allocated as continuous chunks of memory and allow for quick access and insertion of data. The boundaries of such memory buffers need to be enforced by either the operating environment such as a virtual machine or the application itself.

Applications written in Java or C# get the boundary checks for free from the virtual machine but applications written in C or C++ have to check buffer boundaries themselves. This means that the application developer for instance has to write code to check that data copied into a buffer actually fits in the buffer. If he or she forgets about this a buffer overflow is possible. Such overflows where data spills over into adjacent memory often cause application crashes.

A Buffer Overflow Attack
If the application user can affect the data being copied into an overflowable buffer he or she might be able to design the data to manipulate the execution flow. The execution can be redirected to any available code in memory, possibly injected code of the attacker’s choice.

The two basic requirements for a buffer overflow attack are:
  1. Possibility to inject attack code or attack parameters
  2. Possibility to overwrite a code pointer
The first requirement is covered if there is an overflowable buffer. If the attacker wants to inject code the memory segment that holds the buffer needs to be executable. If the attacker instead injects parameters to a loaded function, e.g. the parameter ”/bin/sh” to the library function system(), the buffer memory doesn’t need to be executable.

Overwriting a code pointer means changing a memory value that points to code that is to be executed. Examples of such code pointers are the return address, function pointers, longjump buffers, and global offset table entries. The code pointer can either be overwritten directly through the buffer overflow or indirectly via a general pointer.

For further information on attacks and effective countermeasures we’d like to refer to our paper "A Comparison of Publicly Available Tools for Dynamic Buffer Overflow Prevention" [1].


References
[1] J. Wilander and M. Kamkar. A Comparison of Publicly Available Tools for Dynamic Buffer Overflow Prevention. In Proceedings of the 10th Network and Distributed System Security Symposium (NDSS'03), in San Diego, California. Pages 149--162, February 5-7, 2003.

Submitted by John Wilander (john.wilander@omegapoint.se) in partial fulfillment of the CSSLP experience assessment requirements.

tisdag 14 april 2009

Inbjudan seminariekväll om kodanalys och -granskning

Så kommer då äntligen inbjudan till vår seminariekväll om kodanalys och -granskning. Tisdag 28/4 på Clarion Hotel Stockholm vid Skanstull. Gratis för våra medlemmar (gå med på mejlinglistan bara)!

Eventet sponsras av Fortify som bjudit hit David Anumudu för att presentera och dema deras verktygssvit för säkerhetsanalys. Därtill kommer James Dickson från Simovits Consulting och berättar om sin erfarenhet av kodgranskning.

Agenda
17.30 Förfriskningar och mingel
18.00 Fredrik Möller, Fortify: Intro och Fortifys engagemang i OWASP
18.10 David Anumudu, Fortify: Presentation + demo av Fortify Solution (eng)
19.20 Paus
19.40 James Dickson, Simovits Consulting: "Code review ur ett säkerhetsperspektiv"
20.30 Seminariet slut -- eftersnack i baren
22.00 Gå hem?

Anmäl er senast torsdag 23/4 till mig via e-post (john.wilander alfakrull omegapoint punkt se). De två senaste seminariekvällarna har varit fullbokade så vila inte på send-knappen för länge.

Varmt välkomna!

tisdag 7 april 2009

Säker utveckling i din organisation?

Ägnade lite lunchtid åt att lyssna på en podcast om att rulla ut säker systemutveckling i sin organisation. Det är en bekant på Carnegie-Mellon University som intervjuas - Robert Seacord.

Är statisk kodanalys lösningen?
Robert tycker att verktyg som analyserar källkoden har sin plats men tenderar att få för mycket fokus i organisationen. Det största problemet är att analysverktygen sällan integreras i utvecklarnas vardag. Istället körs de emellanåt och felrapporterna läggs in i ett ärendehanteringssystem för att en bra bit senare landa i utvecklarnas knä. Då får utvecklaren hela kostnaden av att sätta sig in i koden igen och man odlar ett penetrate-and-patch-beteende. Bättre då att få förståelse för säker utveckling och integrera det i det dagliga kodandet:

"... when they're initially writing it, they understand the context in which the code's being written, they understand the complexities of the software. And that's the time to get it right."

Finns det något att göra åt språk som C?
Roberts grupp är engagerade i C1X, den nya C-standarden. De skriver på ett appendix kring säkerhet i C. Efter en del power-search på nätet hittade jag en pdf från 23/2 i år som beskriver deras arbete.

Deras huvudspår är att göra säkerhetsfunktioner valbara i kompilatorn och på så sätt nå samma säkerhetsnivå som Java, rent språkmässigt.

"... if these changes are made through the standards process and in specific implementations such as GCC and Visual Studio and so forth, all that's required then is that source code is recompiled. And development organizations will automatically pick up a lot of protections that are currently lacking in existing applications."

För egen del anser jag att ett av de största (säkerhets-)problemen i C är den manuella minneshanteringen och det kan man ju inte lösa med en ny kompilator. Å andra sidan kommer man nog långt på att rensa upp i pekararitmetiken och multipla anrop till free().

Säkerhet eller prestanda?
Att skriva säker kod tar i många fall (inte alla) längre tid än att skriva osäker kod. Och att följa upp varningar från kompilatorn eller något analysverktyg tar också tid. Därtill har man tiden det faktiskt tar att analysera koden.

Men om koden dessutom blir långsammare pga inkompilerade säkerhetskontroller så börjar det blir problematiskt. Robert har diskuterat med Microsoft där man är på gång att stänga av vissa default-inställningar i kompilatorn som syftar till högre säkerhet. Varför? Jo, de har fått en 200-300 % prestandaförsämring.

Här måste vi så klart hitta en balans.

"... part of this is coming up with solutions that have adequate performance and not trying to force overbearing solutions on developers. But part of this has to be developers being willing to accept some performance hit in order to drive down the number of vulnerabilities that they're deploying in their software."

Hela podcasten är 20 minuter -- lyssna här (mp3)
Det finns också en transkribering -- läs här (pdf)

lördag 4 april 2009

Dagstuhl-seminariet slut


Volta-texten nedan var min sista bloggpost från Dagstuhl-veckan. Jag hade inte tid att sammanfatta fredagens seminarier förrän idag eftersom jag ville göra det mesta av de sista diskussionerna igår.

Hela veckan har varit superintressant och det har verkligen varit en förmån att få vara med. Deltagarna hade en grym koll på hur alla delar av tekniken funkar både när det gäller funktioner, attacker och skydd. Hade man en idé eller fundering kunde man få feedback inom några sekunder. Folk övertygade mig också att jag måste publicera min buffer overflow-testbädd så jag har lovat dem att fixa det inom en månad.

Men nu ska jag vila lite och sen tillbaka till mina konsultprojekt och planeringen av våra seminarier inom OWASP Sweden. Vi ses!

Från web 1.0 till web 2.0 automatiskt i .Net

Ben Livshits, Microsoft Research, presenterade deras omtalade projekt Volta. Tyvärr har det uppstått en namnstrid (dammsugarna?) så de fick ta bort projektet från webben. Googla på "volta microsoft" och kolla den cache:ade kopian.

Målet med Volta är att replikera webbappen på serversidan och mha jämförelse kontrollera att klienten funkar som den ska.

Decomposition
Volta tar valfri webbapplikation i .Net och delar upp den i en rik klientdel och en serverdel mha så kallad decomposition. Det innebär en automatisk övergång från servertunga web 1.0 till rika klienter och web 2.0. Volta skapar också en replika av klientdelen som körs på servern. Replikan kör klientkoden i C# istället för JavaScript vilket gör den relativt snabb och minnesnål (strax över en 1 Mb ram per replika).

Hos klienten skickas alla användarhändelser via en webbläsarplugin eller JavaScript-interpretatorn till replikan som körs på servern. Händelser som musklick eller inmatning på klienten kräver bara ca 2-3 bytes data över linan och kan skickas i batchar.

Innan request accepteras och körs så jämförs replikans tillstånd med requestet från klienten. Om någon har injicerat skript eller gjort en CSRF med färdigifyllda formulärfält så kommer jämförelsen inte stämma och attacken stoppas.


Frågor
Distribuerade webbapplikationer och mashups gör förstås den här tekniken svårare att använda. Därtill ger nätets nyckfullhet ytterligare problem eftersom ordningen på request från klienten och klienthändelser till replikan kan skilja sig.

En annan mer grundläggande fråga gällde faran i att låta ett ramverk som Volta dela upp din applikation. Volta har i sig ingen aning om vilken information som är hemlig och vilken som är OK att skicka till klienten. T ex rabattkuponger som ska kollas på servern men som vid en automatisk splitt kan råka hamna på klienten där de avslöjas. Microsofts lösning på det problemet är att granska applikationen antingen manuellt eller med verktyg.

Säker Java med omskrivning och filtrering

En god vän sen en tidigare konferens Martin Johns, Universität Passau, presenterade skydd mot XSS och SQL-injektion genom en preprocessor som skriver om programmet. Allt utvecklat för J2EE-applikationer.

Idén
Forskningsidén utgår från tanken att utvecklaren faktiskt vet att han/hon vill skriva en select-sats eller en eller en HTML-tag utan skript, men att strängbaserad programmering inbjuder till misstag. Det borde helt enkelt vara skillnad på exempelvis nyckelord i SQL och på strängar.

Om vi nu ska skriva om befintlig kod så måste det vara obligatoriskt, inte valfritt. Det räcker som bekant med att man glömmer en XSS-sårbarhet så är man rökt.

Container-klasser och domänspecifika filter
Man vill skapa primitiver eller tokens för måldomänen direkt i språket. Dvs om du utvecklar en databaskoppling så ska nyckelord i SQL betyda något, om du utvecklar en webbtjänst så ska SOAP-elementen betyda något, och om du utvecklar en webbsida så ska HTML-elementen betyda något. Det ska inte bara vara strängar. Det öppnar nämligen upp för manipulation.

Johns och hans projekt utvecklade container-klasser för ett antal känsliga strukturer som ofta hanteras som strängar. Container-klasserna har tokens för måldomänens grammatik. Vid kompilering parse:as strängargument och skrivs om till container-objekt. Dynamiska data i strängarna ändras förstås runtime i container-objekten men filtreras då med filter som definierats för respektive container.

För varje sårbar struktur har de alltså gjort följande:
  1. Identifiera tokens i måldomänens grammatik
  2. Skapa pojo-API för container-klass
  3. Skapa preprocessor som skriver om strängar till containerkod
  4. Skapa domänspecifika filter för dynamiska data
I SQL-fallet blir det i princip prepared statements utan att att de har förberetts av databasen. Dynamiska argument till SQL-satsen filtreras innan de konkateneras i container-objektet.

I HTML-fallet så filtreras all utgående, dynamiskt skapad data för XSS.

Overhead och utstående frågor
Deras experiment visar på en 25 %:ig overhead vilket är väldigt mycket. Martin kunde inte svara på varför men var överraskad själv. De ska arbeta vidare och kanske hittar de någon flaskhals.

Jag frågade om hur många buggar deras kodomkrivning och container-objekt introducerade. De var hyfsat trygga med att de inte ändrade funktionaliteten men hade inte gjort någon särskild analys av det. Deras industripartner krävde att de utvärderade tekniken i ett större jsp-baserat projekt vilket gjorde storskalig testning och analys väldigt svårt.

Sen tog vi upp att det finns många befintliga tekniker som löser problemen. Särskilt i fallet SQL-injektion där både korrekt använda prepared/parameterized statements och ORM-ramverk löser problemet. Och samma indatavalidering som Martins filter kör på dynamiska element i SQL-satserna skulle lösa hela problemet. Martin höll med men poängterade att deras mål var att skapa något som löste flera säkerhetsproblem på samma sätt, inte bara SQL-injektion.