界: Input Validation and Representation
輸入驗證和表示法問題是由中繼字元、替代編碼和數值表示法引起的。信任輸入會導致安全問題。問題包括:「Buffer Overflows」、「Cross-Site Scripting」攻擊、「SQL Injection」及其他許多問題。
Buffer Overflow
Abstract
在分派的記憶體區塊界線外寫入資料會導致資料毀損、程式當機或惡意程式碼的執行。
Explanation
Buffer overflow 可能是軟體安全性弱點最為人知的一種形式。大部分軟體開發人員都知道什麼是 Buffer overflow 弱點,但傳統和新開發的應用程式仍常遭到 Buffer overflow 攻擊。此問題的部份原因是,發生 Buffer overflow 的方式很多,部分原因是人們常常用不恰當的方式來防範 Buffer overflow。
在典型的 Buffer overflow 攻擊中,攻擊者會將資料傳送到程式,而程式會將其儲存在一個較小的堆疊緩衝區內。結果就是呼叫這個堆疊的資訊超出了它的邊界,其中包括函數的回傳指標。該資料設定了回傳指標的值,當函數回傳時,會將控制傳送到攻擊者資料所包含的惡意程式碼。
這類型的堆疊 Buffer overflow 在一些平台和開發社群中仍然很常見,但卻還有多種其他類型的 Buffer overflow,包括堆積 Buffer overflow 和差一錯誤 (off-by-one-error) 等等。有許多優秀的著作提供了關於堆疊 Buffer overflow 如何攻擊的具體資訊,包括 Building Secure Software[1]、Writing Secure Code[2]和 The Shellcoder's Handbook[3]。
在程式碼層級,會發生 Buffer overflow 弱點通常是因為程式設計師的假設被推翻。許多在 C 和 C++ 的記憶體操作函數不執行範圍檢查,且可以輕易地覆寫所操作的緩衝區已分配的範圍。甚至如
Buffer overflow 弱點通常出現在這樣的程式碼中:
- 依靠外部資料來控制運作方式者。
- 仰賴被強制位於程式碼臨接範圍外的資料特性者。
- 程式碼複雜到程式設計師不能準確預測到其運作方式者。
以下範例顯示了這三種情況。
範例 1.a:接下來的程式碼範例展示了通常由第一種情況導致的簡單 Buffer overflow,即靠外部資料控制運作方式者。程式碼使用
注意:這個類型的 Buffer overflow 弱點 (程式讀取資料,然後信賴其他資料上後續記憶體操作中的一個數值) 在圖形、音頻和其他的檔案處理庫中發生次數頻繁。
範例 3:這是第二種情況的範例,其中的程式碼根據非本地驗證的資料特性而異。在這個範例中,一個名為
該程式碼似乎能安全執行界限檢查,因為它檢查了變數長度的大小,之後這會被用來控制
雖然這個範例中的程式碼不是我們所見到的當中最複雜的一個,但是它解釋了為什麼執行緩衝區操作的程式碼的複雜度應該減到最低。
在典型的 Buffer overflow 攻擊中,攻擊者會將資料傳送到程式,而程式會將其儲存在一個較小的堆疊緩衝區內。結果就是呼叫這個堆疊的資訊超出了它的邊界,其中包括函數的回傳指標。該資料設定了回傳指標的值,當函數回傳時,會將控制傳送到攻擊者資料所包含的惡意程式碼。
這類型的堆疊 Buffer overflow 在一些平台和開發社群中仍然很常見,但卻還有多種其他類型的 Buffer overflow,包括堆積 Buffer overflow 和差一錯誤 (off-by-one-error) 等等。有許多優秀的著作提供了關於堆疊 Buffer overflow 如何攻擊的具體資訊,包括 Building Secure Software[1]、Writing Secure Code[2]和 The Shellcoder's Handbook[3]。
在程式碼層級,會發生 Buffer overflow 弱點通常是因為程式設計師的假設被推翻。許多在 C 和 C++ 的記憶體操作函數不執行範圍檢查,且可以輕易地覆寫所操作的緩衝區已分配的範圍。甚至如
strncpy()
的範圍函數,使用不正確時也會引起弱點。大多數 Buffer overflow 弱點的根本原因,都是緩衝區的處理,加上對資料的大小或組成假設錯誤。Buffer overflow 弱點通常出現在這樣的程式碼中:
- 依靠外部資料來控制運作方式者。
- 仰賴被強制位於程式碼臨接範圍外的資料特性者。
- 程式碼複雜到程式設計師不能準確預測到其運作方式者。
以下範例顯示了這三種情況。
範例 1.a:接下來的程式碼範例展示了通常由第一種情況導致的簡單 Buffer overflow,即靠外部資料控制運作方式者。程式碼使用
gets()
函數,將一個任意長度的資料讀取到堆疊緩衝區。因為沒有什麼方法可以限制這個函數讀取的資料量,所以使用者輸入的字元數必須少於 BUFSIZE
,以確保程式碼的安全性。範例 1.b:此範例顯示只要使用
...
char buf[BUFSIZE];
gets(buf);
...
>>
運算子將輸入讀取到 char[]
字串中,即可輕易模仿 C++ 中 gets()
函數不安全的運作方式。範例 2:雖然這個範例中的程式碼也是依賴於使用者的輸入來控制它的運作方式,但是它會藉由使用邊界記憶體複製函數
...
char buf[BUFSIZE];
cin >> (buf);
...
memcpy()
增加一個間接的層面。此函數接受目的緩衝區、來源緩衝區,以及要複製的位元組數量。輸入緩衝區由 read()
的範圍呼叫所填滿,但使用者指定 memcpy()
要複製的位元組數量。
...
char buf[64], in[MAX_SIZE];
printf("Enter buffer contents:\n");
read(0, in, MAX_SIZE-1);
printf("Bytes to copy:\n");
scanf("%d", &bytes);
memcpy(buf, in, bytes);
...
注意:這個類型的 Buffer overflow 弱點 (程式讀取資料,然後信賴其他資料上後續記憶體操作中的一個數值) 在圖形、音頻和其他的檔案處理庫中發生次數頻繁。
範例 3:這是第二種情況的範例,其中的程式碼根據非本地驗證的資料特性而異。在這個範例中,一個名為
lccopy()
的函數將一個字串做為引數讀取,然後將這個字串中所有的大寫字母轉化成小寫字母回傳一個堆疊分配的字串副本。這個函數不會對其輸入執行範圍檢查,因為程式預期 str
始終小於 BUFSIZE
。如果攻擊者避開對呼叫 lccopy()
的程式碼的測試,或者,如果程式碼有什麼變化,使得關於 str
長度的假設失真,那麼 lccopy()
就會在 strcpy()
超出邊界的呼叫過程中溢位 buf
。範例 4:下列程式碼示範了第三種情況,其中程式碼太過複雜以致無法輕易預測其行為。這段程式碼來自於主流的 libPNG 圖像解碼器,此解碼器廣泛用於多種應用程式。
char *lccopy(const char *str) {
char buf[BUFSIZE];
char *p;
strcpy(buf, str);
for (p = buf; *p; p++) {
if (isupper(*p)) {
*p = tolower(*p);
}
}
return strdup(buf);
}
該程式碼似乎能安全執行界限檢查,因為它檢查了變數長度的大小,之後這會被用來控制
png_crc_read()
複製的資料量。不過,在測試長度之前,程式碼會立即對 png_ptr->mode
執行檢查。檢查失敗時,系統會發出警告,而處理會繼續執行下去。由於 length
會在一個 else if
區塊中進行測試,所以當第一個檢查失敗時,就不會測試 length
;且在呼叫 png_crc_read()
期間對其的盲目使用易引發堆疊 Buffer overflow。雖然這個範例中的程式碼不是我們所見到的當中最複雜的一個,但是它解釋了為什麼執行緩衝區操作的程式碼的複雜度應該減到最低。
範例 5:此範例同樣證明了第三種情況,程式的複雜性將 Buffer overflow 的問題暴露出來。在此案例中,弱點歸咎於函數某個不明確的介面,而不是程式碼的結構 (就如同前面一個範例中所描述的)。
if (!(png_ptr->mode & PNG_HAVE_PLTE)) {
/* Should be an error, but we can cope with it */
png_warning(png_ptr, "Missing PLTE before tRNS");
}
else if (length > (png_uint_32)png_ptr->num_palette) {
png_warning(png_ptr, "Incorrect tRNS chunk length");
png_crc_finish(png_ptr, length);
return;
}
...
png_crc_read(png_ptr, readbuf, (png_size_t)length);
getUserInfo()
函數採用一個定義為多位元組字元串的使用者名和一個指標來組成使用者資訊的結構,並將使用者資訊填入這個結構。因為 Windows 對使用者名稱的 authentication 是使用統一的字元編碼標準,所以 username
是第一個從多位元組字元串轉換成統一字元編碼標準的字串的參數。函數接著會不正確地以位元組而非字元傳送 unicodeUser
的大小。呼叫 MultiByteToWideChar()
可能會因此而將最多 (UNLEN+1)*sizeof(WCHAR)
個寬字元,或(UNLEN+1)*sizeof(WCHAR)*sizeof(WCHAR)
個位元組寫入 unicodeUser
陣列,而僅為該陣列分配了 (UNLEN+1)*sizeof(WCHAR)
個位元組。如果 username
字串包含了多於 UNLEN
的字元,那麼呼叫 MultiByteToWideChar()
將會溢出 unicodeUser
緩衝區。
void getUserInfo(char *username, struct _USER_INFO_2 info){
WCHAR unicodeUser[UNLEN+1];
MultiByteToWideChar(CP_ACP, 0, username, -1,
unicodeUser, sizeof(unicodeUser));
NetUserGetInfo(NULL, unicodeUser, 2, (LPBYTE *)&info);
}
References
[1] J. Viega, G. McGraw Building Secure Software Addison-Wesley
[2] M. Howard, D. LeBlanc Writing Secure Code, Second Edition Microsoft Press
[3] J. Koziol et al. The Shellcoder's Handbook: Discovering and Exploiting Security Holes John Wiley & Sons
[4] About Strsafe.h Microsoft
[5] Standards Mapping - CIS Azure Kubernetes Service Benchmark 4.0
[6] Standards Mapping - CIS Microsoft Azure Foundations Benchmark complete
[7] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 4.0
[8] Standards Mapping - CIS Amazon Web Services Foundations Benchmark 3
[9] Standards Mapping - CIS Google Cloud Computing Platform Benchmark complete
[10] Standards Mapping - CIS Google Kubernetes Engine Benchmark integrity
[11] Standards Mapping - CIS Kubernetes Benchmark complete
[12] Standards Mapping - Common Weakness Enumeration CWE ID 120, CWE ID 129, CWE ID 131, CWE ID 787
[13] Standards Mapping - Common Weakness Enumeration Top 25 2019 [1] CWE ID 119, [3] CWE ID 020, [12] CWE ID 787
[14] Standards Mapping - Common Weakness Enumeration Top 25 2020 [5] CWE ID 119, [3] CWE ID 020, [2] CWE ID 787
[15] Standards Mapping - Common Weakness Enumeration Top 25 2021 [1] CWE ID 787, [4] CWE ID 020, [17] CWE ID 119
[16] Standards Mapping - Common Weakness Enumeration Top 25 2022 [1] CWE ID 787, [4] CWE ID 020, [19] CWE ID 119
[17] Standards Mapping - Common Weakness Enumeration Top 25 2023 [1] CWE ID 787, [6] CWE ID 020, [17] CWE ID 119
[18] Standards Mapping - DISA Control Correlation Identifier Version 2 CCI-002754, CCI-002824
[19] Standards Mapping - General Data Protection Regulation (GDPR) Indirect Access to Sensitive Data
[20] Standards Mapping - Motor Industry Software Reliability Association (MISRA) C Guidelines 2012 Rule 1.3
[21] Standards Mapping - Motor Industry Software Reliability Association (MISRA) C++ Guidelines 2008 Rule 0-3-1, Rule 18-0-5
[22] Standards Mapping - NIST Special Publication 800-53 Revision 4 SI-10 Information Input Validation (P1), SI-16 Memory Protection (P1)
[23] Standards Mapping - NIST Special Publication 800-53 Revision 5 SI-10 Information Input Validation, SI-16 Memory Protection
[24] Standards Mapping - OWASP Top 10 2004 A5 Buffer Overflow
[25] Standards Mapping - OWASP Top 10 2013 A1 Injection
[26] Standards Mapping - OWASP Top 10 2017 A1 Injection
[27] Standards Mapping - OWASP Application Security Verification Standard 4.0 5.1.3 Input Validation Requirements (L1 L2 L3), 5.1.4 Input Validation Requirements (L1 L2 L3), 5.4.1 Memory/String/Unmanaged Code Requirements (L1 L2 L3), 5.4.2 Memory/String/Unmanaged Code Requirements (L1 L2 L3), 14.1.2 Build (L2 L3)
[28] Standards Mapping - OWASP Mobile 2014 M7 Client Side Injection
[29] Standards Mapping - OWASP Mobile 2024 M4 Insufficient Input/Output Validation
[30] Standards Mapping - OWASP Mobile Application Security Verification Standard 2.0 MASVS-CODE-4
[31] Standards Mapping - Payment Card Industry Data Security Standard Version 1.1 Requirement 6.5.5
[32] Standards Mapping - Payment Card Industry Data Security Standard Version 1.2 Requirement 6.3.1.1
[33] Standards Mapping - Payment Card Industry Data Security Standard Version 2.0 Requirement 6.5.2
[34] Standards Mapping - Payment Card Industry Data Security Standard Version 3.0 Requirement 6.5.2
[35] Standards Mapping - Payment Card Industry Data Security Standard Version 3.1 Requirement 6.5.2
[36] Standards Mapping - Payment Card Industry Data Security Standard Version 3.2 Requirement 6.5.2
[37] Standards Mapping - Payment Card Industry Data Security Standard Version 3.2.1 Requirement 6.5.2
[38] Standards Mapping - Payment Card Industry Data Security Standard Version 4.0 Requirement 6.2.4
[39] Standards Mapping - Payment Card Industry Software Security Framework 1.0 Control Objective 4.2 - Critical Asset Protection
[40] Standards Mapping - Payment Card Industry Software Security Framework 1.1 Control Objective 4.2 - Critical Asset Protection, Control Objective B.3.1 - Terminal Software Attack Mitigation, Control Objective B.3.1.1 - Terminal Software Attack Mitigation, Control Objective B.3.1.2 - Terminal Software Attack Mitigation
[41] Standards Mapping - Payment Card Industry Software Security Framework 1.2 Control Objective 4.2 - Critical Asset Protection, Control Objective B.3.1 - Terminal Software Attack Mitigation, Control Objective B.3.1.1 - Terminal Software Attack Mitigation, Control Objective B.3.1.2 - Terminal Software Attack Mitigation, Control Objective C.3.2 - Web Software Attack Mitigation
[42] Standards Mapping - SANS Top 25 2009 Risky Resource Management - CWE ID 119
[43] Standards Mapping - SANS Top 25 2010 Risky Resource Management - CWE ID 120, Risky Resource Management - CWE ID 129, Risky Resource Management - CWE ID 131
[44] Standards Mapping - SANS Top 25 2011 Risky Resource Management - CWE ID 120, Risky Resource Management - CWE ID 131
[45] Standards Mapping - Security Technical Implementation Guide Version 3.1 APP3510 CAT I, APP3590.1 CAT I
[46] Standards Mapping - Security Technical Implementation Guide Version 3.4 APP3510 CAT I, APP3590.1 CAT I
[47] Standards Mapping - Security Technical Implementation Guide Version 3.5 APP3510 CAT I, APP3590.1 CAT I
[48] Standards Mapping - Security Technical Implementation Guide Version 3.6 APP3510 CAT I, APP3590.1 CAT I
[49] Standards Mapping - Security Technical Implementation Guide Version 3.7 APP3510 CAT I, APP3590.1 CAT I
[50] Standards Mapping - Security Technical Implementation Guide Version 3.9 APP3510 CAT I, APP3590.1 CAT I
[51] Standards Mapping - Security Technical Implementation Guide Version 3.10 APP3510 CAT I, APP3590.1 CAT I
[52] Standards Mapping - Security Technical Implementation Guide Version 4.1 APSC-DV-002560 CAT I, APSC-DV-002590 CAT I
[53] Standards Mapping - Security Technical Implementation Guide Version 4.2 APSC-DV-002560 CAT I, APSC-DV-002590 CAT I
[54] Standards Mapping - Security Technical Implementation Guide Version 4.3 APSC-DV-002560 CAT I, APSC-DV-002590 CAT I
[55] Standards Mapping - Security Technical Implementation Guide Version 4.4 APSC-DV-002560 CAT I, APSC-DV-002590 CAT I
[56] Standards Mapping - Security Technical Implementation Guide Version 4.5 APSC-DV-002560 CAT I, APSC-DV-002590 CAT I
[57] Standards Mapping - Security Technical Implementation Guide Version 4.6 APSC-DV-002560 CAT I, APSC-DV-002590 CAT I
[58] Standards Mapping - Security Technical Implementation Guide Version 4.7 APSC-DV-002560 CAT I, APSC-DV-002590 CAT I
[59] Standards Mapping - Security Technical Implementation Guide Version 4.8 APSC-DV-002560 CAT I, APSC-DV-002590 CAT I
[60] Standards Mapping - Security Technical Implementation Guide Version 4.9 APSC-DV-002560 CAT I, APSC-DV-002590 CAT I
[61] Standards Mapping - Security Technical Implementation Guide Version 4.10 APSC-DV-002560 CAT I, APSC-DV-002590 CAT I
[62] Standards Mapping - Security Technical Implementation Guide Version 4.11 APSC-DV-002560 CAT I, APSC-DV-002590 CAT I
[63] Standards Mapping - Security Technical Implementation Guide Version 5.1 APSC-DV-002560 CAT I, APSC-DV-002590 CAT I
[64] Standards Mapping - Security Technical Implementation Guide Version 5.2 APSC-DV-002560 CAT I, APSC-DV-002590 CAT I
[65] Standards Mapping - Security Technical Implementation Guide Version 5.3 APSC-DV-002530 CAT II, APSC-DV-002560 CAT I, APSC-DV-002590 CAT I
[66] Standards Mapping - Web Application Security Consortium Version 2.00 Buffer Overflow (WASC-07)
[67] Standards Mapping - Web Application Security Consortium 24 + 2 Buffer Overflow
desc.dataflow.cpp.buffer_overflow