Library loaded from externally controlled path

Использование аргумента библиотеки из управляемого извне пути

Описание

Этот дефект возникает, когда библиотеки загружаются из фиксированных или управляемых извне небезопасных путей, и непреднамеренные актёры могут управлять одним или несколькими местоположениями в путях. Чтобы считать все входы за пределами периметра анализа тока небезопасными, используйте -consider-analysis-perimeter-as-trust-boundary.

Риск

Если атакующий знает или управляет путем, который вы используете для загрузки библиотеки, атакующий может измениться:

  • Библиотека, которую загружает программа, заменяющая предполагаемую библиотеку и команды.

  • Окружение, в которой библиотека выполняет, давая злоумышленнику непреднамеренные разрешения и возможности.

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

По возможности используйте жестко закодированные или полные имена путей для загрузки библиотек. Возможно, жестко закодированные пути не работают в других системах. Используйте централизованное расположение для жестко закодированных путей, чтобы вы могли легко изменять путь в исходном коде.

Другое решение - использовать функции, которые требуют явных путей. Для примера, 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);
    return libhandle;
}

Этот пример загружает библиотеку libX.so от переменного окружения LD_LIBRARY_PATH. Атакующий может изменить путь к библиотеке в этой переменной окружения. Фактическая библиотека, которую вы загружаете, может отличаться от той, что вы собираетесь.

Коррекция - Изменение и проверка пути

Одна из возможных коррекций - изменить способ получения пути к библиотеке и проверить путь к библиотеке перед открытием библиотеки. Этот пример получает путь как входной параметр, но затем выполняет следующие проверки пути:

  • Функция 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 white list */
static const char *libX_safe_folder[] = {
  "/usr/",
  "/usr/lib",
  "/lib"
};

/* Return the index if the input is in the white list */
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++
По умолчанию: Off
Синтаксис командной строки: TAINTED_PATH_LIB
Влияние: Средний
ИДЕНТИФИКАТОР CWE: 114, 426
Введенный в R2015b