onsdag 31 mars 2010

Chrome enda oknäckta webbläsaren

Många av er har säkert följt Twitterströmmen #pwn2own från konferensen CanSecWest 2010. Tävlingssugna hackers hade tre dagar på sig att knäcka de fyra stora webbläsarna Chrome, Firefox, Internet Explorer och Safari (läs mer på DVLabs-bloggen).

Alla webbläsare utom en föll första dagen. Så här utvecklades tävlingen:
  1. Apple Safari 4 på MacOS X Snow Leopard -- knäckt
  2. Apple Safari 4 på MacOS X Snow Leopard -- knäckt igen
  3. Microsoft Internet Explorer 8 på Windows 7 -- knäckt
  4. Microsoft Internet Explorer 8 på Windows 7 -- knäckt igen
  5. Mozilla Firefox 3 på Windows 7 -- knäckt
  • Google Chrome 4 på Windows 7, Vista och XP -- inte knäckt
Som Mac-ägare blir jag förstås lite ledsen. Safari på iPhone var den plattform som hackades först under pwn2own. Och då snackar vi fientlig nedladdning av hela sms-databasen :(. Under tiden släppte Apple en gigantisk säkerhetspatch för 92 säkerhetshål -- 18 i Leopard, 29 i Snow Leopard och 45 i båda. Men Apple har också fått mycket kritik för sitt säkerhetsarbete.

Mer förvånad blir jag att IE8 på Win7 föll tämligen hårt. Och Mozilla som arbetar hårt med säkerhetsfeatures i sin webbläsare. Det blir intressant att se vad IE9 har att komma med och hur mycket av Microsoft Research:s forskning om t ex Gazelle-läsaren kommer att spela in där. Likheter med Chrome finns.

Det intressanta är att inte många försök gjordes att knäcka Chrome trots prispengarna på $10,000 och den enorma prestigen, särskilt efter att alla de andra fallit första dagen. Chrome:s unika arkitektur med separata processer i sandlådor (kolla processlistan när du surfar med flera flikar) lär vara en av orsakerna. Det faktum att konkurrenterna hade lägre hängande frukt en annan.


Fotnot: Det är rätt häftigt att just personerna bakom Chrome:s säkerhet är inbjudna talare på sommarens konferens i Stockholm! Och de ska prata om The Future of Browser Security.

onsdag 24 mars 2010

0day i Safari, iPhone Safari m fl

g.o.a.t.s.e s.e.c.u.r.i.t.y meddelar via ett antal mejlinglistor att man hittat en 0day (opatchad, tidigare okänd sårbarhet) i webkit-baserade webbläsare såsom Apple Safari, iPhone Safari med flera. Google Chrome verkar vara det enda undantaget. Det rör sig om en integer overflow i webbläsarens portfiltrering.

Om man anger adressen www.owasp.se:25 så svarar Safari "Ej tillåtet att använda nätverksport med begränsad behörighet”. Högre portnummer tillåter den dock. Till exempel om man adderar 65536 (65536 + 25 = 65561) så tycker filtret att det är en tillåten port. www.owasp.se:655561 är alltså helt OK för Safari.

Men inne i webbläsaren konverteras portnumret till en unsigned short, dvs ett heltal som max får vara 65535. Vid en sån konvertering så börjar talet om på noll när det blir större än 65535. Alltså blir 65536 = 0, 65537 = 1 ... och 65561 = 25. En video där de visar buggen genom att rikta Safari mot en lokal Netcat på port 25 finns här.

Buggen är inte superallvarlig men kan användas vid avancerad phising där offrets dator eller telefon luras att anropa interna tjänster och fiska ut information såsom lösenord eller skicka spam med den egna mejlservern.

Vill ni läsa hela deras mejl så finns det arkiverat, t ex här.

fredag 19 mars 2010

JSONP -- medveten XSS med risk för CSRF

Same origin policy (SOP) är vid sidan av webbläsarbråket den ständiga utmaningen i modern webbutveckling. Säkerhetsfolket försvarar den med näbbar och klor, svarthattarna letar säkerhetshål i den, och utvecklarna försöker kringå den för att kunna bygga nya tjänster med innehåll från olika källor. SOP är en strikt policy som antingen är på eller av, konfiguration är inte möjlig.

Same origin policy i ett nötskal
I princip säger SOP att webbinnehåll från olika källor inte får läsa eller ändra på varann. I Unix-termer så säger SOP att e(X)ecute är tillåtet men inte (R)ead eller (W)rite. Några exempel är på sin plats.

Antag att du bygger en webbapplikation med innehåll som du hämtar från flera källor, t ex en kombination av information och funktioner från owasp.org, owasp.se och google.com.
  • Innehåll från http://www.owasp.org får inte läsa eller ändra innehåll från http://www.owasp.se eller http://www.google.com pga olika domäner
  • Innehåll från http://www.owasp.org får inte läsa eller ändra innehåll från https://www.owasp.org pga olika protokoll
  • Innehåll från http://www.owasp.org:80 får inte läsa eller ändra innehåll från http://www.owasp.org:8080 pga olika portar (gäller alla webbläsare utom Internet Explorer)
Kringå SOP med hjälp av JSONP
Det finns flera sätt för utvecklare att arbeta sig runt SOP, en bra summering är Solving Cross-Domain Issues When Building Mashups. En populär teknik heter JSON with Padding (JSONP) och kan beskrivas som medveten cross site scripting.

Man utnyttjar det faktum att JavaScript får laddas från valfri källa, dvs SOP gäller inte script-taggen.

<script>Här får du hämta från valfri källa och köra som JavaScript</script>

Om nu källan istället för att bara svara med JSON (JavaScript Object Notation) lägger till ("paddar") utgående data med ett funktionsanrop så kommer det anropet köras.

Hämta vanlig JSON och stoppa in den mellan script-taggarna:
<script type="text/javascript" src="http://owasp.se/statistics/jsonp/chapterMemberCount"></script>
... resulterar i det icke-fungerande skriptet ...
<script>{"count":"384"}</script>

Men att hämta JSONP med parametern 'callback' och stoppa in mellan script-taggarna:
<script type="text/javascript" src="http://owasp.se/statistics/jsonp/chapterMemberCount?jsoncallback=callback"></script>
... resulterar i det fungerande skriptet ...
<script>callback({"count":"384"})<script>

Om du tänder och släcker script-taggen, dvs skriver ut den och tar bort den, så kan du till och med "polla" en tjänst (en ordentlig beskrivning av hur du gör i ren JavaScript finns på Stefan Petterssons blogg).

En JSONP-klient
Så här kan en JSONP-klient byggd med JQuery se ut, i det här fallet en klient som hämtar antalet medlemmar i OWASP Sweden:

<!DOCTYPE html>
<html>
<head>
<title>Medlemmar i OWASP Sweden</title>

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript">

URL_COUNT = 'https://owasp.se/statistics/jsonp/chapterMemberCount?&jsoncallback=?';

$(document).ready(function() {
__$.getJSON(URL_COUNT,
____function(data){
______$('#count').html(data.count);
____}
__);
});

</script>
</head>
<body>
__Totalt antal medlemmar i chaptret: <span id="count"></div>
</body>
</html>

En JSONP-tjänst på servern
På serversidan får man använda något ramverk som stödjer JSONP, t ex JAX-RS Jersey som nedan eller den bundlade JSON-pluginen i Struts 2. Här är serversidans RESTful service för antalet medlemmar:

@DisableXMLHttpRequest
@GET
@Path("/statistics/jsonp/chapterMemberCount")
@Produces( { "application/x-javascript", MediaType.APPLICATION_JSON } )
public JSONWithPadding chapterMemberCountJsonP (
______@Context HttpServletRequest request,
______@QueryParam("jsoncallback") String callback)
{
__return new JSONWithPadding( new
______GenericEntity<Statistic>
________(getStats(request)) { }, callback);
}

Medveten Cross Site Scripting?
Hur var det nu med medveten cross site scripting? Jo, det är ju precis vad JSONP är. Du hämtar data från en annan källa och skriver ut det mellan script-taggar. Med andra ord litar du blint på det skript som kommer tillbaka och det finns inget som hindrar källan att lägga till valfri JavaScript som du gladeligen kommer köra. Men eftersom det liksom ligger i designens natur och syfte kan man inte se det som ett säkerhetshål, snarare en medveten risk. Använd med andra ord bara JSONP när du anser dig kunna lita på källan.

Risk för Cross Site Request Forgery?
Sen var det frågan om cross site request forgery (CSRF). I det scenariot så har attackeraren inkluderat request till JSONP-tjänsten på sin sida och alla offer som surfar in där kommer under ytan utföra requesten med sin session. CSRF-attacker är alltid blinda eftersom svaret från tjänsten kommer till offrets webbläsare och inte till attackeraren. Men med JSONP kan attackeraren "padda" med JavaScript som läcker ut informationen och alltså åstadkomma icke-blind CSRF. Det är ett säkerhetshål om informationen anses känslig! Och det hålet måste i så fall åtgärdas på servern precis som vid vanlig CSRF, dvs med en token som klienten förväntas skicka tillbaka. Det lite otrevliga med det är att din RESTful service inte blir tillståndslös vilket den egentligen ska vara.

@DisableXMLHttpRequest
@GET
@Path("/statistics/jsonp/chapterMemberCount")
@Produces( { "application/x-javascript", MediaType.APPLICATION_JSON } )
public JSONWithPadding chapterMemberCountJsonP (
______@Context HttpServletRequest request,
______@QueryParam("jsoncallback") String callback,
______@QueryParam("token") String antiCsrfToken )
{
__// Check the token
__...
__return new JSONWithPadding(
______new GenericEntity<Statistic>
________(getStats(request)) { }, callback);
}


(Tack Stefan Pettersson, Netlight, för ditt bidrag till det här blogginlägget!)

Säkerhetsguide för Facebook-applikationer

OWASP och Facebook samarbetar kring säkerhet i Facebook-applikationer. En första version av guiden har precis släppts.

Secure Application Development on Facebook:
  • Overview of the Facebook Platform
  • Security Goals
  • Important Rules to Follow
  • Common Vulnerabilities and Protections
Under de olika delkapitlen finns information om hur man hanterar autentisering och SSL och hur man undviker CSRF, XSS, Cross Site Flashing. Dessutom berörs Facebooks JavaScript-dialekt, FBJS, som kommer att finnas med i programmet på en viss konferens i Stockholm i sommar ;).

