界: Code Quality

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

93 找到的項目
弱點
Abstract
未指定地區設定時,可以發現非預期的移植性問題。
Explanation
在比較可能取決於地區設定的資料時,應該指定適當的地區設定。

範例 1:以下範例將嘗試執行驗證,以確定使用者輸入是否包含 <script> 標籤。

...
public String tagProcessor(String tag){
if (tag.toUpperCase().equals("SCRIPT")){
return null;
}
//does not contain SCRIPT tag, keep processing input
...
}
...
Example 1 的問題是,在無地區設定的情況使用 java.lang.String.toUpperCase() 時,它會使用預設地區設定的規則。使用土耳其文地區設定 "title".toUpperCase() 會傳回「T\u0130TLE」,其中「\u0130」是「LATIN CAPITAL LETTER I WITH DOT ABOVE」字元。這會導致非預期的結果,例如,在 Example 1 中,這會阻止此驗證攔截「script」一字,進而可能導致 Cross-Site Scripting 弱點。
References
[1] STR02-J. Specify an appropriate locale when comparing locale-dependent data CERT
[2] String (JavaDoc) Oracle
[3] Standards Mapping - CIS Azure Kubernetes Service Benchmark 1
[4] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 3
[5] Standards Mapping - CIS Amazon Web Services Foundations Benchmark 1
[6] Standards Mapping - CIS Google Kubernetes Engine Benchmark normal
[7] Standards Mapping - Common Weakness Enumeration CWE ID 474
[8] Standards Mapping - DISA Control Correlation Identifier Version 2 CCI-001310
[9] Standards Mapping - Payment Card Industry Data Security Standard Version 3.0 Requirement 6.5.6
[10] Standards Mapping - Payment Card Industry Data Security Standard Version 3.2 Requirement 6.5.6
[11] Standards Mapping - Payment Card Industry Data Security Standard Version 3.2.1 Requirement 6.5.6
[12] Standards Mapping - Payment Card Industry Data Security Standard Version 3.1 Requirement 6.5.6
[13] Standards Mapping - Payment Card Industry Data Security Standard Version 4.0 Requirement 6.2.4
[14] Standards Mapping - Payment Card Industry Software Security Framework 1.0 Control Objective 4.2 - Critical Asset Protection
[15] Standards Mapping - Payment Card Industry Software Security Framework 1.1 Control Objective 4.2 - Critical Asset Protection
[16] Standards Mapping - Payment Card Industry Software Security Framework 1.2 Control Objective 4.2 - Critical Asset Protection
[17] Standards Mapping - Security Technical Implementation Guide Version 4.1 APSC-DV-002520 CAT II
[18] Standards Mapping - Security Technical Implementation Guide Version 4.2 APSC-DV-002520 CAT II
[19] Standards Mapping - Security Technical Implementation Guide Version 4.3 APSC-DV-002520 CAT II
[20] Standards Mapping - Security Technical Implementation Guide Version 4.4 APSC-DV-002520 CAT II
[21] Standards Mapping - Security Technical Implementation Guide Version 4.5 APSC-DV-002520 CAT II
[22] Standards Mapping - Security Technical Implementation Guide Version 4.6 APSC-DV-002520 CAT II
[23] Standards Mapping - Security Technical Implementation Guide Version 4.7 APSC-DV-002520 CAT II
[24] Standards Mapping - Security Technical Implementation Guide Version 4.8 APSC-DV-002520 CAT II
[25] Standards Mapping - Security Technical Implementation Guide Version 4.9 APSC-DV-002520 CAT II
[26] Standards Mapping - Security Technical Implementation Guide Version 4.10 APSC-DV-002520 CAT II
[27] Standards Mapping - Security Technical Implementation Guide Version 4.11 APSC-DV-002520 CAT II
[28] Standards Mapping - Security Technical Implementation Guide Version 5.1 APSC-DV-002520 CAT II
[29] Standards Mapping - Security Technical Implementation Guide Version 5.2 APSC-DV-002520 CAT II
[30] Standards Mapping - Security Technical Implementation Guide Version 5.3 APSC-DV-002520 CAT II
desc.controlflow.java.portability_flaw_locale_dependent_comparison
Abstract
使用原生 SQL 會造成可攜性問題。
Explanation
SAP 系統專為實現平台獨立而設計。Open SQL 是 SAP 的可攜式 SQL 變體語言,可使應用程式獨立於特定資料庫廠商的 JDBC 驅動程式。Open SQL 的使用可以讓基礎資料庫化繁為簡,並為所有資料庫作業提供一種通用的應用程式介面。但是,原生 SQL 特定用於基礎資料庫,因此對其他平台使用原生 SQL 可能導致應用程式邏輯執行錯誤,並可能導致阻斷服務。
範例 1:以下程式碼使用原生 SQL:


