Ada banyak risiko keamanan yang berasal dari kontak dekat dengan perangkat keras yang bertentangan dengan penggunaan API yang teruji dan terbukti dari bahasa pemrograman tingkat tinggi. Jauh lebih mudah untuk menyebabkan buffer overflow dalam C daripada dalam bahasa seperti Java.
Apa risiko atau kerentanan (misalnya buffer overflows) yang harus diperhatikan oleh setiap programmer C (kerentanan IE yang relevan dengan programmer C)? Masalah apa yang bisa menyebabkan ini? Bagaimana menghindarinya, dan kesalahan umum apa yang menyebabkan ini terjadi dalam program?
Jawaban:
Buffer overflow adalah hal yang besar. Tidak ada dalam C yang dicentang kisaran secara default, jadi sangat mudah untuk menimpa buffer. Ada fungsi pustaka standar
gets()
,, yang tidak dapat berhenti meluap dari buffer, dan hampir tidak boleh digunakan.Ada beberapa teknik tingkat implementasi untuk menghambat eksploitasi, seperti pengacakan tumpukan blok, tetapi itu tidak akan menghentikan buffer overflows di buffer lokal, yang sering dapat melakukan hal-hal menarik seperti mengubah alamat tempat fungsi akan kembali.
Tidak ada solusi umum yang baik dalam C. Banyak fungsi perpustakaan memiliki versi yang akan membatasi jumlah yang akan mereka tulis. meski menghitung itu bisa canggung. Ada perangkat lunak yang dapat mendeteksi tumpukan buffer berlebih dalam pengujian, selama pengujian yang sesuai dijalankan, dan stack overflow sering muncul sebagai crash dalam pengujian. Selain itu, ini adalah masalah pengkodean dan tinjauan kode yang cermat.
Masalah terkait adalah masalah penulisan ke buffer terlalu kecil oleh satu karakter, lupa bahwa string C yang panjang n karakter memerlukan n +1 karakter dalam memori, karena
'\0'
terminator. Jika penyerang dapat mengelola untuk menyimpan string tanpa terminator, fungsi C apa pun yang mengharapkan string akan terus memproses hingga mencapai nol byte, yang dapat mengakibatkan menyalin atau mengeluarkan informasi lebih banyak dari yang diinginkan (atau memukul memori yang dilindungi untuk serangan DOS) ). Solusinya, sekali lagi, adalah kesadaran, kepedulian, dan ulasan kode.Ada risiko lain dengan
printf()
keluarga. Jika Anda pernah menulischar * str; ... printf(str);
, Anda sedang mengatur diri sendiri untuk masalah jikastr
berisi '%' saat dicetak. The%n
Format direktif memungkinkanprintf()
untuk menulis ke memori. Solusinya adalahprintf("%s", str);
atauputs(str);
. (Juga, gunakan C99snprintf()
sebagai gantisprintf()
.)Menggunakan bilangan bulat yang tidak ditandatangani, terutama sebagai indeks loop, dapat menyebabkan masalah. Jika Anda menetapkan nilai negatif kecil untuk yang tidak ditandatangani, Anda mendapatkan nilai positif yang besar. Itu dapat merusak hal-hal seperti hanya memproses N contoh sesuatu, atau dalam fungsi terbatas seperti
strncpy()
. Periksa semua bilangan bulat yang tidak ditandatangani. Anda mungkin ingin menghindariunsigned short
, karena nilai besar di salah satu dari mereka akan dikonversi ke nilai positif besar dalamint
.Jangan lupa bahwa konstanta karakter, dalam C, sebenarnya adalah
int
. Menulis sesuatu sepertichar c; while((c = getchar()) != EOF) ...
dapat dengan mudah gagal, karenaEOF
tidak dapat diwakili dalamchar
.Ada banyak kesalahan karakteristik C yang bisa saya pikirkan, tetapi ini bisa menyebabkan masalah keamanan.
sumber
printf("%s", str)
string telanjang saatputs(str)
akan melakukan pekerjaan yang sama.puts
menambahkan karakter baris baru sementaraprintf
tidak.fputs(str, stdout)
, yang tidak.Beberapa risiko spesifik-C meliputi: buffer overflows , pemformatan serangan string, dan integer overflows .
sumber
Berikut ini adalah risiko yang mudah terlewatkan yang dapat menyebabkan masalah yang membutuhkan waktu berjam-jam untuk diperbaiki.
Pertimbangkan kode berikut, yang akan dikompilasi tanpa masalah.
Ketika Anda memeriksa untuk melihat apakah
lpstr_current_state
ada di dalamCONST_EMERGENCY_STATE_HOLY_CRAP
Anda sebenarnya menugaskan. Lebih baik untuk selalu meletakkan variabel konstan di sebelah kiri. Ketika Anda meletakkan konstanta di sebelah kiri, maka kompiler akan gagal karena Anda tidak dapat menetapkan nilai ke variabel.Maka Anda dapat dengan mudah berkata pada diri sendiri, "Aduh, itu bisa saja buruk", sambil memperbaiki kode untuk membaca ...
sumber
=
dan==
.Hanya ada satu risiko keamanan: Fakta bahwa ada orang di luar yang akan melakukan yang terbaik untuk menangkap kerentanan apa pun dalam perangkat lunak Anda dan memanfaatkannya untuk keuntungan mereka sendiri. Segala sesuatu yang lain mengikuti dari sana.
Jadi, ketika Anda berpikir "tidak ada orang waras yang akan ...", maka Anda harus segera berpikir "kecuali seseorang yang ingin meretas komputer orang lain akan melakukan hal itu".
Konsekuensi terbesar adalah bahwa setiap kali Anda bereaksi terhadap peristiwa di luar (misalnya, dengan memproses data yang dikirim dari luar), Anda harus menganggap bahwa data ini berada di bawah kendali musuh terburuk Anda.
sumber