exponenta event banner

Общее имя сертификата сервера не проверено

Злоумышленник может использовать действительный сертификат для олицетворения доверенного узла

Описание

Дефект возникает, когда вы не проверяете общее имя, указанное в сертификате сервера, по доменному имени сервера.

Обычно, когда клиент подключается к серверу, сервер посылает клиенту цифровой сертификат, который идентифицирует сервер как доверенный объект. Сертификат содержит сведения о сервере, включая общее имя сервера. Общее имя соответствует доменному имени сервера, которое сертификат идентифицирует как доверенный объект.

Проверка не вызывает дефектов, если:

  • Контекст SSL передается в качестве аргумента функции, вызывающей SSL_new.

  • Контекст SSL объявляется вне области действия функции, обрабатывающей соединение.

Риск

Злоумышленник может использовать действительный сертификат для олицетворения доверенного узла, в результате чего клиент взаимодействует с ненадежным сервером.

Зафиксировать

Используйте одну из этих функций, чтобы указать имя домена сервера, которое программа проверяет на соответствие общему имени, указанному в сертификате сервера.

  • SSL_set_tlsext_host_name

  • SSL_set1_host

  • SSL_add1_host

Примеры

развернуть все


#include <stdio.h>
#include <stdlib.h>
#include <openssl/ssl.h>

#define fatal_error() exit(-1)

void check_certificate(SSL_CTX* ctx, SSL* ssl)
{
    /* Check for Client authentication error */
    if (!SSL_get_peer_certificate(ssl)) {
        printf("SSL Client Authentication error\n");
        SSL_free(ssl);
        SSL_CTX_free(ctx);
        exit(0);
    }
    /* Check for Client authentication error */
    if (SSL_get_verify_result(ssl) != X509_V_OK) {
        printf("SSL Client Authentication error\n");
        SSL_free(ssl);
        SSL_CTX_free(ctx);
        exit(0);
    }
}

void func()
{
    int ret;
    SSL_CTX* ctx;
    SSL* ssl;

    /* creation context for the SSL protocol */
    ctx = SSL_CTX_new(SSLv23_client_method());
    if (ctx == NULL) fatal_error();

    /* Handle connection */
    ssl = SSL_new(ctx);
    SSL_set_connect_state(ssl);
    check_certificate(ctx, ssl);
    ret = SSL_connect(ssl);
    if (ret <= 0) fatal_error();

    SSL_free(ssl);
    SSL_CTX_free(ctx);
}

В этом примере структура SSL инициируется методом клиентского соединения. Клиент проверяет сертификат сервера с помощью check_certificate. Однако клиент не проверяет, соответствует ли общее имя сертификата доменному имени сервера. Злоумышленник может использовать действительный сертификат для олицетворения доверенного сервера.

Исправление - укажите доменное имя для проверки по общему имени сертификата

Одной из возможных корректировок является использование SSL_set1_host чтобы указать ожидаемое имя домена, которое программа проверяет по общему имени сертификата сервера.


#include <stdio.h>
#include <stdlib.h>
#include <openssl/ssl.h>

#define fatal_error() exit(-1)

void check_certificate(SSL_CTX* ctx, SSL* ssl)
{
    /* Check for Client authentication error */
    if (!SSL_get_peer_certificate(ssl)) {
        printf("SSL Client Authentication error\n");
        SSL_free(ssl);
        SSL_CTX_free(ctx);
        exit(0);
    }
    /* Check for Client authentication error */
    if (SSL_get_verify_result(ssl) != X509_V_OK) {
        printf("SSL Client Authentication error\n");
        SSL_free(ssl);
        SSL_CTX_free(ctx);
        exit(0);
    }
}

void func()
{
    int ret;
    SSL_CTX* ctx;
    SSL* ssl;

    /* creation context for the SSL protocol */
    ctx = SSL_CTX_new(SSLv23_client_method());
    if (ctx == NULL) fatal_error();

    /* Handle connection */
    ssl = SSL_new(ctx);
    SSL_set_connect_state(ssl);
    check_certificate(ctx, ssl);
    ret = SSL_set1_host(ssl, "www.mysite.com");
    if (ret <= 0) fatal_error();
    ret = SSL_connect(ssl);
    if (ret <= 0) fatal_error();

    SSL_free(ssl);
    SSL_CTX_free(ctx);
}
 

Информация о результатах

Группа: Криптография
Язык: C | C++
По умолчанию: Откл.
Синтаксис командной строки: CRYPTO_SSL_HOSTNAME_NOT_CHECKED
Воздействие: среднее
ИДЕНТИФИКАТОР CWE: 297
Представлен в R2020a