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
Удар: Средняя
ID CWE: 114, 426
Введенный в R2015b