...
import java.sql.PreparedStatement;
import com.sap.sql.NativeSQLAccess;

String mssOnlyStmt = "...";
// variant 1
PreparedStatement ps =
NativeSQLAccess.prepareNativeStatement(
conn, mssOnlyStmt);
. . .
// variant 2
Statement stmt =
NativeSQLAccess.createNativeStatement(conn);
int result = stmt.execute(mssOnlyStmt);
. . .
// variant 3
CallableStatement cs =
NativeSQLAccess.prepareNativeCall(
conn, mssOnlyStmt);
. . .
References
[1] Standards Mapping - CIS Azure Kubernetes Service Benchmark 1
[2] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 5
[3] Standards Mapping - CIS Amazon Web Services Foundations Benchmark 1
[4] Standards Mapping - CIS Google Kubernetes Engine Benchmark normal
[5] Standards Mapping - Common Weakness Enumeration CWE ID 474
desc.structural.java.portability_flaw_native_sql
Abstract
將靜態欄位指派給新物件會呼叫建構函式,即使它依賴於其他變數初始化也是如此,這可能會導致物件錯誤地進行初始化。
Explanation
初始化 Java 類別時,會在類別建構函式之前,針對此類別中宣告的靜態欄位,呼叫初始設定式。這表示,指派給此項的建構函式會在其他程式碼之前被呼叫,如果此建構函式接著依賴於正要初始化的其他欄位或變數,將可能產生部分初始化的物件,或是使用不正確的值初始化的物件。

範例 1:以下類別會宣告靜態欄位,並將其指派給新物件。


...
public class Box{
public int area;
public static final int width = 10;
public static final Box box = new Box();
public static final int height = (int) (Math.random() * 100);

public Box(){
area = width * height;
}
...
}
...


Example 1 中,開發人員預期 box.area 會是一個隨機整數,這正好是 10 的倍數,因為 width 等於 10。然而實際上,它的硬式編碼值始終是 0。使用編譯時間常數宣告的靜態 final 欄位會先進行初始化,然後依序執行每個欄位。這表示,由於 height 不是編譯時間常數,所以會在宣告 box 之後宣告,因此,會在初始化 height 欄位之前呼叫建構函式。

範例 2:以下類別所宣告的靜態欄位彼此相依。


...
class Foo{
public static final int f = Bar.b - 1;
...
}
...
class Bar{
public static final int b = Foo.f + 1;
...
}

