メインコンテンツ

ネットワーク接続操作の順序が正しくありません

接続手順の順序が誤っているか手順が抜けているためソケットが正しく確立できない

説明

この欠陥は、ネットワーク接続上の操作が接続ライフサイクルの不適切な時点で実行された場合に発生します。

リスク

データの送受信先のソケットの接続が正しくないと、予期しない動作や機密情報の開示の原因となることがあります。

ソケットを正しく接続しない場合や接続を誤って変更した場合、予想とは異なるポートに機密データが送信される可能性があります。また、正しくないソケットから予期しないデータを取得することもあります。

修正方法

ソケット接続中および通信中に、各呼び出しの戻り値とデータ長をチェックします。

情報の読み取り、書き込み、送信または受信の前に、ソケットを次の順序で作成します。

  • 接続指向サーバー ソケット (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);
    }
}

この例では、接続指向ネットワーク接続を作成します。この関数は、socketbindlistenaccept という正しい関数を正しい順序で呼び出しています。しかしプログラムは、ソケット listenfd ではなくソケット connfd に書き込みを行う必要があります。

修正 — 安全なソケットを使用

1 つの修正方法として、ソケット listenfd ではなく関数 connfd に書き込みを行います。

# 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
影響度: Medium

バージョン履歴

R2015b で導入