Share via


Membangun program C++ yang andal dan aman

Publikasi pemerintah Amerika Serikat NISTIR 8397: Pedoman tentang Standar Minimum untuk Verifikasi Pengembang Perangkat Lunak berisi panduan yang sangat baik tentang cara membangun perangkat lunak yang andal dan aman dalam bahasa pemrograman apa pun.

Dokumen ini mengikuti struktur yang sama dengan NISTIR 8397. Setiap bagian:

  • meringkas cara menggunakan produk pengembang Microsoft untuk C++ dan bahasa lain untuk memenuhi kebutuhan keamanan bagian tersebut, dan
  • memberikan panduan untuk mendapatkan nilai terbanyak di setiap area.

2.1 Pemodelan ancaman

Ringkasan

Pemodelan ancaman adalah proses yang berharga, terutama ketika diterapkan dengan cara yang menskalakan untuk memenuhi kebutuhan pengembangan Anda dan yang mengurangi kebisingan.

Rekomendasi

Pemodelan ancaman harus menjadi salah satu bagian dari Siklus Hidup Pengembangan Keamanan (SDL) dinamis Anda. Kami menyarankan bahwa untuk produk Anda secara keseluruhan, untuk fitur tertentu, atau untuk perubahan desain atau implementasi utama:

  • Memiliki SDL yang solid dan dinamis yang memungkinkan keterlibatan awal dengan tim pengembang dan hak pendekatan.
  • Terapkan pemodelan ancaman dengan cara yang ditargetkan. Terapkan pemodelan ancaman ke semua fitur, tetapi mulai secara taktis dengan fitur yang terekspos, kompleks, atau penting. Terapkan secara teratur sebagai bagian dari tinjauan produk top-down.
  • Terapkan pemodelan ancaman lebih awal (seperti semua persyaratan keamanan), ketika masih ada kesempatan untuk mengubah desain. Selain itu, model ancaman berfungsi sebagai input ke proses lain, seperti pengurangan permukaan serangan atau merancang untuk keamanan. Model ancaman yang dibuat nanti adalah "survei" terbaik untuk pengujian pena (pengujian penetrasi) atau area yang membutuhkan pengujian keamanan seperti fuzzing. Setelah Anda membuat model ancaman dasar, rencanakan untuk terus melakukan iterasi saat permukaan serangan berubah.
  • Gunakan inventaris aset dan kepatuhan untuk melacak dengan tepat apa yang membentuk produk, dan melacak artefak keamanan (termasuk model ancaman) bersama dengan aset yang diterapkan. Pendekatan ini memungkinkan penilaian risiko otomatis yang lebih baik dan memfokuskan upaya keamanan pada komponen atau fitur tertentu yang berubah.
  • Di Azure, Alat Pemodelan Ancaman Microsoft diperbarui pada tahun 2022 untuk pengembangan Azure. Untuk informasi selengkapnya, lihat Gambaran umum Alat Pemodelan Ancaman Microsoft - Azure

Faktor dan praktik pendukung

Untuk menerapkan pemodelan ancaman dengan benar dan menghindari penggunaan yang kurang/berlebihan, kami telah menemukan bahwa konsep inti berikut perlu ditangani terlebih dahulu.

Pendekatan pengembangan

Pertama, pahami pendekatan pengembangan tim. Untuk tim dengan alur kerja pengembangan tangkas yang mendorong puluhan perubahan ke produksi setiap hari, tidak praktis atau masuk akal untuk memerlukan pembaruan model ancaman untuk setiap perubahan fungsional. Sebagai gantinya, sejak awal saat menulis persyaratan fungsional fitur, pertimbangkan untuk menyertakan kuesioner persyaratan keamanan. Kuesioner harus berfokus pada pertanyaan spesifik tentang fitur untuk menentukan aspek masa depan SDL Anda. Misalnya:

  • Apakah fitur ini membuat perubahan besar dalam desain bagaimana kami menyediakan isolasi pelanggan di lingkungan multipenyewa? Jika demikian, pertimbangkan untuk melakukan model ancaman penuh.
  • Apakah fitur baru mengizinkan unggahan file? Jika demikian, mungkin yang lebih tepat adalah penilaian keamanan aplikasi web.
  • Apakah perubahan ini terutama hanya perubahan UI fungsi? Jika demikian, mungkin tidak ada yang diperlukan di luar peralatan otomatis tradisional Anda.

Hasil kuesioner keamanan menginformasikan teknik SDL mana yang akan diikat ke unit pengembangan mana. Ini juga menginformasikan mitra pengembangan garis waktu SDL fitur, sehingga mereka dapat berkolaborasi pada waktu yang tepat.

Inventaris produk

Kedua, pertahankan inventaris aset yang kuat dari produk yang anda tugaskan untuk menilai. Produk tumbuh dalam kompleksitas. Adalah umum untuk menulis perangkat lunak untuk perangkat yang terhubung yang memiliki:

  • sensor (seperti rel penumpang dan kendaraan),
  • jaringan berbasis bus yang berbicara dengan komponen lain dalam kendaraan (seperti CANBUS atau PROFIBUS),
  • nirkabel/seluler/Bluetooth untuk komunikasi dengan perangkat pelanggan dan ujung belakang cloud,
  • pembelajaran mesin di cloud yang mengumpan kembali ke perangkat atau aplikasi manajemen armada,
  • dan banyak lagi.

Dalam produk yang kompleks seperti itu, pemodelan ancaman sangat penting. Memiliki inventori aset yang kuat memungkinkan Anda melihat seluruh tumpukan produk untuk melihat gambar lengkap, dan untuk melihat tempat-tempat utama yang perlu dievaluasi tentang bagaimana fitur baru atau yang diubah memengaruhi keamanan produk.

Granularitas dan integrasi

Buat sistem untuk mengukur kepatuhan menggunakan metrik yang jelas.

  • Mengukur kepatuhan secara teratur untuk pengembangan tingkat fitur. Kepatuhan fitur umumnya harus diukur dengan frekuensi yang lebih tinggi dan granularitas yang lebih kecil, terkadang bahkan pada sistem pengembang atau pada waktu penerapan/penggabungan kode.
  • Evaluasi keamanan secara berkala untuk produk yang lebih luas di mana fitur atau komponen sedang digunakan. Evaluasi yang lebih luas biasanya dilakukan dengan frekuensi yang lebih rendah dan granularitas yang lebih luas, seperti pada modul atau waktu pengujian sistem.

