メインコンテンツ

CERT C: Rec.WIN00-C

Be specific when dynamically loading libraries

説明

ルール定義

ライブラリを動的に読み込む場合は、具体的に指定します。1

Polyspace 実装

ルール チェッカーは以下の問題をチェックします。

  • 相対パスからライブラリを読み込むと、外部アクターの制御を受ける可能性があります

  • 外部制御されるパスから読み込まれたライブラリ

チェッカーの拡張

既定の Bug Finder 解析では、現在の解析境界の外部からの特定の入力に関する "外部制御されるパスから読み込まれたライブラリ" 問題にフラグを設定しない場合があります。Polyspace 解析での汚染のソースを参照してください。Polyspace 解析の現在のスコープ以外から発生したすべてのデータを汚染されたものと見なすには、コマンド ライン オプション [-consider-analysis-perimeter-as-trust-boundary] を使用します。

すべて展開する

問題

相対パスからライブラリを読み込むと、外部アクターの制御を受ける可能性がありますは、外部ライブラリを読み込むライブラリ読み込みルーチンを検出します。ライブラリの読み込みに相対パスを使用するかパスを使用しない場合、Bug Finder はその読み込みルーチンに欠陥のフラグを立てます。

リスク

外部ライブラリの読み込みに相対パスを使用するかパスを使用しないことで、プログラムでは、安全でない検索プロセスがライブラリの検索に使用されます。攻撃者は検索プロセスを制御して、想定されているライブラリを攻撃者独自のライブラリに置き換えることができます。

修正方法

外部ライブラリを呼び出す際は絶対パスを指定します。

例 - ライブラリをライブラリ名で開く
#include <dlfcn.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <stdio.h>

void relative_path()
{
    dlopen("liberty.dll",RTLD_LAZY); //Noncompliant
}

この例では、dlopen が、ライブラリの名前のみを呼び出すことでライブラリ liberty を開いています。しかし、ライブラリのこの呼び出しでは相対パスを使用してライブラリが検索されるため、安全ではありません。

修正 — ライブラリへの絶対パスを使用

1 つの修正方法として、ライブラリをプログラムに読み込む際にライブラリへの絶対パスを使用します。

#include <dlfcn.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <stdio.h>

void relative_path()
{
    dlopen("/home/my_libs/library/liberty.dll",RTLD_LAZY);
}
問題

外部制御されるパスから読み込まれたライブラリは、固定のパスまたは制御されているパスから読み込まれたライブラリを調べます。この固定のパス上にある 1 つ以上の場所を想定外のアクターが制御できる場合、Bug Finder により欠陥が報告されます。

リスク

ライブラリの読み込みに使用されているパスを攻撃者が知っているか制御している場合、攻撃者は以下を変更できます。

  • プログラムで読み込まれるライブラリ。想定されたライブラリとコマンドが置き換えられる。

  • ライブラリが実行される環境。想定外の権限と機能が攻撃者に付与される。

修正方法

可能な場合は、ハードコードされたパス名か完全修飾パス名を使用してライブラリを読み込みます。ハードコードされたパスは、他のシステムでは機能しない可能性があります。ハードコードされたパスには一元的な場所を使用して、ソース コード内でパスを簡単に変更できるようにします。

別の解決策として、明示的なパスが要求される関数を使用します。たとえば、system() では環境変数 PATH を使用できるため、絶対パスは要求されません。しかし、execl()execv() では絶対パスが要求されます。

例 - カスタム ライブラリの呼び出し
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <dlfcn.h>
#include <limits.h>

enum {
    SIZE10  =  10,
    SIZE100 = 100,
    SIZE128 = 128
};

void* taintedpathlib() {
    void* libhandle = NULL;
    char lib[SIZE128] = "";
    char* userpath = getenv("LD_LIBRARY_PATH");
    strncpy(lib, userpath, SIZE128);
    strcat(lib, "/libX.so");
    libhandle = dlopen(lib, 0x00001); //Noncompliant
    return libhandle;
}

この例では、ライブラリ libX.so が環境変数 LD_LIBRARY_PATH から読み込まれています。攻撃者は、この環境変数のライブラリ パスを変更できます。実際に読み込まれるライブラリは、想定とは異なるライブラリとなる可能性があります。

修正 — パスを変更してチェック

1 つの修正方法として、ライブラリ パスの取得方法を変更し、ライブラリを開く前にライブラリのパスをチェックします。この例では、パスを入力引数として受け取っています。そのうえでパスがチェックされ、ライブラリが /usr/ の下にないことが確認されます。

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <dlfcn.h>
#include <limits.h>

enum {
    SIZE10  =  10,
    SIZE100 = 100,
    SIZE128 = 128
};

/* Function to sanitize a string */
int sanitize_str(char* s, size_t n) {
    /* strlen is used here as a kind of firewall for tainted string errors */
    int res = (strlen(s) > 0 && strlen(s) < n);
    return res;
}
void* taintedpathlib(char* userpath) {
    void* libhandle = NULL;
    if (sanitize_str(userpath, SIZE128)) {
        char lib[SIZE128] = "";

        if (strncmp(userpath, "/usr", 4)!=0) {
            strncpy(lib, userpath, SIZE128);
            strcat(lib, "/libX.so");
            libhandle = dlopen(lib, RTLD_LAZY);    
        }
    }
    return libhandle;
}

チェック情報

グループ: Rec.51.Microsoft Windows (WIN)

バージョン履歴

R2019a で導入


1 This software has been created by MathWorks incorporating portions of: the “SEI CERT-C Website,” © 2017 Carnegie Mellon University, the SEI CERT-C++ Web site © 2017 Carnegie Mellon University, ”SEI CERT C Coding Standard – Rules for Developing safe, Reliable and Secure systems – 2016 Edition,” © 2016 Carnegie Mellon University, and “SEI CERT C++ Coding Standard – Rules for Developing safe, Reliable and Secure systems in C++ – 2016 Edition” © 2016 Carnegie Mellon University, with special permission from its Software Engineering Institute.

ANY MATERIAL OF CARNEGIE MELLON UNIVERSITY AND/OR ITS SOFTWARE ENGINEERING INSTITUTE CONTAINED HEREIN IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.

This software and associated documentation has not been reviewed nor is it endorsed by Carnegie Mellon University or its Software Engineering Institute.