Bad order of dropping privileges

Пропущенный выше поднятые привилегии прежде, чем пропустить ниже поднятые привилегии

Описание

Этот дефект происходит, когда вы используете функции, такие как setuid и setgid в неправильном порядке, пропуская выше поднятые привилегии прежде, чем пропустить ниже поднятые привилегии. Например, вы понижаетесь, поднятые первичные привилегии группы прежде, чем понизиться подняли вспомогательные привилегии группы.

Риск

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

Фиксация

Уважайте этот порядок отбрасывания поднятых привилегий:

  • Пропустите (поднятые) вспомогательные привилегии группы, затем пропустите (поднятые) первичные привилегии группы.

  • Пропустите (поднятые) первичные привилегии группы, затем пропустите (поднятые) полномочия пользователя.

Примеры

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

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

static void sanitize_privilege_drop_check(uid_t olduid, gid_t oldgid)
{
    if (seteuid(olduid) != -1)
    {
        /* Privileges can be restored, handle error */
        fatal_error();
    }
    if (setegid(oldgid) != -1)
    {
        /* Privileges can be restored, handle error */
        fatal_error();
    }
}
void badprivilegedroporder(void) {
    uid_t
        newuid = getuid(),
        olduid = geteuid();
    gid_t
        newgid = getgid(),
        oldgid = getegid();

    if (setuid(newuid) == -1) {
        /* handle error condition */
        fatal_error();
    }
    if (setgid(newgid) == -1)  { 
        /* handle error condition */
        fatal_error();
    }
    if (olduid == 0) {
        /* drop ancillary groups IDs only possible for root */
        if (setgroups(1, &newgid) == -1) {
            /* handle error condition */
            fatal_error();
        }
    }

    sanitize_privilege_drop_check(olduid, oldgid);
}

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

Коррекция — противоположный порядок отбрасывания привилегии

Одна возможная коррекция должна пропустить самые низкие привилегии уровня сначала. В этой коррекции вспомогательные привилегии группы пропущены, затем пропущены первичные привилегии группы, и наконец полномочия пользователя пропущены.

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

static void sanitize_privilege_drop_check(uid_t olduid, gid_t oldgid)
{
    if (seteuid(olduid) != -1)
    {
        /* Privileges can be restored, handle error */
        fatal_error();
    }
    if (setegid(oldgid) != -1)
    {
        /* Privileges can be restored, handle error */
        fatal_error();
    }
}
void badprivilegedroporder(void) {
    uid_t
        newuid = getuid(),
        olduid = geteuid();
    gid_t
        newgid = getgid(),
        oldgid = getegid();

    if (olduid == 0) {
        /* drop ancillary groups IDs only possible for root */
        if (setgroups(1, &newgid) == -1) {
            /* handle error condition */
            fatal_error();
        }
    }
    if (setgid(getgid()) == -1)  {
        /* handle error condition */
        fatal_error();
    }
    if (setuid(getuid()) == -1) {
        /* handle error condition */
        fatal_error();
    }

    sanitize_privilege_drop_check(olduid, oldgid);
}

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

Группа: безопасность
Язык: C | C++
Значение по умолчанию: 'off'
Синтаксис командной строки: BAD_PRIVILEGE_DROP_ORDER
Удар: высоко
ID CWE: 250, 696

Введенный в R2017b