Sisik

Pertahankan sistem inventaris aset yang tepat yang menangkap dan mempertahankan artefak keamanan dan output tinjauan model ancaman. Memiliki inventori yang jelas memungkinkan Anda mengevaluasi output ulasan untuk pola, dan membuat keputusan cerdas tentang cara menyempurnakan program keamanan produk secara teratur.

Cobalah untuk menggabungkan kuesioner keamanan fase persyaratan, hasil pemodelan ancaman, hasil penilaian keamanan, dan hasil dari alat otomatis. Menggabungkannya memungkinkan Anda mengotomatiskan sudut pandang risiko relatif dari produk tertentu, idealnya sebagai "dasbor," untuk memberi tahu tim keamanan Anda apa yang harus difokuskan untuk mendapatkan nilai terbaik dari pemodelan ancaman.

2.2 Pengujian otomatis

Ringkasan

Pengujian otomatis adalah cara penting untuk memastikan kualitas dan keamanan kode Anda. Ini adalah bagian integral dalam mendukung area lain yang disebutkan dalam dokumen ini, seperti Pemodelan Ancaman. Ketika dipasangkan dengan praktik pengodean aman lainnya, mereka membantu melindungi dari bug dan kerentanan yang dimasukkan ke dalam basis kode.

Atribut kunci

Pengujian harus dapat diandalkan, konsisten, dan terisolasi. Pengujian ini harus mencakup sebanyak mungkin kode. Semua fitur baru dan perbaikan bug harus memiliki pengujian yang sesuai untuk memastikan keamanan jangka panjang dan keandalan kode jika memungkinkan. Jalankan pengujian otomatis secara teratur dan di lingkungan sebanyak mungkin, untuk memastikan pengujian dijalankan dan mencakup semua area:

  • Tempat pertama yang harus mereka jalankan adalah pada mesin yang membuat perubahan. Menjalankan pengujian paling mudah dilakukan dalam IDE yang digunakan untuk pengeditan, atau sebagai skrip pada baris perintah saat pengembang membuat perubahan.
  • Tempat berikutnya yang harus mereka jalankan adalah sebagai bagian dari proses penerapan/penggabungan permintaan pull.
  • Tempat terakhir untuk menjalankan pengujian adalah sebagai bagian dari alur Integrasi Berkelanjutan dan Penyebaran Berkelanjutan (CI/CD), atau pada build kandidat rilis Anda.

Cakupan pengujian harus meningkat di setiap langkah, dengan langkah terakhir memberikan cakupan penuh untuk apa pun yang mungkin terlewatkan oleh langkah-langkah lain.

Penggunaan dan pemeliharaan berkelanjutan

Keandalan pengujian adalah bagian penting untuk menjaga efektivitas rangkaian pengujian. Kegagalan pengujian harus ditetapkan dan diselidiki, dengan potensi masalah keamanan mendapatkan prioritas tinggi dan diperbarui dalam jangka waktu yang diminta dan ditentukan sebelumnya. Mengabaikan kegagalan pengujian seharusnya bukan praktik umum, tetapi harus memerlukan pembenaran dan persetujuan yang kuat. Kegagalan pengujian karena masalah dalam rangkaian pengujian itu sendiri harus diperlakukan sama dengan kegagalan lain, untuk mencegah selang dalam cakupan di mana masalah produk dapat terlewatkan.

Jenis tes, terutama pengujian unit

Ada beberapa jenis pengujian otomatis, dan meskipun tidak semua berlaku untuk semua aplikasi, rangkaian pengujian yang baik berisi pilihan beberapa jenis yang berbeda. Kasus Pengujian Berbasis Kode seperti pengujian unit adalah yang paling umum dan paling integral, berlaku untuk semua aplikasi dan sengaja mencakup jalur kode sebanyak mungkin untuk kebenaran. Pengujian ini harus kecil, cepat, dan tidak memengaruhi status mesin, sehingga rangkaian lengkap pengujian dapat dijalankan dengan cepat dan sering. Jika memungkinkan, jalankan pengujian pada banyak komputer yang memiliki pengaturan perangkat keras yang berbeda untuk menangkap masalah yang tidak dapat direproduksi pada satu jenis komputer.

Visual Studio

Visual Studio Test Explorer secara asli mendukung banyak kerangka kerja pengujian C++ paling populer, dan memiliki opsi untuk menginstal ekstensi untuk kerangka kerja lainnya. Fleksibilitas ini berguna untuk menjalankan subset pengujian yang mencakup kode yang sedang Anda kerjakan, dan memudahkan untuk men-debug kegagalan pengujian saat muncul. Visual Studio juga memudahkan untuk menyiapkan rangkaian pengujian baru untuk proyek yang ada, dan menyediakan alat bermanfaat seperti CodeLens untuk mempermudah pengelolaan pengujian ini. Untuk informasi selengkapnya tentang menulis, menjalankan, dan mengelola pengujian C/C++ dengan Visual Studio, lihat Menulis pengujian unit untuk C/C++ - Visual Studio (Windows).

Di Azure dan GitHub CI/CD

Pengujian yang melakukan verifikasi lebih dalam dan membutuhkan waktu lebih lama untuk dijalankan, seperti analisis statis, deteksi komponen, dan sebagainya, adalah kandidat yang baik untuk pengujian permintaan pull atau pengujian integrasi berkelanjutan. Azure DevOps dan GitHub Actions memudahkan untuk menjalankan validasi secara otomatis dan memblokir pemeriksaan kode jika validasi gagal. Penegakan otomatis membantu memastikan bahwa semua kode yang dicek masuk aman berdasarkan pemeriksaan yang lebih ketat ini yang dijalankan. Azure Pipelines dan Validasi Build Azure DevOps dijelaskan di sini:

2.3 Berbasis kode, atau statis, analisis

