แก้ไขลวดลายจุดเชื่อมต่อStencils
วิธี เขียน รหัส C เพื่อ ป้องกัน การ เกิด เหตุ
Table of Contents
Bruffs ท่วมท้นไปด้วยความปลอดภัยที่ต่อเนื่องและอันตรายที่สุดอย่างหนึ่งในโปรแกรม C แม้ว่าจะถูกวางแผงอย่างดีมาหลายทศวรรษแล้วก็ตาม พวกเขายังคงก่อปัญหาร้ายแรงเช่นการทุจริตข้อมูล ระบบล่ม ระบบคอมพิวเตอร์ และรหัสรหัสคอมพิวเตอร์ระยะไกล การเขียนรหัสซีต้องเข้าใจอย่างลึกซึ้งว่าสารบัฟเฟอร์มีมากขนาดไหน และวิธีการจัดการอย่างมีวินัยเพื่อป้องกันมัน บทความนี้ยังเป็นคู่มือในการเขียนโค้ดแบบครอบคลุม, การครอบคลุมแบบครอบคลุม, การครอบคลุมพื้นฐาน, การรักษาความปลอดภัย, เทคนิคความปลอดภัย, และมาตรการที่ทันสมัย
การ เข้าใจ ความ รู้สึก ของ ผู้ คน มาก เกิน ไป
การเยื้องของบัฟเฟอร์จะเกิดขึ้นเมื่อโปรแกรมเขียนข้อมูลไปยังบล็อกหน่วยความจําแบบต่อเนื่อง (เป็นบัฟเฟอร์) มากกว่าการรวมบัฟเฟอร์ไว้เก็บ เนื่องจากบัฟเฟอร์อยู่ในกองหรือกองหน่วยความจํา การทุจริตนี้สามารถเปลี่ยนแปลงสถานะโปรแกรมได้โดยเพิ่มสถานะไม่ได้, แนะนําพฤติกรรมที่คาดเดาไม่ได้ หรือถูกบริโภคโดยผู้โจมตีในการฉีดและประมวลผลโค้ดตามใจ
ผลที่จะตามมาขึ้นอยู่กับว่าจะเกิดอะไรขึ้นมากกว่า การเขียนที่อยู่การตอบกลับบนกอง สามารถเปลี่ยนการประมวลผลเป็นรหัสที่ควบคุมการเข้าโจมตีได้ การเขียนมากกว่าตัวชี้ของตัวชี้ของหน่วยความจําสามารถนําไปสู่การเขียนได้ แม้การชนธรรมดาก็สามารถเพิ่มข้อมูลการปฏิเสธการให้บริการได้ การเข้าใจกลไกคือขั้นตอนแรกในการป้องกัน
น้ําท่วมแบบทับถม
ตัวแปรภายใน รวมถึงบัฟเฟอร์ที่เปิดใช้อยู่ภายในฟังก์ชัน จะถูกเก็บไว้บนสแต็ก สแต็กยังเก็บที่อยู่การตอบกลับไว้ เช่น บันทึกตัวชี้ของเฟรม และข้อมูลควบคุมอื่น ๆ เมื่อมีการเพิ่มข้อมูลแบบ [FLT: 0] เก็บข้อมูลเข้าที่อยู่แบบชั่วคราวเช่นหนอนมอร์ริส (1988) ซึ่งใช้กองข้อมูลเพื่อเข้าถึงข้อมูลที่ไม่ได้รับอนุญาต
น้ําท่วมที่ร้อนจัด
การดูดซึมแบบไม่ตายตัว (FLT:1) [FT:2]] ] อาศัยอยู่ตามกองหินที่นี่ กระแสน้ําสามารถทุจริตข้อมูลที่ใช้ในการใช้งานของ Allocator, นําไปสู่การเกิดอุบัติเหตุ หรือการหาประโยชน์ทางการบริโภคผ่านทางการพ่นควัน หรือการใช้หลังการจู่โจมอย่างไม่มีการใช้งาน เทือกเขาที่ไหลท่วมได้ยากขึ้นแต่อันตรายพอๆกัน
การ ทํา งาน ที่ ทํา ได้ ง่าย ทั่ว ไป และ วิธี ที่ ปลอด ภัย
ห้อง สมุด มาตรฐาน C มี หลาย อย่าง ที่ ไม่ ได้ ทํา การ ตรวจ สอบ ขอบ เขต.
สําเนา และ การ รวม ตัว
- [FLT: 0]] — Unt: Unklies (inline perienter, no lection
]] ตัวเลือก:[FLT: 4] — สําเนาที่ส่วนใหญ่ตัวอักษร n; โปรดสังเกตว่ามันไม่ได้รับข้อมูลที่ ช่องว่างอีกต่อไป หากเป็นแหล่งกําเนิดที่ยาวกว่า n –0 เสมอ, ดังนั้น ช่องว่างของสมาชิก (FLT:3). - ยังดีกว่า: [FLT: 5] — ใช้งานบนระบบ BSD และระบบลินุกซ์จํานวนมาก; เสมอ un-terminates และผลตอบแทนความยาวของข้อความต้นฉบับสําหรับการตรวจสอบการแบ่งตัว (truncation)
- [FLT: 0][FLT: 6] — Unt: ceptembers โดยไม่จํากัด
] ทาง เลือก: [FLT:] — ผนวกตัวอักษร n ตัว และว่างตลอด.
ฟอร์แมตการแสดงผลและนําเข้าข้อมูลเข้า
- [FLT: 0]][FLT: 8]] — Unt: infaces (in อังกฤษ: Broad) เขียนผลลัพธ์ที่ออกมาอย่างเป็นระบบไม่มีขนาด
[FLT: 4] [FLTT: 4] — จํากัดการส่งออกไปถึง 1 ตัวอักษร รวมตัวพิมพ์ว่าง (FLT: 9). - [FLT: 0] — ความเสี่ยงที่คล้ายกัน ใช้ แทน.
- [FLT: 0] — อันตรายอย่างร้ายแรง; ถูกถอดออกจาก C11 มาตรฐาน ใช้ แทน.
- [FLT: 0] — Not sceck. ใช้ หรือ โดยมีความกว้างกว้าง.
คัดลอกหน่วยความจําและย้าย
- [FLT: 0]] — ปลอดภัยก็ต่อเมื่อ n ถูกตรวจสอบแล้วว่าไม่เกินขนาดของบัฟเฟอร์
]] ทางเลือก:[FLTT:1] [การทับซ้อนมือ] และมั่นใจเสมอว่า ⁇ ⁇ ⁇ – ⁇ . - เวที บาง แห่ง จัด จาก แอน เนส เค (Offial in C11) แต่ การ รับ มา เลี้ยง บุตร มี จํากัด.
การจัดการการตรวจสอบและขนาด
แม้ จะ มี การ ทํา งาน ที่ ปลอด ภัย คุณ ต้อง ตรวจ สอบ ความ ยาว ที่ คุณ เข้า ไป, ตรวจ ดู ขนาด ของ บัฟฟาโล, และ จัด การ กับ ความ สามารถ ที่ จะ รับ ความ เสีย หาย ได้ อย่าง ดี.
Check values
ก่อนที่จะคัดลอกหรือประมวลผลข้อมูลเข้าภายนอก (พิมพ์ข้อมูลเครือข่าย, เนื้อหาแฟ้ม) เป็นตัวกําหนดความยาวที่ยอมรับได้สูงสุด และปฏิเสธหรือทับค่าข้อมูลที่มากกว่าแฟ้มดังกล่าว ตัวอย่างเช่น:
#define MAX_INPUT 255
char buffer[MAX_INPUT + 1]; // +1 for null
if (strlen(user_input) > MAX_INPUT) {
// Handle error: reject or truncate
fputs("Input too long", stderr);
return -1;
}
strncpy(buffer, user_input, sizeof(buffer) - 1);
buffer[sizeof(buffer) - 1] = '\0';
ใช้บัฟเฟอร์ขนาดความกว้างคงที่กับข้อจํากัดที่รู้จัก
เมื่อเป็นไปได้ ให้กําหนดบัฟเฟอร์ที่มีขนาดคงที่ และบังคับมันตลอดรหัส หลีกเลี่ยงการใช้ลําดับตัวแปร (VLAS) ซึ่งจะทําให้การซ้อนทับได้หากมีขนาดขนาดใหญ่จัดจําหน่ายแทน แทน การปรับลดขนาดแบบไม่ตายตัวด้วยการตรวจให้ชัดเจน
การลดรอยหยักบนภาพ
ฟังก์ชันอย่างเช่น [FLT: 21] และ[FLT: 22] สามารถลดข้อมูลลงได้ โปรดระวังค่ากลับมาในการตรวจสอบการลดรอยหยัก และตัดสินใจว่าข้อมูลการตรึงจะเป็นที่ยอมรับหรือไม่ หรือหากผิดพลาดควรจะถูกยกขึ้นมา การไม่แยแสการลดรอยขีดเส้นตายสามารถปล่อยบัฟเฟอร์ไว้ในสถานะที่ไม่คาดฝันได้
แฟล็กรักษาความปลอดภัยและการป้องกันการทํางาน
ผู้รวบรวมสมัยใหม่เสนอธงที่เพิ่มการรับบัฟเฟอร์และลดความบิดเบือนโดยไม่มีรหัส เปิดการใช้งานในระบบการสร้างของคุณ
- [FLT: 0]] / [FLT: 24] — แทรก Canies (ค่าในรัฐบาล) ก่อนส่งที่อยู่กลับ หากตัฟเฟอร์เติม สารสนเทศเข้าไป ก่อนที่จะแก้ไขที่อยู่การกลับมา โปรแกรมยกเลิกก่อนการแสวงหาผลประโยชน์จะเสร็จ
- [FLT: 0]]] — แทนที่การทํางานที่ไม่ปลอดภัยอย่าง และ[FLT: 27] พร้อมการตรวจสอบรุ่นที่ยกเลิกเมื่อตัวบัฟเฟอร์ปลายทางมีขนาดเล็กเกินไป เรียก หรือค่าปรับแต่งสูงกว่า
- [FLT: 0] — เตือนเกี่ยวกับรูปแบบการพ้องความอ่อนแอที่นําไปสู่การแพร่เชื้อ หรือข้อมูลรั่วไหล
- [FLT: 0] — addressSanizer (ASan) การเข้ารหัสอุปกรณ์เพื่อตรวจจับการไหลของบัฟเฟอร์, การใช้ข้อมูลหลังจากไม่มีการใช้งาน และความทรงจําผิดพลาดอื่นๆ ในขณะรันทัศน การประมวลผลช้าแต่เป็นการทดสอบที่ประเมินค่าไม่ได้
- [FLT: 0] — หลีกเลี่ยงการเพิ่มจํานวนการไหลของเช็ค (ใช้ด้วยความระวัง).
การ ป้องกัน ระบบ การ ปฏิบัติ การ
ก้าน ไม้ ที่ เป็น ก้อน เป็น เพียง ชั้น เดียว.
- [FLT: 0] Data control (DPP) / NX บิต — Marks scap and cracking as uncutable, ป้องกันการประหารชีวิตแบบเชลล์โค้ด (FLT: 1).
- [FLT: 0] Adche Planguage Planguage (ASLR) [FLT: 1) — สุ่มจําที่อยู่หน่วยความจํา (tack, cape, load, ห้องสมุดร่วมกัน) เพื่อทํานายเป้าหมาย
- [FLT: 0] สํารองการอ่าน-เฉพาะ (RELRO) [FLT: 1] — ป้องกัน JE (ตารางการลงเสียงแบบเรียบเรียง) จากการเขียนเกินขนาด.
การเปิดใช้งานการป้องกันเหล่านี้ (ปกติจะเป็นค่าปริยาย) จะเป็นการยกแถบสําหรับการหาประโยชน์ แต่ไม่ได้ทําการแทนที่การเข้ารหัสที่แน่นหนา
รหัส Audits และการวิเคราะห์สแตรติก
การ ทบทวน ของ มนุษย์ รวม ทั้ง การ วิเคราะห์ แบบ อัตโนมัติ อาจ ทํา ให้ เกิด ปัญหา ที่ เกิด ขึ้น ใน ตอน เริ่ม ต้น.
- [FLT: 0]. ประมวลรหัสภาษา — หาการใช้ฟังก์ชันที่ไม่ปลอดภัย, การตรวจขนาดหายไป และวนที่เขียนเกินขอบเขตการบัฟเฟอร์.
- [FLT: 0] เครื่องวิเคราะห์เชิงเทคนิค — เครื่องมืออย่าง ] ] และ ตรวจจับศักยภาพ ครอบคลุม ใช้งานอันตราย และปิดกิจการโดย 1 คน ] สามารถทํางานใน CIPTS ได้
- [FLT: 0] การจับต้อง — ใช้ libfzer, AFL หรือ fazers อื่น ๆ เพื่อทดสอบการป้อนข้อมูลอัตโนมัติกับข้อมูลที่ไม่คาดฝัน ที่อาจเกิดขึ้นมา
ตัว อย่าง ที่ ใช้ ได้ จริง ของ รหัส ที่ ปลอด ภัย
สําเนาข้อความปลอดภัย พร้อมการตรวจสอบขอบเขต
#include <stdio.h>
#include <string.h>
int safe_string_copy(char *dest, size_t dest_size, const char *src) {
if (!dest || !src || dest_size == 0) {
return -1; // Invalid parameters
}
size_t src_len = strlen(src);
if (src_len >= dest_size) {
// Source too large; truncation or error
// Option: copy what fits and null-terminate
strncpy(dest, src, dest_size - 1);
dest[dest_size - 1] = '\0';
return 1; // Truncation occurred
}
strncpy(dest, src, dest_size);
// strncpy fills remaining with null, so dest_size fits; no need to null-terminate if src shorter
return 0; // Success, no truncation
}
การ จัด การ กับ ตัว เลข ที่ ปลอด ภัย สําหรับ ขนาด ของ บัฟเฟอร์
การไหลของกระเพื่อม อาจเป็นผลมาจากจํานวนเต็มที่เพิ่มขึ้นเมื่อคํานวณขนาด. ตรวจดูเลขคณิตก่อนการวาง
#include <stdlib.h>
#include <limits.h>
#include <errno.h>
void *safe_malloc_array(size_t nmemb, size_t size) {
if (nmemb == 0 || size == 0) {
return NULL; // Or handle zero-size allocation
}
if (nmemb > SIZE_MAX / size) {
// Integer overflow would occur
errno = ENOMEM;
return NULL;
}
return malloc(nmemb * size);
}
ใช้ snprintf สําหรับรูปแบบสตริง
char log_message[256];
int ret = snprintf(log_message, sizeof(log_message),
"User %s logged in from %s", username, ip_address);
if (ret < 0) {
// Output error
} else if ((size_t)ret >= sizeof(log_message)) {
// Truncation occurred; handle if needed
}
การใช้งานที่ดีที่สุด
- [FLT: 0] เปิดใช้งานบัฟเฟอร์ — เสมอเป็นศูนย์-intition bruffs เพื่อหลีกเลี่ยงการรั่วไหลของหน่วยความจําที่ไม่สามารถรับรู้ได้
- [FLT: 0] การกลับมาอย่างไร้ขีดจํากัด โดยไม่มีขอบเขตความลึก — การไหลของสแต็กสามารถเกิดขึ้นได้จากการเกิดการเกิดอีกครั้งที่ลึก; ใช้การตีตราหรือความลึกจํากัด
- [FLT: 0] ใช้ Qualifier — ช่วยผู้รวบรวมระบบเสียงที่เชี่ยวชาญและอาจจับปัญหาการเปลี่ยนชื่อได้ แต่ไม่ได้ป้องกันการไหลเข้ามาโดยตรง
- [FLT: 0]. preffer ไม่ถูกต้อง — ป้องกันการดัดแปลงสายข้อมูลเข้าโดยไม่ได้ตั้งใจ และบังคับความประสงค์
- [FLT: 0] การแก้ข้อผิดพลาด — อย่าละเลยค่ากลับจากฟังก์ชันเช่น ] ] ] [FLTT:43] เป็นต้น (พ.ศ.
แหล่ง ข้อมูล สําหรับ การ เรียน รู้ เพิ่ม เติม
- [FLT: 0] ESATE CATE C Ccing Stander [[FLT: 1) — กฎที่เข้าใจง่ายสําหรับรหัส C.
- [FLT: 0] CWE-201: Bruff Secord of Checked [FLT: 1) — ประเภทของสารบัฟเฟอร์ที่เพิ่มขึ้นมา
- [FLT: 0] WOWAS Brov Overfive — แนะนําการใช้งานจากโครงการรักษาความปลอดภัยเว็บโอเพนท์
- [FLT: 0]. GNU C Bookary C. คู่มือ: สตริงและอาร์เรย์ Usitality [[FLT: 1) — เอกสารสําหรับฟังก์ชันสตริงความปลอดภัย (FLT: 1).
- [FLT: 0] Adches Sanniverser[FLT: 1) — เครื่องตรวจจับความผิดพลาดของหน่วยความจําอย่างรวดเร็ว (FLT: 1).
รูปแบบการวน
การป้องกันการแพร่เชื้อที่ไหลล้นในซีนั้น ไม่ใช่ทางเลือกอื่น มันเป็นความรับผิดชอบพื้นฐานของนักพัฒนาที่ทํางานกับภาษา โดยความเข้าใจในกลไกของการใช้ที่ไหลเข้ามา