CWE-478: Missing Default Case in Switch Statement(switch缺少default)

 ID: 478

類型:變量
結構:簡單

狀態:草稿

描述

代碼在switch語句中沒有defult,這可能導致複雜的邏輯錯誤和由此產生的弱點。

擴展描述

這個缺陷代表了軟件開發中的一個常見問題,在這個問題中,並非所有變量的可能值都由給定的過程來考慮或處理。因此,進一步的決策是基於糟糕的信息和級聯故障結果。這種級聯故障可能導致任何數量的安全問題,並構成系統中的重大故障。

關聯視圖

與“研究層面”視圖(CWE-1000)相關

與“開發層面”視圖(CWE-699)相關

引入模式

階段

說明

實現

 

應用平臺

語言

C (出現的可能性不確定)

C++ (出現的可能性不確定)

Java (出現的可能性不確定)

C# (出現的可能性不確定)

後果

範圍

衝擊

可能性

完整性

技術衝擊: 上下文相關; 修改執行邏輯

根據所涉及的邏輯情況,可能會導致任何後果:例如,保密性、認證、授權、可利用性、完整性、責任性或不可抵賴性問題。

 

示例

例1

如果安全檢查函數在發生錯誤時返回-1值,則以下內容無法正確檢查返回代碼。如果攻擊者可以提供將調用錯誤的數據,則攻擊者可以繞過安全檢查:

(問題代碼)

Example Language:

#define FAILED 0
#define PASSED 1
int result;
...
result = security_check(data);
switch (result) {

case FAILED:

printf("Security check failed!\n");
exit(-1);
//Break never reached because of exit()
break;


case PASSED:

printf("Security check passed.\n");
break;

}
// program execution continues...
...

應該使用default語句處理未考慮到的情況:

(正確代碼)

Example Language:

#define FAILED 0
#define PASSED 1
int result;
...
result = security_check(data);
switch (result) {

case FAILED:

printf("Security check failed!\n");
exit(-1);
//Break never reached because of exit()
break;


case PASSED:

printf("Security check passed.\n");
break;


default:

printf("Unknown error (%d), exiting...\n",result);
exit(-1);

}

之所以使用此標籤,是因爲無法假設所有可能的案例都已得到解釋。一個好的實踐是爲錯誤處理保留默認情況。

例2

在下面的Java示例中,GETSeReStand方法檢索抵押點的利率。輸入參數中提供了點數,switch語句將根據點數設置要返回的利率值。

(問題代碼)

Example Language: Java 

public static final String INTEREST_RATE_AT_ZERO_POINTS = "5.00";
public static final String INTEREST_RATE_AT_ONE_POINTS = "4.75";
public static final String INTEREST_RATE_AT_TWO_POINTS = "4.50";
...
public BigDecimal getInterestRate(int points) {

BigDecimal result = new BigDecimal(INTEREST_RATE_AT_ZERO_POINTS);

switch (points) {

case 0:

result = new BigDecimal(INTEREST_RATE_AT_ZERO_POINTS);
break;


case 1:

result = new BigDecimal(INTEREST_RATE_AT_ONE_POINTS);
break;


case 2:

result = new BigDecimal(INTEREST_RATE_AT_TWO_POINTS);
break;

}
return result;

}

但是,此代碼假定Points輸入參數的值始終爲0、1或2,並且不檢查傳遞給該方法的其他錯誤值。這可以通過在switch語句中提供一個默認標籤輕鬆實現,該標籤輸出一條錯誤消息,指示Points輸入參數的無效值,並返回一個空值。

(正確代碼)

Example Language: Java 

public static final String INTEREST_RATE_AT_ZERO_POINTS = "5.00";
public static final String INTEREST_RATE_AT_ONE_POINTS = "4.75";
public static final String INTEREST_RATE_AT_TWO_POINTS = "4.50";
...
public BigDecimal getInterestRate(int points) {

BigDecimal result = new BigDecimal(INTEREST_RATE_AT_ZERO_POINTS);

switch (points) {

case 0:

result = new BigDecimal(INTEREST_RATE_AT_ZERO_POINTS);
break;


case 1:

result = new BigDecimal(INTEREST_RATE_AT_ONE_POINTS);
break;


case 2:

result = new BigDecimal(INTEREST_RATE_AT_TWO_POINTS);
break;


default:

System.err.println("Invalid value for points, must be 0, 1 or 2");
System.err.println("Returning null value for interest rate");
result = null;

}

return result;

}

應對措施

階段: 實現

在根據給定變量的值調整流或值時,確保沒有未計數的情況。在switch語句中,這可以通過使用默認標籤來實現。

階段: 實現

在switch樣式語句的情況下,創建默認情況的非常簡單的操作可以減輕這種情況(如果正確地完成)。然而,通常情況下,默認情況只是用來表示一個假定的選項,而不是作爲對無效輸入的檢查。這是一種糟糕的做法,在某些情況下,這和完全忽略默認情況一樣糟糕。

種屬

關係

類型

ID

名稱

屬於

884

CWE Cross-section

屬於

962

SFP Secondary Cluster: Unchecked Status Condition

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章