Ringkasan Analisis kode statis/biner harus diaktifkan secara default, agar aman secara default. Analisis statis menganalisis program untuk kebijakan keselamatan dan keamanan yang diperlukan pada saat sedang dibangun, bukan pada waktu eksekusi ketika eksploitasi dapat terjadi pada komputer pelanggan. Analisis statis dapat menganalisis program dalam bentuk kode sumber atau dalam bentuk yang dapat dieksekusi yang dikompilasi.

Rekomendasi Microsoft merekomendasikan agar Anda:

  • Aktifkan analisis statis untuk semua program C++, untuk kode sumber input (sebelum kompilasi) dan biner yang dapat dieksekusi (setelah kompilasi). "Aktifkan" mungkin berarti menjalankan analisis selama setiap build pada komputer pengembang, atau sebagai build terpisah untuk memeriksa kode nanti atau sebagai persyaratan pemeriksaan.
  • Masukkan analisis statis ke dalam alur CI sebagai bentuk pengujian.
  • Analisis statis menurut definisi dilengkapi dengan positif palsu, dan bersiaplah untuk memasukkan fakta itu ke dalam perulangan umpan balik kualitas Anda. Jadilah cepat untuk mengaktifkan semua peringatan positif palsu rendah di depan. Kemudian proaktif untuk secara bertahap meningkatkan jumlah aturan yang basis kode Anda mengompilasi peringatan-bersih karena Anda secara teratur menambahkan lebih banyak aturan yang menandai bug penting dengan mengorbankan positif palsu yang secara bertahap lebih tinggi (awalnya, sebelum basis kode telah dibersihkan untuk aturan tersebut juga).
  • Selalu gunakan versi Visual Studio terbaru yang didukung, dan siapkan lingkungan teknik Anda untuk dengan cepat menggunakan rilis patch terbaru segera setelah tersedia, tanpa menunda ke tahap/siklus pengembangan berikutnya.

Alat utama Waspadai dan gunakan hal berikut:

Catatan:

  • /analyze memungkinkan analisis statis kode C++ pada waktu kompilasi untuk mengidentifikasi kerentanan keamanan dan kode keandalan penting. Ini harus diaktifkan di seluruh garis waktu pengembangan program C++. Mulailah dengan mengaktifkan setidaknya "Microsoft Native Recommended" secara default sebagai garis besar minimum. Kemudian lihat dokumentasi tentang cara menentukan lebih banyak aturan, terutama aturan Pedoman Inti C++, sebagaimana diperlukan oleh kebijakan rekayasa Anda. Kemampuan Analisis Statis kode sumber tersedia di Visual C++ IDE dan di Alat Build baris perintah.
  • /W4 dan /WX harus diaktifkan sedapat mungkin, untuk memastikan Anda mengkompilasi kode Anda dengan bersih pada tingkat peringatan tinggi (W4) dan memperlakukan peringatan sebagai kesalahan yang harus diperbaiki (WX). Opsi ini memungkinkan menemukan kesalahan data yang tidak diinisialisasi yang tidak dapat diperiksa oleh alat analisis statis lainnya, karena kesalahan hanya terlihat setelah back-end kompilator melakukan analisis interprosedural dan inlining.
  • Analisis biner BinSkim memastikan bahwa proyek memungkinkan berbagai fitur keamanan. BinSkim menghasilkan PDB dan output lain yang memudahkan verifikasi chain-of-custody dan merespons masalah keamanan secara efisien. Microsoft merekomendasikan untuk menjalankan alat BinSkim untuk menganalisis semua biner yang dapat dieksekusi (.sys, .dll atau .exe) yang diproduksi untuk atau dikonsumsi oleh program Anda. Panduan Pengguna BinSkim menyertakan daftar standar keamanan yang didukung. Microsoft menyarankan agar Anda memperbaiki semua masalah yang dilaporkan sebagai "kesalahan" oleh alat BinSkim. Masalah yang dilaporkan sebagai "peringatan" harus dievaluasi secara selektif, karena menyelesaikannya dapat memiliki implikasi performa atau mungkin tidak diperlukan.

Di Azure dan GitHub CI/CD Microsoft merekomendasikan untuk selalu mengaktifkan kode sumber dan analisis statis biner dalam skenario CI/CD rilis. Jalankan analisis sumber segera pada komputer pengembang lokal, atau setidaknya untuk setiap permintaan penerapan atau penarikan, untuk menangkap bug sumber sedini mungkin dan meminimalkan biaya keseluruhan. Bug tingkat biner cenderung diperkenalkan lebih lambat, sehingga mungkin cukup untuk menjalankan analisis biner dalam skenario CI/CD prarilis yang lebih jarang (seperti build malam atau mingguan).

2.4 Ulasan untuk rahasia hardcoded

Ringkasan

Jangan hardcode rahasia dalam perangkat lunak. Anda dapat menemukan dan menghapus rahasia dari kode sumber secara efisien dengan menggunakan alat andal yang dapat memindai seluruh basis kode sumber Anda. Setelah Anda menemukan rahasia, pindahkan ke tempat yang aman mengikuti pedoman untuk penyimpanan yang aman dan penggunaan rahasia.

Masalah

"Rahasia" berarti entitas yang menetapkan identitas dan menyediakan akses ke sumber daya, atau yang digunakan untuk menandatangani atau mengenkripsi data sensitif. Contohnya termasuk kata sandi, kunci penyimpanan, string koneksi, dan kunci privat. Sangat menggoda untuk menyimpan rahasia dalam produk perangkat lunak sehingga mereka dapat dengan mudah diperoleh ketika diperlukan oleh perangkat lunak. Namun, rahasia hardcoded ini dapat menyebabkan insiden keamanan yang parah atau bencana karena mudah ditemukan dan dapat digunakan untuk membahayakan layanan dan data Anda.

Pencegahan

