Privilege drop not verified

Атакующий может получить непреднамеренный поднятый доступ к программе

Описание

Этот дефект происходит, когда вы оставляете привилегии с помощью функций, таких как 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++
Значение по умолчанию: Off
Синтаксис командной строки: MISSING_PRIVILEGE_DROP_CHECK
Удар: высоко
ID CWE: 250, 273
Введенный в R2017b