exponenta event banner

Неправильный порядок операций сетевого подключения

Не удалось правильно установить сокет из-за неправильного порядка шагов подключения или отсутствия шагов

Описание

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

Риск

Отправка или получение данных на неправильно подключенный сокет может привести к непредвиденному поведению или раскрытию конфиденциальной информации.

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

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

Во время подключения сокета и связи проверьте возврат каждого вызова и длину данных.

Прежде чем читать, писать, отправлять или получать информацию, создайте сокеты в следующем порядке:

  • Для серверного сокета, ориентированного на подключение (SOCK_STREAM или SOCK_SEQPACKET):

    socket(...);
    bind(...);
    listen(...);
    accept(...);
  • Для серверного сокета без подключения (SOCK_DGRAM):

    socket(...);
    bind(...);
    
  • Для клиентского сокета (ориентированного на подключение или без подключения):

    socket(...);
    connect(...);

Примеры

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

# include <stdio.h>
# include <string.h>
# include <time.h> 
# include <arpa/inet.h>
# include <unistd.h>

enum { BUF_SIZE=1025 };

volatile int rd;

int stream_socket_server(int argc, char *argv[])
{
    int listenfd = 0, connfd = 0;
    struct sockaddr_in serv_addr; 
     
    char sendBuff[BUF_SIZE];
    time_t ticks; 
    struct tm * timeinfo;

    listenfd = socket(AF_INET, SOCK_STREAM, 0);
    memset(&serv_addr, 48, sizeof(serv_addr));
    memset(sendBuff, 48, sizeof(sendBuff)); 
    
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    serv_addr.sin_port = htons(5000); 
    
    bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); 
    
    listen(listenfd, 10); 
    
    while(1)
    {
        connfd = accept(listenfd, (struct sockaddr*)NULL, NULL); 
        
        ticks = time(NULL);
        timeinfo = localtime(&ticks);
        strftime (sendBuff,BUF_SIZE,"%I:%M%p.",timeinfo);
     
        write(listenfd, sendBuff, strlen(sendBuff));
        
        close(connfd);
        sleep(1);
    }
}

В этом примере создается сетевое соединение, ориентированное на соединение. Функция вызывает правильные функции в правильном порядке: socket, bind, listen, accept. Тем не менее, программа должна написать в connfd вместо разъема listenfd розетка.

Исправление - использовать безопасный разъем

Одной из возможных корректировок является запись в connfd вместо функции listenfd розетка.

# include <stdio.h>
# include <string.h>
# include <time.h> 
# include <arpa/inet.h>
# include <unistd.h>

enum { BUF_SIZE=1025 };

volatile int rd;

int stream_socket_server_good(int argc, char *argv[])
{
    int listenfd = 0, connfd = 0;
    struct sockaddr_in serv_addr; 
    
    char sendBuff[BUF_SIZE];
    time_t ticks; 
    struct tm * timeinfo;

    listenfd = socket(AF_INET, SOCK_STREAM, 0);
    memset(&serv_addr, 48, sizeof(serv_addr));
    memset(sendBuff, 48, sizeof(sendBuff)); 
    
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    serv_addr.sin_port = htons(5000); 
    
    bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
    listen(listenfd, 10); 
    
    while(1)
    {
        connfd = accept(listenfd, (struct sockaddr*)NULL, NULL); 
        ticks = time(NULL);
        timeinfo = localtime(&ticks);
        strftime (sendBuff,BUF_SIZE,"%I:%M%p.",timeinfo);
        write(connfd, sendBuff, strlen(sendBuff));
        close(connfd);
        sleep(1);
    }
}

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

Группа: Безопасность
Язык: C | C++
По умолчанию: Откл.
Синтаксис командной строки: BAD_NETWORK_CONNECT_ORDER
Воздействие: среднее
ИДЕНТИФИКАТОР CWE: 666
Представлен в R2015b