Rahasia yang dikodekan secara permanen dalam kode sumber (sebagai teks biasa atau blob terenkripsi) adalah kerentanan keamanan. Berikut adalah panduan umum tentang cara menghindari rahasia dalam kode sumber:

  • Gunakan alat pra-pemeriksaan untuk memindai dan menangkap potensi rahasia yang dikodekan secara permanen dalam kode sebelum mengirimkan ke kontrol sumber.
  • Jangan letakkan kredensial teks yang jelas dalam kode sumber atau file konfigurasi.
  • Jangan simpan kredensial teks yang jelas di SharePoint, OneNote, berbagi file, dan sebagainya. Atau bagikan melalui email, IM, dan sebagainya.
  • Jangan mengenkripsi rahasia dengan kunci dekripsi yang mudah ditemukan. Misalnya, jangan menyimpan file PFX bersama dengan file yang berisi kata sandinya.
  • Jangan mengenkripsi rahasia dengan dekripsi yang lemah. Misalnya, jangan mengenkripsi file PFX dengan kata sandi yang lemah atau umum.
  • Hindari menempatkan kredensial terenkripsi dalam kode sumber. Sebagai gantinya, gunakan tempat penampung di sumber Anda, dan biarkan sistem penyebaran Anda menggantinya dengan rahasia dari penyimpanan yang disetujui.
  • Terapkan prinsip yang sama ke rahasia di lingkungan seperti pengujian, penahapan, dan sebagainya, seperti yang Anda lakukan dalam penyebaran produksi. Adversaries sering menargetkan sistem nonproduksi karena dikelola dengan kurang baik, lalu menggunakannya untuk mempivot ke dalam produksi.
  • Jangan berbagi rahasia antara penyebaran (misalnya, pengujian, penahapan, produksi).

Meskipun tidak terkait langsung dengan rahasia hardcoded, ingat juga mengamankan rahasia untuk pengujian, pengembangan, dan produksi Anda:

  • Putar rahasia Anda secara berkala dan kapan pun mereka mungkin telah terekspos. Memiliki kemampuan yang ditunjukkan untuk memutar/menyebarkan ulang rahasia adalah bukti sistem yang aman. Lebih penting lagi, tidak adanya kemampuan ini bahkan merupakan bukti yang lebih kuat dari kerentanan yang tidak dapat dihindari.
  • Jangan menyerah pada alasan pengembang umum bahwa "kredensial pengujian saya tidak menciptakan risiko." Dalam praktiknya, mereka hampir selalu melakukannya.
  • Pertimbangkan untuk menjauh dari rahasia (misalnya, kata sandi, kunci pembawa) sepenuhnya dalam preferensi solusi RBAC/berbasis identitas sebagai solusi rekayasa yang baik yang dapat menghalangi kesalahan pengelolaan rahasia sepenuhnya.

Deteksi

Komponen warisan produk Anda mungkin berisi rahasia hardcoded tersembunyi dalam kode sumbernya. Terkadang rahasia dari komputer desktop pengembang dapat merayap ke cabang jarak jauh dan bergabung ke cabang rilis, membocorkan rahasia secara tidak sengaja. Untuk menemukan rahasia yang mungkin bersembunyi di kode sumber, Anda dapat menggunakan alat yang dapat memindai kode Anda untuk rahasia yang dikodekan secara permanen:

Perbaikan

Ketika kredensial ditemukan dalam kode sumber Anda, kebutuhan mendesak segera adalah untuk membatalkan kunci yang terekspos dan melakukan analisis risiko berdasarkan paparan. Bahkan jika sistem Anda perlu tetap berjalan, Anda dapat mengaktifkan manajer rahasia untuk remediasi menggunakan langkah-langkah berikut:

  1. Jika remediasi memungkinkan pengalihan ke identitas terkelola, atau memerlukan penurunan di manajer rahasia seperti Azure Key Vault (AKV), lakukan terlebih dahulu. Kemudian sebarkan ulang dengan identitas atau kunci yang diperbarui.
  2. Batalkan validasi rahasia yang diekspos.
  3. Lakukan audit/penilaian risiko terhadap potensi kerusakan akibat penyusupan.

Untuk melindungi kunci kriptografi dan rahasia lain yang digunakan oleh aplikasi dan layanan cloud, gunakan Azure Key Vault dengan kebijakan akses yang sesuai.

Jika paparan mengorbankan data/PII pelanggan tertentu, mungkin memerlukan persyaratan kepatuhan/pelaporan lainnya.

Hapus rahasia yang sekarang tidak valid dari kode sumber Anda, dan ganti dengan metode alternatif yang tidak mengekspos rahasia langsung dalam kode sumber Anda. Cari peluang untuk menghilangkan rahasia jika memungkinkan dengan menggunakan alat seperti Microsoft Azure ACTIVE Directory. Anda dapat memperbarui metode autentikasi untuk memanfaatkan identitas terkelola melalui Azure Active Directory). Hanya gunakan penyimpanan yang disetujui untuk menyimpan dan mengelola rahasia seperti Azure Key Vault (AKV). Untuk informasi selengkapnya, lihat:

Azure DevOps (AzDO)

Pengguna AzDO dapat memindai kode mereka melalui GitHub Advanced Security untuk Azure DevOps (GHAzDO). GHAzDO juga memungkinkan pengguna untuk mencegah paparan rahasia dengan mengaktifkan Perlindungan Push pada repositori mereka, menangkap potensi paparan sebelum mereka pernah bocor. Untuk informasi selengkapnya tentang cara mendeteksi rahasia yang dikodekan secara permanen dalam kode di Azure DevOps, lihat Pemindaian Rahasia untuk Github Advanced Security untuk Azure DevOps di setiap tautan berikut:

Di GitHub

Pemindaian rahasia tersedia di GitHub.com dalam dua bentuk:

  • Pemberitahuan pemindaian rahasia untuk mitra. Berjalan secara otomatis di semua repositori publik. Setiap string yang cocok dengan pola yang disediakan oleh mitra pemindaian rahasia dilaporkan langsung ke mitra yang relevan.
  • Pemberitahuan pemindaian rahasia untuk pengguna. Anda dapat mengaktifkan dan mengonfigurasi pemindaian tambahan untuk repositori yang dimiliki oleh organisasi yang menggunakan GitHub Enterprise Cloud dan memiliki lisensi untuk GitHub Advanced Security. Alat-alat ini juga mendukung repositori privat dan internal.

GitHub menyediakan pola rahasia yang diketahui untuk mitra dan pengguna yang dapat dikonfigurasi untuk memenuhi kebutuhan Anda. Untuk informasi selengkapnya, silakan lihat:

Catatan

