メインコンテンツ

安全でない標準関数

セキュリティ関連用には安全でない関数

説明

この欠陥は、安全でなく、セキュリティ関連のプログラミングに使用してはならない標準関数を使用した場合に発生します。関数は、多くの理由によって安全でなくなります。一部の関数は、再呼び出し不可能であるため安全ではありません。他の関数は、ターゲットやプラットフォームによって動作が変わるため、一部の実装が安全ではなくなります。

リスク

一部の安全でない関数は、再呼び出し可能ではありません。これは、呼び出し中に関数の内容がロックされないということです。そのため、攻撃者は途中で値を変更できます。

特に getlogin は、実装次第で安全でなくなります。getlogin の実装には、ログイン名の最初の 8 文字だけが返される場合があります。攻撃者は、最初の 8 文字が同じ別のログインを使用して侵入し、プログラムを操作できます。

修正方法

安全でない関数は、セキュリティ関連では使用しないようにします。安全でない関数を回避できない場合は、その関数のより安全なバージョンを代わりに使用します。getlogin に対しては、getlogin_r を使用します。

すべて展開する

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>
#include <string.h>
#include <stdlib.h>


volatile int rd = 1;

int login_name_check(char *user)
{
    int r = -2;
    char *name = getlogin();
    if (name != NULL)
    {
        if (strcmp(name, user) == 0)
        {
            r = 0;
        }
        else
            r = -1;
    }

    return r;
}

この例では getlogin を使用して、現在のユーザーのユーザー名を指定のユーザー名と比較しています。しかし、並列処理により文字列が変更されることがあるため、getlogin は現在のユーザー名以外を返す場合があります。

修正 — getlogin_r を使用

1 つの修正方法として、getlogin_rgetlogin の代わりに使用します。getlogin_r は再呼び出し可能なので、その結果は信頼できます。

#define _POSIX_C_SOURCE 199506L // use of getlogin_r
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>
#include <string.h>
#include <stdlib.h>


volatile int rd = 1;

enum {  NAME_MAX_SIZE=64  };

int login_name_check(char *user)
{
    int r;
    char name[NAME_MAX_SIZE];
    
    if (getlogin_r(name, sizeof(name)) == 0) 
    {
        if ((strlen(user) < sizeof(name)) && 
                     (strncmp(name, user, strlen(user)) == 0))
        {
            r = 0;
        }
        else
            r = -1;
    }
    else
        r = -2;
    return r;
}

結果情報

グループ: セキュリティ
言語: C | C++
既定値: オフ
コマンド ライン構文: UNSAFE_STD_FUNC
影響度: Medium

バージョン履歴

R2015b で導入