Heartbleed問題
先週発表されたOpenSSLの脆弱性問題ですが、ここ最近の脆弱性の中で一番深刻なセキュリティホールのようです。ある発表によると深刻度10段階中、11ぐらいとのこと。
SSLは普段意識せず使用していますが、インターネット上の通信を暗号化する際に利用しています。https〜で始まるURLが該当します。
バグ自体は非常に単純な境界チェック漏れ(バッファーオーバフロー)です。
ハートビートリクエストのペイロード長フィールドに実際に送信している値より、大きな値を指定して送信するとペイロード領域を超えたメモリ領域まで読込んで、ハートビートレスポンスとして送り返すというものです。
グーグルのニールさんが発見したそうですが、さすがですね。
シンプルなバグなので、修正もシンプルで私でもよく分かりました。
単純なバグですが、影響の大きさにびっくりです。
実際悪用されても、痕跡は残らないため、どうなるのやら。
見覚えないクレジットカードの請求が来ませんように。。
OpenSSL Security Advisory [07 Apr 2014]
========================================TLS heartbeat read overrun (CVE-2014-0160)
==========================================A missing bounds check in the handling of the TLS heartbeat extension can be
used to reveal up to 64k of memory to a connected client or server.Only 1.0.1 and 1.0.2-beta releases of OpenSSL are affected including
1.0.1f and 1.0.2-beta1.Thanks for Neel Mehta of Google Security for discovering this bug and to
Adam Langleyand Bodo Moeller for
preparing the fix.Affected users should upgrade to OpenSSL 1.0.1g. Users unable to immediately
upgrade can alternatively recompile OpenSSL with -DOPENSSL_NO_HEARTBEATS.1.0.2 will be fixed in 1.0.2-beta2.
修正前のt1_lib.c
2561 /* Read type and payload length first */ 2562 hbtype = *p++; 2563 n2s(p, payload); 2564 pl = p; 2565 2566 if (s->msg_callback) 2567 s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT, 2568 &s->s3->rrec.data[0], s->s3->rrec.length, 2569 s, s->msg_callback_arg); 2570 2571 if (hbtype == TLS1_HB_REQUEST) 2572 { 2573 unsigned char *buffer, *bp; 2574 int r; 2575 2576 /* Allocate memory for the response, size is 1 bytes 2577 * message type, plus 2 bytes payload length, plus 2578 * payload, plus padding 2579 */ 2580 buffer = OPENSSL_malloc(1 + 2 + payload + padding); 2581 bp = buffer; 2582 2583 /* Enter response type, length and copy payload */ 2584 *bp++ = TLS1_HB_RESPONSE; 2585 s2n(payload, bp); 2586 memcpy(bp, pl, payload);
修正後のt1_lib.c
2596 /* Read type and payload length first */ 2597 if (1 + 2 + 16 > s->s3->rrec.length) 2598 return 0; /* silently discard */ 2599 hbtype = *p++; 2600 n2s(p, payload); 2601 if (1 + 2 + payload + 16 > s->s3->rrec.length) 2602 return 0; /* silently discard per RFC 6520 sec. 4 */ 2603 pl = p; 2604 2605 if (hbtype == TLS1_HB_REQUEST) 2606 { 2607 unsigned char *buffer, *bp; 2608 int r; 2609 2610 /* Allocate memory for the response, size is 1 bytes 2611 * message type, plus 2 bytes payload length, plus 2612 * payload, plus padding 2613 */ 2614 buffer = OPENSSL_malloc(1 + 2 + payload + padding); 2615 bp = buffer; 2616 2617 /* Enter response type, length and copy payload */ 2618 *bp++ = TLS1_HB_RESPONSE; 2619 s2n(payload, bp); 2620 memcpy(bp, pl, payload);