This example is perhaps easier to identify, but would be dependent on which class is loaded first by the JVM. In this example Foo.f could be either -1 or 0, and Bar.b could be either 0 or 1.
References
[1] DCL00-J. Prevent class initialization cycles CERT
[2] Standards Mapping - CIS Azure Kubernetes Service Benchmark 1
[3] Standards Mapping - CIS Microsoft Azure Foundations Benchmark complete
[4] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 2
[5] Standards Mapping - CIS Amazon Web Services Foundations Benchmark 4
[6] Standards Mapping - CIS Google Kubernetes Engine Benchmark integrity
[7] Standards Mapping - CIS Kubernetes Benchmark partial
[8] Standards Mapping - Common Weakness Enumeration CWE ID 362, CWE ID 367
[9] Standards Mapping - Common Weakness Enumeration Top 25 2022 [22] CWE ID 362
[10] Standards Mapping - Common Weakness Enumeration Top 25 2023 [21] CWE ID 362
[11] Standards Mapping - DISA Control Correlation Identifier Version 2 CCI-003178
[12] Standards Mapping - General Data Protection Regulation (GDPR) Indirect Access to Sensitive Data
[13] Standards Mapping - OWASP Top 10 2021 A04 Insecure Design
[14] Standards Mapping - OWASP Application Security Verification Standard 4.0 1.11.2 Business Logic Architectural Requirements (L2 L3), 1.11.3 Business Logic Architectural Requirements (L3), 11.1.6 Business Logic Security Requirements (L2 L3)
[15] Standards Mapping - Payment Card Industry Data Security Standard Version 3.0 Requirement 6.5.6
[16] Standards Mapping - Payment Card Industry Data Security Standard Version 3.2 Requirement 6.5.6
[17] Standards Mapping - Payment Card Industry Data Security Standard Version 3.2.1 Requirement 6.5.6
[18] Standards Mapping - Payment Card Industry Data Security Standard Version 3.1 Requirement 6.5.6
[19] Standards Mapping - Payment Card Industry Data Security Standard Version 4.0 Requirement 6.2.4
[20] Standards Mapping - Payment Card Industry Software Security Framework 1.0 Control Objective 4.2 - Critical Asset Protection
[21] Standards Mapping - Payment Card Industry Software Security Framework 1.1 Control Objective 4.2 - Critical Asset Protection, Control Objective B.3.3 - Terminal Software Attack Mitigation
[22] Standards Mapping - Payment Card Industry Software Security Framework 1.2 Control Objective 4.2 - Critical Asset Protection, Control Objective B.3.3 - Terminal Software Attack Mitigation
[23] Standards Mapping - SANS Top 25 2009 Insecure Interaction - CWE ID 362
[24] Standards Mapping - SANS Top 25 2010 Insecure Interaction - CWE ID 362
[25] Standards Mapping - Security Technical Implementation Guide Version 3.1 APP3630.1 CAT II
[26] Standards Mapping - Security Technical Implementation Guide Version 3.4 APP3630.1 CAT II
[27] Standards Mapping - Security Technical Implementation Guide Version 3.5 APP3630.1 CAT II
[28] Standards Mapping - Security Technical Implementation Guide Version 3.6 APP3630.1 CAT II
[29] Standards Mapping - Security Technical Implementation Guide Version 3.7 APP3630.1 CAT II
[30] Standards Mapping - Security Technical Implementation Guide Version 3.9 APP3630.1 CAT II
[31] Standards Mapping - Security Technical Implementation Guide Version 3.10 APP3630.1 CAT II
[32] Standards Mapping - Security Technical Implementation Guide Version 4.1 APSC-DV-001995 CAT II
[33] Standards Mapping - Security Technical Implementation Guide Version 4.2 APSC-DV-001995 CAT II
[34] Standards Mapping - Security Technical Implementation Guide Version 4.3 APSC-DV-001995 CAT II
[35] Standards Mapping - Security Technical Implementation Guide Version 4.4 APSC-DV-001995 CAT II
[36] Standards Mapping - Security Technical Implementation Guide Version 4.5 APSC-DV-001995 CAT II
[37] Standards Mapping - Security Technical Implementation Guide Version 4.6 APSC-DV-001995 CAT II
[38] Standards Mapping - Security Technical Implementation Guide Version 4.7 APSC-DV-001995 CAT II
[39] Standards Mapping - Security Technical Implementation Guide Version 4.8 APSC-DV-001995 CAT II
[40] Standards Mapping - Security Technical Implementation Guide Version 4.9 APSC-DV-001995 CAT II
[41] Standards Mapping - Security Technical Implementation Guide Version 4.10 APSC-DV-001995 CAT II
[42] Standards Mapping - Security Technical Implementation Guide Version 4.11 APSC-DV-001995 CAT II
[43] Standards Mapping - Security Technical Implementation Guide Version 5.1 APSC-DV-001995 CAT II
[44] Standards Mapping - Security Technical Implementation Guide Version 5.2 APSC-DV-001995 CAT II
[45] Standards Mapping - Security Technical Implementation Guide Version 5.3 APSC-DV-001995 CAT II
desc.structural.java.race_condition_class_initialization_cycle
Abstract
程式可能解除參照一個 Null 指標,造成分段錯誤。
Explanation
Null 指標異常通常是由於一個或者多個程式設計師的假設遭到破解而造成的。此問題至少有三項特點:解除參照之後檢查、檢查後解除參照及儲存後解除參照。當程式在檢查指標是否為 null 之前先解除參照可能為 null 的指標,將會造成「解除參照之後檢查」的錯誤。當程式執行明確的 null 檢查,但仍繼續解除參照已知為 null 的指標時,將會造成「檢查後解除參照」的錯誤。這種類型的錯誤通常是打字錯誤或程式設計師的疏忽所造成。當程式明確的將某指標設定為 null,卻在之後解除參考該指標,則會發生儲存後解除參照錯誤。這種錯誤通常是由於程式設計師在宣告變數時將變數初始化為 null 所致。

