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
Влияние: Высокий
ИДЕНТИФИКАТОР CWE: 250, 273
Введенный в R2016b