界: Code Quality

程式碼品質不佳,會導致無法預料的行為。從使用者的角度來看,這通常表現為可用性不佳。對於攻擊者而言,這提供了以意想不到的方式向系統施加壓力的機會。

Obsolete

Abstract
使用不推薦或過時的函數可能表示有程式碼被忽略。
Explanation
一般而言,隨著程式語言的演變,有時有些方法可能會過時,原因如下:

- 語言進化
- 更加了解應如何有效且安全地執行作業

- 管理某些特定作業的慣例發生變化

在程式語言中,舊陳述式會被新陳述式所取代,而新陳述式會以不同但更好的方式執行同樣的任務。

特別是,SAP ABAP 已發展為包含 ABAP 物件 (ABAP 的物件導向擴充) 並可在與 Unicode 相容的環境中操作。因此,類別或 Unicode 程式中執行的語法更嚴格。過時的建構仍然可用,原因僅僅是與舊版本相容,但只能在類別外部或者非 Unicode 程式中使用。所有過時的語言元素具有替代建構,用以改善程式的效率及可讀性。過時語法中許多隱含、不明確的類型/長度/記憶體規格必須在新語法中以更加精確而明確的方式指定。建議採用新語法,以使程式更易理解、更加可靠、更易維護。


並不是所有函數都因為有安全性風險,才不推薦使用或被取代。但是,過時函數的存在通常表示周圍的程式碼已經沒有作用,甚至有可能處在廢棄狀態。長久以來,軟體的安全性始終不是優先的考量,甚或不納入考量。如果程式使用不推薦或過時的函數,則安全性問題更有可能伺機出沒。
desc.semantic.abap.obsolete
Abstract
使用不推薦或過時的函數可能表示有程式碼被忽略。
Explanation
隨著程式語言的發展,函數遭淘汰的原因有以下幾點:

- 語言進化
- 更加瞭解應如何有效且安全地執行作業

- 管理某些特定作業的慣例發生變化


在程式語言中,舊函數會被新函數所取代,而新函數會以不同但更好的方式執行同樣的任務。
範例:以下程式碼建構了一個新的 SqlClientPermission 物件,其規定使用者可連接到資料庫的方式。在此範例中,程式把 false 作為第二個參數傳遞給構造函數,控制使用者是否可使用空白密碼進行連接。若傳送的參數值為 false,表示不允許密碼為空白。


...
SCP = new SqlClientPermission(pstate, false);
...


不過,因為作為第一個參數傳遞的 PermissionState 物件代替了所有傳遞至第二個參數的值,因此構造函數允許使用空白密碼進行資料庫連線,這與第二個引數互相矛盾。若要禁止使用空白密碼,程式應該把 PermissionState.None 傳遞給建構函數的第一個參數。因為其功能的不明確,SqlClientPermission 構造函數的雙參數版本已遭反對,改用單參數版本,單參數版本可提供與雙參數版本相同的功能,但是避免了誤譯的風險。

並不是所有函數都因為有安全性風險,才不推薦使用或被取代。但是,過時函數的存在通常表示周圍的程式碼已經沒有作用,甚至有可能處在廢棄狀態。長久以來,軟體的安全性始終不是優先的考量,甚或不納入考量。如果程式使用不推薦或過時的函數,則安全性問題更有可能伺機出沒。
desc.semantic.dotnet.obsolete
Abstract
使用不推薦或過時的函數可能表示有程式碼被忽略。
Explanation
隨著程式語言的發展,函數遭淘汰的原因有以下幾點:

- 語言進化。
- 對操作的有效性、安全性有更深一步的瞭解。
- 對操作管理規則進行的修改。

在編程語言中,舊函數會被新函數所替代,這是因為比起舊函數,新函數更能以我們所期望的方式執行任務。
範例:以下程式碼使用了不推薦使用的函數 getpw() 來檢驗一個純文字密碼是否與使用者加密密碼匹配。如果密碼是有效的,那函數將把 result 設為 1;如果無效,將其設為 0。


...
getpw(uid, pwdline);
for (i=0; i<3; i++){
cryptpw=strtok(pwdline, ":");
pwdline=0;
}
result = strcmp(crypt(plainpw,cryptpw), cryptpw) == 0;
...


雖然此程式碼的行為通常正確無誤,但是從安全性的角度來看,使用 getpw() 函數會產生問題,因為這會導致傳遞至其第二個參數的緩衝區發生溢位。鑒於存在這一弱點,getpw() 已由 getpwuid() 取代,後者會執行與 getpw() 相同的查詢,但是會傳回指向靜態分配之結構的指標以降低風險。

