Incorrect order of network connection operations

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

Описание

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

Риск

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

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

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

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

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

  • Для серверного сокета, ориентированного на подключение (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
Влияние: Средний
ИДЕНТИФИКАТОР CWE: 666
Введенный в R2015b