メインコンテンツ

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

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

外部制御されているパスに由来するライブラリ引数を使用

説明

この欠陥は、固定のまたは外部制御された、セキュリティで保護されていないパスからライブラリが読み込まれ、そのパス上にある 1 つ以上の場所を想定外のアクターが制御できる場合に発生します。

リスク

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

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

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

修正方法

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

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

チェッカーの拡張

既定では、Polyspace® は外部ソースからのデータは汚染されていると仮定します。Polyspace 解析での汚染のソースを参照してください。Polyspace 解析の現在のスコープ以外から発生したすべてのデータを汚染されたものと見なすには、コマンド ライン オプション [-consider-analysis-perimeter-as-trust-boundary] を使用します。

すべて展開する

#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);//Noncompliant- userpath is tainted
    strcat(lib, "/libX.so");
    libhandle = dlopen(lib, 0x00001);//Noncompliant
    return libhandle;
}

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

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

1 つの修正方法として、ライブラリ パスの取得方法を変更し、ライブラリを開く前にライブラリのパスをチェックします。この例では、パスを入力引数として受信しますが、そのパスに対して以下のチェックを実行します。

  • 関数 sanitize_str が可能性のあるバッファー オーバーフローから保護している。

  • 関数 identified_safe_libX_folder が、パスが許可されたパスのリストに登録されているかどうかをチェックする。

#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
};

/* Use allowlist */
static const char *libX_safe_folder[] = {
  "/usr/",
  "/usr/lib",
  "/lib"
};

/* Return the index if the input is in the allowlist */
int identified_safe_libX_folder(const char* path)
{
  for (int i = 0; i < sizeof(libX_safe_folder) / sizeof(libX_safe_folder[0]); i ++)
    {
      if (strcmp(path, libX_safe_folder[i]) == 0)
      return i;
    }
  return -1;    
}

/* Function to sanitize a string */
char *sanitize_str(char* s, size_t n) {
  /* strlen is used here as a kind of firewall for tainted string errors */
  if (strlen(s) > 0 && strlen(s) < n)
    return s;
  else
    return NULL;
}

void* taintedpathlib(char* userpath) {
  void* libhandle = NULL;
  const char *const checked_userpath = sanitize_str(userpath, SIZE128);
  if (checked_userpath != NULL) {
    int index = identified_safe_libX_folder(checked_userpath);
    if (index > 0) {
      char lib[SIZE128] = "";
      strncpy(lib, libX_safe_folder[index], SIZE128);
      strcat(lib, "/libX.so");
      libhandle = dlopen(lib, RTLD_LAZY);    
    }
  }
  return libhandle;
}

結果情報

グループ: 汚染されたデータ
言語: C | C++
既定値: オフ
コマンド ライン構文: TAINTED_PATH_LIB
影響度: Medium

バージョン履歴

R2015b で導入