GitHub Advanced Security untuk Azure DevOps membawa solusi pemindaian rahasia, pemindaian dependensi, dan pemindaian kode CodeQL yang sama yang sudah tersedia untuk pengguna GitHub dan secara asli mengintegrasikannya ke Azure DevOps untuk melindungi Azure Repos and Pipelines Anda.

Sumber Daya Tambahan:

2.5 Jalankan dengan pemeriksaan dan perlindungan yang disediakan bahasa dan OS

Ringkasan

Pengerasan biner dilakukan dengan menerapkan kontrol keamanan waktu kompilasi. Ini termasuk mitigasi yang:

  • mencegah kerentanan yang dapat dieksploitasi dalam kode,
  • mengaktifkan deteksi runtime yang memicu pertahanan keamanan pada eksploitasi, dan
  • aktifkan produksi dan pengarsipan data untuk membantu membatasi kerusakan yang disebabkan oleh insiden keamanan.

Konsumen biner harus memilih fitur keamanan Windows untuk mendapatkan manfaat penuh dari pengerasan.

Microsoft menyediakan serangkaian fasilitas khusus untuk proyek C++ untuk membantu pengembang menulis dan mengirim kode yang lebih aman dan lebih aman. Pengembang C++ juga harus mematuhi standar keamanan yang umum untuk bahasa yang menghasilkan kode yang dapat dieksekusi. Microsoft mempertahankan BinSkim, pemeriksa biner OSS publik yang membantu memberlakukan penggunaan banyak perlindungan yang dijelaskan di bagian ini. Untuk informasi selengkapnya tentang BinSkim, lihat Panduan pengguna Binskim | Github

Kontrol tingkat biner berbeda sesuai dengan tempat kontrol diterapkan dalam proses rekayasa. Anda harus membedakan antara opsi kompilator dan linker yang: adalah waktu kompilasi yang ketat, mengubah pembuatan kode dengan overhead run-time, dan mengubah pembuatan kode untuk mencapai kompatibilitas dengan perlindungan OS.

Pengaturan pengembang harus lebih memilih untuk mengaktifkan analisis statis sebanyak mungkin, memungkinkan produksi data privat untuk mempercepat penelusuran kesalahan, dan sebagainya. Build rilis harus disetel ke kombinasi keamanan, performa, dan masalah pembuatan kode lainnya yang sesuai. Proses rilis harus dikonfigurasi untuk menghasilkan dan mengelola data build publik vs. yang digunakan secara privat dengan benar (misalnya, simbol publik vs. privat).

Tetap terkini: Selalu gunakan pengkompilasi dan alat terbaru

Kompilasi semua kode dengan toolset saat ini untuk mendapatkan manfaat dari dukungan bahasa terbaru, analisis statis, pembuatan kode, dan kontrol keamanan. Karena kompilator berdampak pada setiap komponen yang dihasilkan, potensi regresi pada pembaruan alat relatif tinggi. Menggunakan kompilator yang sudah kedaluwarsa menciptakan risiko tertentu untuk tindakan korektif saat menanggapi insiden keamanan, karena tim mungkin tidak memiliki cukup waktu untuk meningkatkan kompilator. Microsoft merekomendasikan agar tim mengembangkan fasilitas untuk secara teratur menyegarkan dan menguji pembaruan kompilator.

Menggunakan metode pengembangan yang aman, versi bahasa, kerangka kerja/API

Kode harus menggunakan metodologi pengembangan, versi bahasa, kerangka kerja, API, dan sebagainya, yang meminimalkan risiko dengan menumbuhkan keamanan dan kesederhanaan di C++, termasuk:

  • Lihat C++ Core Guidelines' Guideline Support Library (GSL) untuk panduan menulis kode C++ modern, aman, dan konsisten yang mengikuti praktik terbaik dan menghindari perangkap umum.
  • Lihat Implementasi Microsoft GSL untuk fungsi dan jenis yang disarankan oleh Pedoman Inti C++ yang Anda gunakan.
  • Kontainer C++ yang aman sumber daya, perlindungan luapan memori pustaka runtime C (CRT): Pilih std::vector dan std::string, yang aman sumber daya. Jika Anda harus menggunakan data C, gunakan versi aman fungsi CRT, yang dirancang untuk membantu mencegah kerusakan memori karena penyalahgunaan buffer dan perilaku bahasa yang tidak terdefinisi.
  • Pustaka Brankas Int melindungi dari luapan bilangan bulat dalam operasi matematika dan perbandingan.

Mengonsumsi dependensi aman

Biner tidak boleh menautkan ke pustaka dan dependensi yang tidak aman. Tim pengembangan harus melacak semua dependensi eksternal dan mengatasi CVE/kerentanan keamanan yang diidentifikasi dalam komponen ini dengan memperbarui ke versi yang lebih aman ketika tunduk pada kerentanan tersebut.

Memaksimalkan jaminan pembuktian kode dan efisiensi respons keamanan

Kompilasi harus memungkinkan jaminan pembuktian kode yang kuat untuk membantu mendeteksi dan mencegah pengenalan backdoor dan kode berbahaya lainnya. Data yang dihasilkan, juga penting untuk penelusuran kesalahan dan investigasi, harus diarsipkan untuk semua rilis perangkat lunak untuk mendorong respons keamanan yang efisien jika disusupi. Sakelar kompilator berikut menghasilkan informasi yang penting untuk respons keamanan:

  • /ZH:SHA_SHA256 di Visual C++ - Memastikan bahwa algoritma yang aman secara kriptografis digunakan untuk menghasilkan semua hash file sumber PDB.
  • /Zi, /ZI (Format Informasi Debug) di Visual C++ - Selain menerbitkan simbol yang dilucuti untuk mengumpulkan data crash dan skenario penggunaan publik lainnya, pastikan bahwa build menghasilkan dan mengarsipkan PDB privat untuk semua biner yang dirilis. Alat analisis biner memerlukan simbol penuh untuk memverifikasi apakah banyak mitigasi keamanan diaktifkan pada waktu kompilasi. Simbol privat sangat penting dalam respons keamanan, dan biaya debugging dan investigasi yang lebih rendah ketika teknisi berlomba untuk menilai dan membatasi kerusakan ketika eksploitasi terjadi.
  • /SOURCELINK di Visual C++ Linker - Sertakan file Sourcelink di PDB: Tautan sumber adalah sistem agnostik kontrol bahasa dan sumber yang menyediakan penelusuran kesalahan sumber untuk biner. Penelusuran kesalahan sumber sangat meningkatkan efisiensi rentang validasi keamanan prarilis dan respons insiden pasca-rilis.