tisdag 16 mars 2010

JBroFuzz 2.0 släppt

Version 2.0 av OWASP-fuzzern JBroFuzz har precis släppts. Ur listan på nyheter:
  • User basic authentication supported
  • Added Authorization header option in UI, under URL Encoding
  • Implemented a Cross Product Fuzzer within core/CrossProductFuzzer.java
  • Introduced PowerFuzzer.java, DoubleFuzzer.java and fixed the directory location preferences
Och så en massa fixar så klart.

söndag 7 mars 2010

Apache Shiro, alternativ till ESAPI?

Ett nytt Apache-projekt finns nu att beskåda i deras inkubator -- Apache Shiro.

Det ser att bli en konkurrent till OWASP ESAPI. Med andra ord kommer man, som alltid inom Javavärlden, få valmöjligheter och valvåndor.

Stora delar av den riktigt matnyttiga dokumentationen (core) är fortfarande oskriven eller dold bakom inloggning till deras Confluence. Men några kodexempel som ger en känsla för användbarheten kan man hitta. Som ...

if ( !currentUser.isAuthenticated() ) {
__token.setRememberMe(true);
__currentUser.login(token);
}

... och ...

try {
__currentUser.login( token );
} catch ( UnknownAccountException uae ) {
__// Show an error message?
} catch ( IncorrectCredentialsException ice ) {
__// Password didn't match, try again?
} catch ( LockedAccountException lae ) {
__// Account for that username is locked -
__// can't login. Show them a message?
}

Säkpub på fredag

På fredag (12/3, kl 17:30) så är det Säkpub igen i Stockholm. Diverse säkerhetskunnigt och -intresserat folk träffas på Läckerbiten, Skanstull. Vi tar ett par glas, käkar pubmat, beklagar oss över att vi har för mycket att göra och lyssnar på spontana föredrag. Projektor finns så vill du berätta om något är det bara att köra.

Många OWASP:are brukar vara där. Kom du med!