並不是所有函數都因為有安全性風險,才不推薦使用或被取代。但是,過時函數的存在通常表示周圍的程式碼已經沒有作用,甚至有可能處在廢棄狀態。長久以來,軟體的安全性始終不是優先的考量,甚或不納入考量。如果程式使用不推薦或過時的函數,則安全性問題更有可能伺機出沒。
desc.semantic.cpp.obsolete
Abstract
使用不推薦或過時的函數,表示有被閒置的程式碼或使用過時的 ColdFusion 版本。
Explanation
隨著程式語言的演變,有時有些方法可能會過時,原因如下:

- 語言進化
- 更加了解應如何有效且安全地執行作業

- 管理某些特定作業的慣例發生變化

在某種語言中,我們通常都會捨棄某些方法,並以較新且類似的方法取代。新的方法可以使用稍微不同但較好的方式來執行同樣的工作。


並不是所有函數都因為有安全性風險,才不推薦使用或被取代。但是,過時函數的存在通常表示周圍的程式碼已經沒有作用,甚至有可能處在廢棄狀態。長久以來,軟體的安全性始終不是優先的考量,甚或不納入考量。如果程式使用不推薦或過時的函數,則安全性問題更有可能伺機出沒。
desc.semantic.cfml.obsolete
Abstract
使用不推薦或過時的函數可能表示有程式碼被忽略。
Explanation
隨著程式語言的演變,有時有些方法可能會過時,原因如下:

- 語言進化
- 更加了解應如何有效且安全地
執行作業
- 管理某些特定作業的慣例發生變化

在某種語言中,我們通常都會捨棄某些方法,並以較新且類似的方法取代。新的方法可以使用稍微不同但較好的方式來執行同樣的工作。
範例:以下程式碼會使用位元組陣列和指定每個 16 位元 Unicode 字元前 8 個位元的值來建構一個字串物件。


...
String name = new String(nameBytes, highByte);
...


在此範例中,建構函式可能無法正確地將位元組轉換成字元,這需視要使用哪個字元組來編碼由 nameBytes 所呈現的字串而定。由於用於編碼字串的字元組的演變,所以不推薦使用此建構函式,取而代之的是新的構造函式。新的構造函式可接受作為名為 charset 的其中一個參數,用來編碼字元組以進行字元轉換。

並不是所有函數都因為有安全性風險,才不推薦使用或被取代。但是,過時函數的存在通常表示周圍的程式碼已經沒有作用,甚至有可能處在廢棄狀態。長久以來,軟體的安全性始終不是優先的考量,甚或不納入考量。如果程式使用不推薦或過時的函數,則安全性問題更有可能伺機出沒。
References
[1] MET02-J. Do not use deprecated or obsolete classes or methods CERT
desc.semantic.java.obsolete
Abstract
使用不推薦或過時的函數可能表示有程式碼被忽略。
Explanation
隨著程式語言的演變,有時有些方法可能會過時,原因如下:

- 語言進化
- 更加了解應如何有效且安全地執行作業

- 對操作管理規則進行的修改。

在某種語言中,我們通常都會捨棄某些方法,並以較新且類似的方法取代。新的方法可以使用稍微不同但較好的方式來執行同樣的工作。
範例:以下程式碼使用 Digest::HMAC stdlib,但由於發行涉及意外,因此在文件中明確勸阻這樣的使用。


require 'digest/hmac'

hmac = Digest::HMAC.new("foo", Digest::RMD160)
...
hmac.update(buf)
...


在此範例中,由於發行涉及意外,在涉及 Digest::HMAC 類別時便會立即捨棄。由於實驗性和未正確測試的程式碼造成此要求無法如預期般運作,強烈勸阻使用此類別,尤其考慮到加密式功能涉及的關係 HMAC。

並不是所有函數都因為有安全性風險,才不推薦使用或被取代。但是,過時函數的存在通常表示周圍的程式碼已經沒有作用,甚至有可能處在廢棄狀態。長久以來,軟體的安全性始終不是優先的考量,甚或不納入考量。如果程式使用不推薦或過時的函數,則安全性問題更有可能伺機出沒。
desc.structural.ruby.obsolete
Abstract
使用了已被取代的函數。
Explanation
由於智慧合約的快節奏特性,函數和運算子可能會隨較新的編譯器版本而被取代,使用它們可能會導致低品質的程式碼、意外的副面影響和/或編譯錯誤。

範例 1:以下程式碼使用自 Solidity 編譯器 0.5.0 版本起就已被取代的 block.blockhash() 取得目前區塊的雜湊。


bytes32 blockhash = block.blockhash(0);
desc.structural.solidity.swc111