メインコンテンツ

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

権限の削除が検証されていません

攻撃者がプログラムへの意図しない昇格されたアクセス権を取得可能

説明

この欠陥は、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 */
}

この例では、意図する権限レベルでコードを実行するために、権限を昇格して削除しています。権限を削除するとき、関数本体を終了する前に権限レベルを検証していません。悪意のある攻撃者が、昇格した権限を再取得できます。

修正 - 権限の削除を検証

考えられる 1 つの修正方法として、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
影響度: High

バージョン履歴

R2016b で導入