大部分的 Null 指標問題都會導致一般軟體可靠性問題,但是如果攻擊者蓄意觸發 Null 指標解除參照的話,攻擊者就可能會使用引發的異常來略過安全性邏輯以掛載 Denial of Service 攻擊,或是使應用程式洩漏出除錯資訊,這些資訊對於計畫後續攻擊很有價值。

範例 1:在以下程式碼中,程式設計師確定物件 foonull,並在之後以錯誤的方式解除參照。在 if 陳述式中檢查 foo 時,若其為 null,便會發生 null 解除參照,因此造成 Null 指標異常。


if (foo is null) {
foo.SetBar(val);
...
}
範例 2:在以下程式碼中,程式設計師會假設 foo 變數不是 null,並解除參照物件來確認這項假設。不過,程式設計師之後將對照 null 檢查 foo,來反駁這項假設。在 if 陳述式中檢查 foo 時,若其為 null,則在解除參照時也可為 null,並有可能會造成 Null 指標異常。解除參照不安全,後續檢查也不必要。


foo.SetBar(val);
...
if (foo is not null) {
...
}
範例 3:在以下程式碼中,程式設計師明確地將變數 foo 設定為 null。之後,程式設計師先解除參照 foo,再檢查物件是否為 null 值。


Foo foo = null;
...
foo.SetBar(val);
...
}
desc.controlflow.dotnet.redundant_null_check
Abstract
程式可能解除參照一個 Null 指標,造成分段錯誤。
Explanation
Null 指標異常通常是由於一個或者多個程式設計師的假設遭到破解而造成的。此問題至少有三項特點:解除參照之後檢查、檢查後解除參照及儲存後解除參照。當程式在檢查指標是否為 null 之前先解除參照可能為 null 的指標,將會造成「解除參照之後檢查」的錯誤。當程式執行明確的 null 檢查,但仍繼續解除參照已知為 null 的指標時,將會造成「檢查後解除參照」的錯誤。這種類型的錯誤通常是打字錯誤或程式設計師的疏忽所造成。當程式明確的將某指標設定為 null,卻在之後解除參考該指標,則會發生儲存後解除參照錯誤。這種錯誤通常是由於程式設計師在宣告變數時將變數初始化為 null 所致。

大部分的 Null 指標問題都會導致一般軟體可靠性問題,但是如果攻擊者蓄意觸發 Null 指標解除參照的話,攻擊者就可能會使用引發的異常來略過安全性邏輯以掛載 Denial of Service 攻擊,或是使應用程式洩漏出除錯資訊,這些資訊對於計畫後續攻擊很有價值。

範例 1:在以下程式碼中,程式設計師假設變數 ptr 不是 NULL。當程式設計師取消參照指標時,這個假設就變得清楚。當程式設計師檢查 ptrNULL 時,這個假設其實就出現其矛盾之處。若在 if 指令中檢查 ptr 時,其可為 NULL,則解除參照時也可為 NULL,並產生分段錯誤。


ptr->field = val;
...
if (ptr != NULL) {
...
}
範例 2:在以下程式碼中,程式設計師確定變數 ptrNULL,並在之後以錯誤的方式解除參照。若在 if 陳述式中檢查 ptr 時,其非 NULL,就會發生 null 解除參照,從而導致分段錯誤。


if (ptr == null) {
ptr->field = val;
...
}
範例 3:在以下程式碼中,程式設計師忘記了字串 '\0' 實際上是 0 還是 NULL,因此解除參照 Null 指標,並導致分段錯誤。


if (ptr == '\0') {
*ptr = val;
...
}
範例 4:在以下程式碼中,程式設計師明確地將變數 ptr 設定為 NULL。之後,程式設計師先解除參照 ptr,再檢查物件是否為 null 值。


*ptr = NULL;
...
ptr->field = val;
...
}
desc.controlflow.cpp.redundant_null_check
Abstract
程式可能會解除參照 Null 指標,因此造成 Null 指標異常。
Explanation
Null 指標異常通常是由於一個或者多個程式設計師的假設遭到破解而造成的。特別是,當程式執行明確的 null 檢查,但仍繼續解除參照已知為 null 的物件時,將會造成「解除參照之後檢查」的錯誤。這種類型的錯誤通常是打字錯誤或程式設計師的疏忽所造成。

