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

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

Описание

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

Риск

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

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

Фиксация

Во время сокетного соединения и коммуникации, проверяйте возврат каждого вызова и длину данных.

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

  • Для сокета сервера с установлением соединения (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++
Значение по умолчанию: 'off'
Синтаксис командной строки: BAD_NETWORK_CONNECT_ORDER
Влияние: носитель
ID CWE: 666

Введенный в R2015b