exponenta event banner

Удаление привилегий не проверено

Злоумышленник может получить непреднамеренный повышенный доступ к программе

Описание

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

Риск

Если отказ от привилегий не удается, злоумышленник может восстановить повышенные привилегии и иметь больший доступ к вашей программе, чем предполагалось. Это отверстие безопасности может вызвать непредвиденное поведение в коде, если его оставить открытым.

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

Перед окончанием области убедитесь, что удаляемые привилегии действительно удалены.

Примеры

развернуть все

#define _BSD_SOURCE
#include <sys/types.h>
#include <unistd.h>
#include <grp.h>
#include <stdlib.h>
#define fatal_error() abort()
extern int need_more_privileges;

void missingprivilegedropcheck()
{
    /* Code intended to run with elevated privileges */

    /* Temporarily drop elevated privileges */
    if (seteuid(getuid()) != 0) {
        /* Handle error */
        fatal_error();
    }

    /* Code intended to run with lower privileges */

    if (need_more_privileges) {
        /* Restore elevated privileges */
        if (seteuid(0) != 0) {
            /* Handle error */
            fatal_error();
        }
        /* Code intended to run with elevated privileges */
    }

    /* ... */

    /* Permanently drop elevated privileges */
    if (setuid(getuid()) != 0) {
        /* Handle error */
        fatal_error();
    }

    /* Code intended to run with lower privileges */
}

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

Исправление - Проверка удаления привилегий

Одной из возможных корректировок является использование setuid для проверки удаления привилегий.

#define _BSD_SOURCE
#include <sys/types.h>
#include <unistd.h>
#include <grp.h>
#include <stdlib.h>
#define fatal_error() abort()
extern int need_more_privileges;

void missingprivilegedropcheck()
{
    /* Store the privileged ID for later verification */
    uid_t privid = geteuid();

    /* Code intended to run with elevated privileges   */

    /* Temporarily drop elevated privileges */
    if (seteuid(getuid()) != 0) {
        /* Handle error */
        fatal_error();
    }

    /* Code intended to run with lower privileges  */

    if (need_more_privileges) {
        /* Restore elevated Privileges */
        if (seteuid(privid) != 0) {
            /* Handle error */
            fatal_error();
        }
        /* Code intended to run with elevated privileges   */
    }

    /* ... */

    /* Restore privileges if needed */
    if (geteuid() != privid) {
        if (seteuid(privid) != 0) {
            /* Handle error */
            fatal_error();
        }
    }

    /* Permanently drop privileges */
    if (setuid(getuid()) != 0) {
        /* Handle error */
        fatal_error();
    }

    if (setuid(0) != -1) {
        /* Privileges can be restored, handle error */
        fatal_error();
    }

    /* Code intended to run with lower privileges; */
}

Информация о результатах

Группа: Безопасность
Язык: C | C++
По умолчанию: Откл.
Синтаксис командной строки: MISSING_PRIVILEGE_DROP_CHECK
Воздействие: Высокое
ИДЕНТИФИКАТОР CWE: 250, 273
Представлен в R2016b