大部分的 Null 指標問題都會導致一般的軟體可靠性問題,但如果攻擊者蓄意造成程式解除參照 Null 指標的話,他們就可能可以使用引發的異常來掛載 Denial of Service 攻擊,或是使應用程式洩漏出除錯資訊,這些資訊對於計畫後續攻擊很有利用價值。

範例 1:在以下程式碼中,程式設計師確定變數 foonull,並在之後以錯誤的方式解除參照。在 if 陳述式中檢查 foo 時,若其為 null,便會發生 null 解除參照,因此造成 Null 指標異常。


if (foo == null) {
foo.setBar(val);
...
}
desc.internal.java.null_dereference_dereference_after_check
Abstract
函數未指定明確存取修飾符。
Explanation
在制訂 Solidity 智慧合約時,開發人員可以設定函數的存取修飾符來控制誰可以叫用它。如果開發人員未指定存取修飾符,則函數將預設為 public,從而允許惡意動作執行者在未經授權的情況下叫用該函數。

範例 1:以下程式碼無法在這兩個函數中設定存取修飾符,因此任何人都可以叫用它們,從而允許使用者略過對 require 的呼叫。


function withdrawWinnings() {
require(uint32(msg.sender) == 0);
_sendWinnings();
}

function _sendWinnings() {
msg.sender.transfer(this.balance);
}
References
[1] Enterprise Ethereum Alliance Code Linting
[2] Standards Mapping - CIS Azure Kubernetes Service Benchmark 5
[3] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 5
[4] Standards Mapping - CIS Amazon Web Services Foundations Benchmark 3
[5] Standards Mapping - CIS Google Kubernetes Engine Benchmark normal
[6] Standards Mapping - Common Weakness Enumeration CWE ID 710
[7] Standards Mapping - Smart Contract Weakness Classification SWC-100
desc.structural.solidity.swc100
Abstract
函數將合約餘額與特定的以太幣 (Ether) 值進行比較。
Explanation
假設合約具有特定的以太幣 (Ether) 餘額可能會導致錯誤或意外的行為,這是因為合約的餘額可以被強制更改,例如透過將以太幣 (Ether) 傳送到合約的方式。

範例 1:以下程式碼使用 assert 來檢查 Lock 合約執行個體的餘額是否為特定值 (msg.value)。


contract Lock {
constructor (address owner, uint256 unlockTime) public payable {
...
}
}

contract Lockdrop {
...
function lock(...) {
uint256 eth = msg.value;
address owner = msg.sender;
uint256 unlockTime = unlockTimeForTerm(term);

Lock lockAddr = (new Lock).value(eth)(owner, unlockTime);

assert(address(lockAddr).balance == msg.value);
}
}
References
[1] Enterprise Ethereum Alliance No Exact Balance Check
[2] Standards Mapping - CIS Azure Kubernetes Service Benchmark 2
[3] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 5
[4] Standards Mapping - CIS Amazon Web Services Foundations Benchmark 3
[5] Standards Mapping - CIS Google Kubernetes Engine Benchmark normal
[6] Standards Mapping - Common Weakness Enumeration CWE ID 710
[7] Standards Mapping - Smart Contract Weakness Classification SWC-132
desc.structural.solidity.swc132
Abstract
合約定義了固定燃料量或叫用具有固定燃料量的函數。
Explanation
燃料交易成本可能會根據當前網路狀況而異,例如,硬分叉期間 EVM (以太坊虛擬機器) 指令的燃料成本可能會受到顯著影響。這可能會打破仰賴固定燃料量的現有功能,也可能影響用於價值轉移的交易,例如 transfer()send(),其使用 2300 的固定燃料量。

範例 1:以下程式碼執行呼用並指定固定燃料量。


interface ICallable {
function callMe() external;
}

contract HardcodedNotGood {
function callWithArgs() public {
callable.callMe{gas: 10000}();
}
}
References
[1] Enterprise Ethereum Alliance Gas and Gas Prices
[2] Standards Mapping - CIS Azure Kubernetes Service Benchmark 2
[3] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 5
[4] Standards Mapping - CIS Amazon Web Services Foundations Benchmark 3
[5] Standards Mapping - CIS Google Kubernetes Engine Benchmark normal
[6] Standards Mapping - Common Weakness Enumeration CWE ID 665
[7] Standards Mapping - Smart Contract Weakness Classification SWC-134
desc.structural.solidity.swc134