Mengaktifkan kesalahan kompilator untuk mencegah masalah pada waktu penulisan kode

Kompilasi harus mengaktifkan pemeriksaan kompilator yang relevan dengan keamanan sebagai kesalahan yang melanggar, misalnya:

Menandai biner sebagai kompatibel dengan mitigasi keamanan runtime OS

Pengaturan compiler dan linker harus memilih fitur pembuatan kode yang mendeteksi dan mengurangi eksekusi kode berbahaya, termasuk:

Mencegah pengungkapan informasi sensitif

Pengaturan pengkompilasi harus memilih pencegahan penemuan informasi sensitif. Dalam beberapa tahun terakhir, peneliti telah mengungkap kebocoran informasi yang tidak diinginkan yang berasal dari fitur perangkat keras seperti eksekusi spekulatif.

Pada tingkat perangkat lunak, data rahasia mungkin ditransmisikan ke penyerang jika bocor secara tidak terduga. Kegagalan untuk menginisialisasi buffer nol dan penyalahgunaan buffer lainnya dapat membocorkan data rahasia privat kepada penyerang yang memanggil API tepercaya. Kelas masalah ini paling baik ditangani dengan mengaktifkan analisis statis ekstra dan menggunakan kontainer sumber daya aman seperti yang dijelaskan sebelumnya.

  • /Qspectre - Mitigasi serangan saluran samping eksekusi spekulatif - Menyisipkan instruksi penghapus yang membantu mencegah pengungkapan data sensitif yang dihasilkan oleh eksekusi spekulatif. Mitigasi ini harus diaktifkan untuk kode yang menyimpan data sensitif dalam memori dan beroperasi di seluruh batas kepercayaan. Microsoft selalu merekomendasikan pengukuran dampak performa terhadap tolok ukur yang sesuai saat mengaktifkan mitigasi Spectre karena kemungkinan memperkenalkan pemeriksaan runtime dalam blok atau perulangan kritis performa. Jalur kode ini dapat menonaktifkan mitigasi melalui pengubah spectre(nomitigation)declspec . Proyek yang mengaktifkan '/Qspectre'' juga harus ditautkan ke pustaka yang juga dikompilasi dengan mitigasi ini, termasuk pustaka runtime Microsoft.

2.6 Kasus uji kotak hitam

Ringkasan

Pengujian kotak hitam tidak mengandalkan mengetahui cara kerja dalam komponen yang diuji. Pengujian kotak hitam dirancang untuk menguji fungsionalitas menyeluruh fitur dalam produk pada lapisan atau tingkat apa pun. Pengujian kotak hitam dapat berupa pengujian fungsi, pengujian UI, pengujian performa, dan pengujian integrasi. Tes kotak hitam sangat berharga untuk mengukur keandalan umum dan kebenaran fungsi, dan memastikan bahwa produk bereaksi seperti yang diharapkan.

Hubungan dengan bagian lain

Jenis pengujian berbasis persyaratan ini berguna untuk memvalidasi asumsi yang dibuat dalam Model Ancaman dan mencakup potensi ancaman seperti yang dimunculkan di bagian tersebut. Pengujian ini berguna untuk menguji integrasi antara komponen terpisah dari produk, terutama yang berada di seluruh batas kepercayaan seperti yang dijelaskan dalam model ancaman. Kasus pengujian kotak hitam juga berguna untuk menguji semua jenis kasus tepi untuk validasi input pengguna. Menguji kasus tepi yang diketahui dan kasus kesalahan keduanya berguna. Fuzzing juga berguna untuk menguji kasus yang kurang jelas.

Otomatisasi dan regresi

Jalankan pengujian ini secara teratur, dan bandingkan hasilnya dengan eksekusi sebelumnya untuk menangkap perubahan yang melanggar atau regresi performa. Selain itu, menjalankan pengujian ini pada banyak komputer yang berbeda dan pengaturan penginstalan dapat membantu mencakup masalah apa pun yang mungkin timbul dari arsitektur yang berbeda atau perubahan penyiapan.

Crash dump

Pengujian ini membantu menemukan masalah dengan keandalan, mampu menguji banyak skenario berbeda yang mungkin mengalami crash, macet, kebuntuan, dan sebagainya. Dengan mengumpulkan crash dump sebagai bagian dari kegagalan pengujian, Anda dapat mengimpor cadangan langsung ke Visual Studio untuk menyelidiki lebih lanjut bagian kode apa yang mencapai masalah ini. Jika Anda menjalankan pengujian fungsional dari dalam Visual Studio, Anda dapat dengan mudah mereplikasi dan men-debug kegagalan dengan melihat persis di mana di dalam kotak hitam pengujian gagal, dan Anda dapat menguji perbaikan dengan cepat.

Untuk memulai pengujian penelusuran kesalahan, lihat Debug pengujian unit dengan Test Explorer - Visual Studio (Windows)

Di Azure

Azure DevOps juga dapat membantu mengelola dan memvalidasi pengujian ini dengan penggunaan Paket Pengujian. Pengujian ini dapat digunakan untuk memastikan persetujuan dengan validasi manual, dan untuk menjalankan pengujian otomatis yang terkait dengan persyaratan produk. Informasi selengkapnya tentang Azure Test Plans dan menggunakannya untuk menjalankan pengujian otomatis dapat ditemukan di sini:

2.7 Kasus pengujian berbasis kode

Ringkasan

Kasus pengujian berbasis kode adalah bagian integral dari menjaga keamanan dan keandalan produk Anda. Tes ini harus kecil dan cepat dan seharusnya tidak berdampak satu sama lain sehingga dapat dijalankan secara paralel. Pengujian berbasis kode mudah bagi pengembang untuk berjalan secara lokal di mesin pengembangan mereka kapan saja mereka membuat perubahan pada kode tanpa khawatir memperlambat siklus pengembangan mereka.

