メインコンテンツ

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

switch 条件の case がありません

switch 変数が case によってカバーされておらず、default ケースがない

説明

この欠陥は、変数 switchcase ステートメントでカバーされない値を取る可能性がある場合に発生します。

メモ

Bug Finder では、switch 変数が全範囲でない場合にのみ欠陥が報告されます。

リスク

switch 変数が case ステートメントでカバーされていない値を取る場合、プログラムで想定外の動作になることがあります。

セキュリティについての判定をする switch ステートメントは、取りうる値が必ずしもすべて明示的に扱われているわけではない場合、特に脆弱になります。攻撃者はこの状況を利用して正規の実行フローを逸脱させることができます。

修正方法

case ステートメントでカバーされない値をすべてキャッチする受け皿として default ステートメントを使用することをお勧めします。switch 変数が想定外の値を取ったとしても、結果の動作は予想どおりになります。

すべて展開する

#include <stdio.h>
#include <string.h>

typedef enum E
{
    ADMIN=1,
    GUEST,
    UNKNOWN = 0
} LOGIN;

static LOGIN system_access(const char *username) {
  LOGIN user = UNKNOWN;

  if ( strcmp(username, "root") == 0 )
    user = ADMIN;

  if ( strcmp(username, "friend") == 0 )
    user = GUEST;

  return user;
}

int identify_bad_user(const char * username)
{
    int r=0;

    switch( system_access(username) ) 
    {
    case ADMIN:
        r = 1;
        break;
    case GUEST:
        r = 2;
    }

    printf("Welcome!\n");
    return r;
}

この例で、enum パラメーター User は、case ステートメントでカバーされていない値 UNKNOWN を取ることができます。

修正 — 既定の条件を追加

1 つの修正方法として、取りうる値のうち case ステートメントでカバーされていないものに対し、既定の条件を追加します。

#include <stdio.h>
#include <string.h>

typedef enum E
{
    ADMIN=1,
    GUEST,
    UNKNOWN = 0
} LOGIN;

static LOGIN system_access(const char *username) {
  LOGIN user = UNKNOWN;

  if ( strcmp(username, "root") == 0 )
    user = ADMIN;

  if ( strcmp(username, "friend") == 0 )
    user = GUEST;

  return user;
}

int identify_bad_user(const char * username)
{
    int r=0;

    switch( system_access(username) ) 
    {
    case ADMIN:
        r = 1;
        break;
    case GUEST:
        r = 2;
	break;
    default:
        printf("Invalid login credentials!\n");
    }

    printf("Welcome!\n");
    return r;
}

結果情報

グループ: セキュリティ
言語: C | C++
既定値: オフ
コマンド ライン構文: MISSING_SWITCH_CASE
影響度: Low

バージョン履歴

R2015b で導入