Az Apple ma kiadott iOS frissítésében (7.0.6, 6.1.6) egy különösen veszélyes problémát javított a készülékekkel szállított SSL könyvtárban. Úgy tűnik, Stefan Essernek sikerült megtalálnia a problémát okozó kódrészletet, amivel az Apple előkelő pozícióra tett szert a hülye hibák ranglistáján:
static OSStatus
SSLVerifySignedServerKeyExchange(SSLContext *ctx, bool isRsa, SSLBuffer signedParams,
uint8_t *signature, UInt16 signatureLen)
{
// ...
if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0)
goto fail;
goto fail;
if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0)
goto fail;err = sslRawVerify(ctx,
ctx->peerPubKey,
dataToSign, /* plaintext */
dataToSignLen, /* plaintext length */
signature,
signatureLen);
// ...fail:
SSLFreeBuffer(&signedHashes);
SSLFreeBuffer(&hashCtx);
return err;}
Amint látjátok, egy feltehetően véletlenül becsúszott(?) sorduplikáció azt eredményezi, hogy a kód hibaágra fut még az SSL tanúsítvány tényleges ellenőrzése előtt, ami nem lenne akkora baj, ha a függvény visszaadott hibakódja nem jelezne sikert (err=0, nincs hiba). Így a hibás implementáció gyakorlatilag bármilyen tanúsítványt elfogad. (Komolyan érdekelne, hogy egy ilyen problémára miért nincs legalább egy unit teszt az Apple-nél...)
A durva az, hogy a Register szerint a probléma az OS X 10.9.1-et is érinti, javítás azonban egyelőre csak a 10.9.2 bétájában áll rendelkezésre (vagy talán ott sem). Szintén kellemetlen helyzetben vannak a jailbreakerek, akik számára egyelőre nem áll rendelkezésre a frissített verziókra szánt evasi0n.
Friss: Kutyacica tesztjei szerint a probléma legalább 2013 márciusa óta fenn áll. Ez azt jelenti, hogy az Apple megvalósítását használó SSL kliensek (pl. Safari) már legalább egy éve nem voltak megbízhatók.
Friss2: A legfontosabb információk, az eszközök tesztelésére használható tesztek, illetve linkek a nem hivatalos patchekhez a gotofail.com-on vannak összegyűjtve.
hillaby · http://twitter.com/hillaby 2014.02.23. 12:31:41
Gerilgfx 2014.02.23. 14:06:32
NagySzellem 2014.02.23. 16:17:45
hillaby · http://twitter.com/hillaby 2014.02.23. 19:31:28
www.opensource.apple.com/source/OpenSSL/OpenSSL-38/openssl/crypto/pkcs7/pk7_doit.c
NagySzellem 2014.02.23. 20:22:40
Eric csak írni szeret kódot, olvasni nem.
Ez a disassembler programok szintje.
buherator · http://buhera.blog.hu 2014.02.23. 20:55:01
A beágyzott xkcd strip szerintem jól rávilágít a probléma lényegére. És ezen az sem változtat, hogy a goto elterjedt (vö. "egyél szart, 100 milliárd légy nem tévedhet").
Emellett persze más szempontok (indent, zárójelezés, hibakezelési minta,...) is felhozhatók a problémával kapcsolatban (avandeursen.com/2014/02/22/gotofail-security/), de ennél egyértelműbb példát a goto ellen csak nagy kínlódás árán tudnék felhozni.
hillaby · http://twitter.com/hillaby 2014.02.23. 21:19:59
goto nélkül ugyanez a függvény:
- vagy tele lenne ismétlődő
SSLFreeBuffer(&signedHashes);
SSLFreeBuffer(&hashCtx);
return err;
blokkokkal
- vagy az egyre növekvő indentálás miatt kimászna jobbra a képernyőből
Ha pedig felbontjuk függvényekre (amit ilyenkor javasolni szoktak), akkor csomó, csak egy helyről meghívódó függvényt gyártottunk, feleslegesen.
Egyik sem túl jó, persze a goto sem. Ez van, ha C-ben programozunk.
hillaby · http://twitter.com/hillaby 2014.02.23. 21:38:57
dailyvicodin 2014.02.23. 23:36:50
Drout 2014.02.24. 18:06:59
domi007 2014.02.24. 21:37:04
www.imperialviolet.org/2014/02/22/applebug.html
Tegnap IRCn kicsit körbejártuk a goto-t is, és végül is a konszenzus az volt, hogy nem feltétlenül bűn itt használni amíg megmarad az ilyen goto fail szinten és nem burjánzik tovább.
theshadow · http://hackstock.blog.hu/ 2014.02.26. 12:52:03
SSLVerifySignedServerKeyExchange(SSLContext *ctx, bool isRsa, SSLBuffer signedParams,
uint8_t *signature, UInt16 signatureLen)
{
// ...
if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) == 0 &&
(err = SSLHashSHA1.final(&hashCtx, &hashOut)) == 0)
{
err = sslRawVerify(ctx,
ctx->peerPubKey,
dataToSign, /* plaintext */
dataToSignLen, /* plaintext length */
signature,
signatureLen);
// ...
}
SSLFreeBuffer(&signedHashes);
SSLFreeBuffer(&hashCtx);
return err;
}
Problem? (Esetleg blog.hu elrontja a formázást.)
bagoj ur 2014.02.26. 13:12:09
hillaby · http://twitter.com/hillaby 2014.02.28. 09:01:06
err = func1();
if (err == 0) {
err = func2();
}
if (err == 0) {
err = func3();
}
if (err == 0) {
err = func4();
}
return err;