Jenis, dan hubungan dengan bagian lain

Jenis umum kasus pengujian berbasis kode meliputi:

  • pengujian unit,
  • pengujian parameter untuk mencakup fungsi dengan beberapa jenis input,
  • pengujian komponen untuk memisahkan setiap komponen pengujian, dan
  • pengujian tiruan untuk memvalidasi bagian kode yang berkomunikasi dengan layanan lain, tanpa memperluas cakupan pengujian untuk menyertakan layanan tersebut sendiri.

Pengujian ini didasarkan pada kode internal yang ditulis, sedangkan pengujian kotak hitam didasarkan pada persyaratan fungsional eksternal produk.

Tujuan

Melalui pengujian ini, tujuannya adalah untuk mencapai tingkat cakupan pengujian yang tinggi atas kode Anda. Anda harus secara aktif melacak cakupan ini dan di mana celah ada. Saat Anda menambahkan lebih banyak pengujian yang menjalankan lebih banyak jalur kode, keyakinan keseluruhan pada keamanan dan keandalan kode Anda meningkat.

Visual Studio

Alat penjelajah pengujian di Visual Studio memudahkan untuk sering menjalankan pengujian ini dan mendapatkan umpan balik tentang tingkat pass/fail dan lokasi kegagalan dengan cepat. Banyak kerangka kerja pengujian juga mendukung fitur CodeLens untuk melihat status pengujian di lokasi pengujian itu sendiri, membuat penambahan dan pemeliharaan rangkaian pengujian lebih mudah. Test Explorer juga memudahkan pengelolaan pengujian ini, memungkinkan grup pengujian, daftar putar pengujian kustom, pemfilteran, pengurutan, pencarian, dan banyak lagi.

Untuk informasi selengkapnya, lihat:

Visual Studio juga dilengkapi dengan alat untuk melacak cakupan kode. Alat-alat ini memungkinkan Anda memastikan bahwa perubahan kode yang Anda buat tercakup oleh pengujian yang ada, atau untuk menambahkan pengujian baru untuk mencakup jalur kode baru dan yang belum diuji. Alat ini juga menunjukkan persentase cakupan kode untuk memastikannya dipertahankan di atas tingkat target untuk keyakinan dalam kualitas kode keseluruhan.

Untuk informasi tentang alat-alat ini, lihat Pengujian cakupan kode - Visual Studio (Windows)

Di Azure

Azure DevOps juga dapat membantu dalam melacak hasil cakupan kode untuk seluruh produk sebagai bagian dari proses alur build. Untuk informasi selengkapnya, lihat Meninjau cakupan kode - Azure Pipelines.

2.8 Kasus pengujian historis

Ringkasan

Kasus pengujian historis, juga dikenal sebagai kasus pengujian regresi, mencegah masalah lama muncul kembali dan meningkatkan cakupan pengujian keseluruhan produk. Anda harus memastikan bahwa ketika bug diperbaiki, proyek juga menambahkan kasus pengujian yang sesuai. Seiring waktu, saat perbaikan dilakukan, ketahanan keseluruhan rangkaian pengujian akan terus meningkat, memberikan jaminan keandalan dan keamanan yang lebih baik.

Kualitas utama, dan hubungannya dengan bagian lain

Karena mereka menguji regresi bug, pengujian ini harus cepat dan mudah dijalankan, sehingga mereka dapat berjalan bersama [Kasus Pengujian Berbasis Kode] dan berkontribusi pada cakupan kode keseluruhan produk. Seiring dengan ini, menggunakan contoh nyata dari pelanggan untuk menginspirasi kasus pengujian baru adalah cara yang bagus untuk meningkatkan cakupan dan kualitas pengujian.

Visual Studio

Visual Studio memungkinkan Anda dengan mudah menambahkan pengujian ke suite sambil membuat perubahan untuk memperbaiki bug, dan dengan cepat menjalankan pengujian dan cakupan kode untuk memastikan semua kasus baru dipertimbangkan. Mereferensikan ID bug dari sistem pelacakan masalah Anda dalam kode Anda di mana Anda menulis pengujian adalah cara yang baik untuk menghubungkan pengujian regresi ke masalah yang sesuai. Lebih suka menggunakan Azure Boards dan paket pengujian bersama dengan Visual Studio:

  • untuk mengaitkan pengujian, kasus pengujian, dan masalah; Dan
  • untuk melacak semua aspek masalah dan pengujian yang sesuai.

Untuk informasi selengkapnya, lihat:

Akhirnya, mengintegrasikan pengujian ini ke dalam area pengujian unit yang seharusnya mencakup bagian kode membantu menjaga rangkaian pengujian tetap terorganisir dan lebih mudah dikelola. Anda dapat menggunakan pengelompokan pengujian Test Explorer untuk melacak pengujian yang dimiliki bersama secara efektif. Untuk informasi selengkapnya, lihat Menjalankan pengujian unit dengan Test Explorer - Visual Studio (Windows)

2.9 Fuzzing

Summary Fuzzing (juga dikenal sebagai pengujian fuzz) adalah teknik pengujian perangkat lunak otomatis yang melibatkan penyediaan data yang tidak valid, tidak terduga, atau acak sebagai input ke program. Program ini kemudian dipantau untuk pengecualian seperti crash, pernyataan kode bawaan atau kompilator yang gagal disuntikkan dan potensi kebocoran memori.

Panduan

Gunakan fuzzing pada semua perangkat lunak yang mungkin memproses input yang tidak tepercaya yang dapat dikontrol oleh penyerang. Jika Anda membangun aplikasi baru dan rangkaian pengujian terkait, sertakan fuzzing untuk modul kunci sedini mungkin. Menjalankan fuzzing untuk pertama kalinya pada perangkat lunak hampir selalu mengungkap kerentanan aktual yang sebelumnya tidak diketahui. Setelah anda mulai fuzzing, jangan pernah berhenti.

Hubungan dengan bagian lain

Ketika fuzzing melaporkan kegagalan, selalu secara alami menyediakan kasus pengujian yang dapat direproduksi yang menunjukkan bug. Kasus pengujian ini dapat direproses, diselesaikan, lalu ditambahkan ke Kasus Pengujian Historis.

Saat menggunakan kedua sanitizer seperti Address Sanitizer (ASan) dan fuzzing:

  • Pertama-tama jalankan pengujian normal Anda dengan sanitizer diaktifkan untuk melihat apakah ada masalah, maka setelah kodenya adalah sanitizer-clean mulai fuzzing.
  • Untuk C atau C++, ada kompilator yang mengotomatiskan injeksi pernyataan runtime dan meta-data yang mengaktifkan ASan. Saat dikompilasi untuk ASan, tautan biner yang dihasilkan dengan pustaka runtime yang justru dapat mendiagnosis 15+ kategori kesalahan keamanan memori dengan nol positif palsu. Untuk C atau C++ saat Anda memiliki sumber, gunakan LibFuzzer, yang mengharuskan ASan diaktifkan terlebih dahulu.
  • Untuk pustaka yang ditulis dalam Java, C#, Python, Rust, dan sebagainya, gunakan kerangka kerja AFL++.

Kualitas utama

  • Fuzzing menemukan kerentanan yang sering dilewatkan oleh analisis program statis, pengujian fitur lengkap, dan inspeksi kode manual.
  • Fuzzing adalah cara efektif untuk menemukan bug keamanan dan keandalan dalam perangkat lunak, sehingga Siklus Hidup Pengembangan Keamanan Microsoft memerlukan fuzzing di setiap antarmuka yang tidak tepercaya dari setiap produk (lihat juga Pemodelan Ancaman).
  • Selalu gunakan fuzzing untuk perangkat lunak yang mungkin memproses input yang tidak tepercaya.
  • Fuzzing efektif untuk aplikasi mandiri dengan pengurai data besar.

Azure dan GitHub CI/CD

Ubah build Anda untuk mendukung pembuatan executable berkelanjutan yang menggunakan LibFuzzer atau AFL++. Anda dapat menambahkan sumber daya komputasi tambahan yang diperlukan untuk fuzzing di layanan seperti OSS-Fuzz atau OneFuzz.

2.10 Pemindaian Aplikasi Web

Ringkasan

Dalam cakupan Microsoft Visual C++ di Windows, Microsoft merekomendasikan:

  • Pilih TypeScript, JavaScript, dan ASP.NET untuk aplikasi web.
  • Jangan menulis ekstensi web di C++. Microsoft telah menghentikan ActiveX.
  • Ketika kode dikompilasi ke Emscripten/WASM, kode tidak lagi C++ dan alat lainnya berlaku.
  • Microsoft menyediakan RESTler, fuzzer REST API stateful.

Gambaran umum dan kualitas utama

Pemindai aplikasi web menjelajahi aplikasi web dengan menjelajahi halaman webnya dan memeriksanya untuk kerentanan keamanan. Perayapan ini melibatkan pembuatan otomatis input berbahaya dan evaluasi respons aplikasi. Secara kritis, pemindaian aplikasi web harus mencakup/mendukung:

  • Katalog semua aplikasi web di jaringan Anda, termasuk aplikasi baru dan yang tidak dikenal, dan menskalakan dari beberapa aplikasi ke ribuan.
  • Pemindaian mendalam untuk versi perangkat lunak, layanan SOAP dan REST API dan API yang digunakan oleh perangkat seluler.
  • Penyisipan primitif keamanan ke dalam pengembangan dan penyebaran aplikasi di lingkungan DevOps. Primitif ini bekerja dengan perayap.
  • Deteksi malware.

2.11 Periksa Komponen Perangkat Lunak yang Disertakan

Ringkasan

Tangani kode C++ Anda sama dengan kode yang ditulis dalam bahasa pemrograman lain, dan terapkan alat Analisis Komposisi Perangkat Lunak (SCA) dan Analisis Asal (OA) yang diadopsi oleh perusahaan Anda ke kode C++Anda. Alur kerja dan pemindaian keamanan harus dirancang sebagai bagian dari sistem CI/CD (integrasi berkelanjutan dan pengiriman berkelanjutan).

Pertahanan upstram

Untuk mengurangi risiko serangan pada dependensi hulu, sumber/komponen pihak ketiga harus disimpan pada aset yang dikendalikan perusahaan, di mana alat SCA dan OA dijalankan.

  • Alat harus memindai dan memperingatkan kapan kerentanan diidentifikasi (termasuk database publik) seperti: Beranda | CVE
  • Jalankan analisis statis pada semua komponen perangkat lunak yang disertakan dalam aplikasi/repositori Anda untuk mengidentifikasi pola kode yang rentan.

Pertahanan dependensi

Lakukan dan pertahankan audit dependensi untuk memvalidasi bahwa semua kejadian tersebut diperhitungkan dan dicakup oleh alat SCA dan OA Anda.

  • Komponen harus diaudit secara teratur dan diperbarui ke versi terverifikasi terbaru.
  • Dependensi umpan paket.
  • Alat SCA/OA mencakup dan mengaudit semua dependensi paket yang berasal dari satu umpan.

SBOM

Hasilkan SBOM (tagihan perangkat lunak bahan) dengan produk Anda mencantumkan semua dependensi seperti:

  • asal (misalnya, URL (Uniform Resource Locator))
  • versi
  • konsistensi (misalnya, hash sumber SHA-256), dan cara lain untuk memvalidasi konsistensi seperti build deterministik.
  • Memerlukan dan mengaudit file SBOM dalam dependensi perangkat lunak atau diproduksi sebagai bagian dari build termasuk OSS (perangkat lunak sumber terbuka).
  • Microsoft menstandarkan dan merekomendasikan SPDX (Software Package Data Exchange) versi 2.2 atau yang lebih baru | Linux Foundation sebagai format dokumen SBOM.
  • Determinisme build dapat digunakan untuk menghasilkan biner identik bit-bijaksana secara independen dan memberikan verifikasi independen integritas:
    • Pengesahan reproduksi pihak pertama atau pihak ketiga
    • Teknik lain seperti penandatanganan biner melalui sumber sertifikat tepercaya juga dapat memberikan beberapa jaminan integritas biner.

Sumber Daya Tambahan:

Solusi Microsoft mencakup panduan dan produk berikut: