Menyiapkan database untuk CodeQL

Selesai

CodeQL memperlakukan kode seperti data. Analisis CodeQL bergantung pada ekstraksi data relasional dari kode Anda dan menggunakannya untuk membangun database CodeQL. Database ini berisi semua informasi penting tentang basis kode.

Anda kemudian dapat menjalankan kueri CodeQL terhadap database ini untuk mengidentifikasi kerentanan keamanan, bug, dan kesalahan lainnya. Anda dapat menulis kueri Anda sendiri atau menjalankan kueri CodeQL standar yang ditulis oleh peneliti GitHub dan kontributor komunitas.

Anda dapat menggunakan CodeQL CLI mandiri untuk membuat dan menganalisis database CodeQL. Menganalisis database menghasilkan hasil dalam Format Pertukaran Hasil Analisis Statis (SARIF), yang dapat diunggah ke repositori GitHub untuk melihat detail pemberitahuan.

Arsitektur pemindaian CodeQL

Pemindaian CodeQL mengikuti alur yang mengubah kode sumber menjadi data yang dapat dikueri, menjalankan kueri keamanan, dan menerbitkan hasilnya sebagai pemberitahuan pemindaian kode.

Alur kerja pemindaian adalah:

  1. Kode sumber: CodeQL diawali dengan isi repositori pada commit yang sedang dianalisis.
  2. Ekstraksi: Ekstraktor khusus bahasa membaca kode dan mengumpulkan fakta tentang file sumber, sintaksis, alur kontrol, dan aliran data.
  3. Pembuatan database: Fakta yang diekstrak disimpan dalam database CodeQL. Setiap database mewakili satu bahasa dalam basis kode.
  4. Eksekusi kueri: CodeQL menjalankan kueri yang dikelola GitHub, kueri komunitas, atau kueri kustom terhadap database.
  5. Generasi SARIF: Hasil kueri ditulis dalam Format Pertukaran Hasil Analisis Statis (SARIF).
  6. GitHub pemindaian kode: Hasil SARIF diunggah ke GitHub dan ditampilkan sebagai pemberitahuan pemindaian kode.

Arsitektur ini memisahkan ekstraksi kode dari eksekusi kueri. Setelah database dibuat, Anda dapat menjalankan suite kueri yang berbeda terhadap database yang sama tanpa mengekstrak kode lagi.

Strategi bahasa

CodeQL mendukung bahasa yang dikompilasi dan ditafsirkan, tetapi strategi ekstraksi tergantung pada jenis bahasa.

Bahasa yang dikompilasi

Untuk bahasa yang dikompilasi seperti:

  • C/C++
  • C#
  • Java
  • Kotlin
  • Rust
  • Cepat
  • Go

CodeQL sering kali perlu memahami bagaimana proyek dibangun. Selama pembuatan database, CodeQL dapat memantau proses build sehingga dapat mengekstrak file sumber yang diproses oleh pengkompilasi.

Untuk hasil yang paling andal, konfigurasikan perintah build eksplisit daripada mengandalkan pembuatan otomatis atau tanpa opsi build .

Bahasa yang ditafsirkan

Untuk bahasa yang ditafsirkan seperti:

  • Python
  • JavaScript/TypeScript
  • Ruby

CodeQL mengekstrak informasi langsung dari kode sumber tanpa memerlukan perintah build terpisah.

Repositori multibahasa

Untuk repositori yang berisi beberapa bahasa yang didukung:

  • Buat database terpisah untuk setiap bahasa.
  • Dalam GitHub Actions, gunakan matriks bahasa sehingga setiap bahasa diinisialisasi, diekstrak, dan dianalisis dengan benar.

Persiapan database untuk CodeQL

Sebelum membuat database CodeQL:

  1. Instal dan konfigurasikan CodeQL CLI.
  2. Lihat versi basis kode yang ingin Anda analisis.

Untuk bahasa yang dikompilasi:

  • Pastikan proyek siap dibangun.
  • Instal semua dependensi yang diperlukan sebelumnya.
  • CodeQL mengekstrak representasi relasional dari setiap file sumber untuk membuat database.

Untuk bahasa yang ditafsirkan:

  • Ekstraktor berjalan langsung pada kode sumber.
  • Dependensi diselesaikan secara otomatis selama ekstraksi.

Untuk bahasa yang dikompilasi, CodeQL memantau proses build normal. Setiap kali pengkompilasi memproses file sumber, CodeQL membuat salinan dan mengekstrak semua informasi relevan yang diperlukan untuk analisis.

Penyiapan CLI

Ikuti langkah-langkah ini untuk menginstal CodeQL CLI.

1. Unduh bundel CodeQL CLI

Metode penginstalan yang direkomendasikan adalah mengunduh paket yang dibundel, yang memastikan kompatibilitas antara CLI, pustaka, dan paket kueri.

Bundel mencakup:

  • CodeQL CLI
  • Kueri dan pustaka CodeQL yang kompatibel
  • Paket kueri yang telah dikompilasi sebelumnya

Untuk mengunduh bundel:

  1. Buka halaman Rilis repositori publik CodeQL.
  2. Unduh bundel khusus platform di bawah Aset .

Halaman Rilis juga mencakup:

  • Catatan rilis
  • Versi sebelumnya
  • codeql-bundle.tar.gz, yang mendukung semua platform

2. Ekstrak arsip

.zip Ekstrak arsip ke dalam direktori pilihan Anda.

Pengguna macOS Catalina (atau yang lebih baru) harus menyelesaikan langkah-langkah penyiapan tambahan seperti yang dijelaskan dalam dokumentasi CodeQL CLI.

3. Jalankan CodeQL

Setelah ekstraksi, salah satu dari berikut:

  • Jalankan:
<extraction-root>/codeql/codeql

or

  • Tambahkan:
<extraction-root>/codeql

ke sistem PATH Anda sehingga Anda dapat memanggil CLI hanya sebagai:

codeql

Sekarang Anda dapat menjalankan perintah CodeQL.

Memverifikasi penyiapan CLI Anda

Jalankan perintah berikut untuk memverifikasi bahwa penginstalan Anda berfungsi dengan benar.

Tampilkan paket CodeQL yang diinstal:

codeql resolve packs

Jika file executable tidak ada di PATH, gunakan:

<extraction-root>/codeql/codeql resolve packs

Jika paket bahasa yang diharapkan hilang, verifikasi bahwa Anda mengunduh bundel CodeQL, bukan CLI mandiri.

Tampilkan bahasa yang didukung:

codeql resolve languages

Pembuatan database

Buat database CodeQL dari akar proyek Anda:

codeql database create <database> --language=<language-identifier>

Mengganti:

  • <database> dengan direktori tujuan.
  • <language-identifier> dengan pengidentifikasi bahasa yang akan dianalisis.

Anda juga bisa menggunakan opsi berikut ini:

Option Purpose
--source-root Menentukan direktori akar yang berisi kode sumber.
--db-cluster Membuat database untuk beberapa bahasa.
--command Menentukan perintah build untuk bahasa yang dikompilasi. Tidak diperlukan untuk Python, Ruby, atau JavaScript.
--no-run-unnecessary-builds Melompati build yang tidak perlu saat digunakan dengan --db-cluster.

Setelah eksekusi berhasil:

  • Direktori database baru dibuat.
  • Saat menggunakan --db-cluster, subdirektori dibuat untuk setiap bahasa.

Setiap database berisi:

  • Data untuk analisis relasional
  • Arsip sumber
  • Metadata diperlukan untuk analisis CodeQL

Arsip sumber adalah rekam jepret file sumber pada saat database dibuat dan digunakan saat menampilkan hasil analisis.

Pembuatan database dan pertimbangan performa

Setelah membuat database CodeQL, penting untuk memahami cara kerja pembuatan database dan bagaimana pengaruhnya terhadap performa.

Metode pembuatan database

Anda dapat membuat database CodeQL menggunakan:

CodeQL CLI

Buat database dan jalankan analisis secara manual.

Pendekatan ini berguna untuk:

  • Pengembangan lokal
  • Pemecahan Masalah
  • Konfigurasi tingkat lanjut

alur kerja GitHub Actions

Sebagian besar organisasi mengotomatiskan pembuatan database melalui GitHub Actions.

Alur kerja umum:

  1. Menginisialisasi CodeQL.
  2. Membuat basis data.
  3. Menjalankan kueri.
  4. Mengunggah hasil SARIF ke GitHub.

Database per bahasa

CodeQL membuat database terpisah untuk setiap bahasa yang didukung.

Setiap bahasa:

  • Menggunakan ekstraktornya sendiri.
  • Menggunakan skema databasenya sendiri.
  • Dianalisis secara independen.

Untuk repositori multibahasa, lakukan salah satu hal berikut:

  • Gunakan opsi --db-cluster dengan CLI.
  • Konfigurasikan matriks bahasa di GitHub Actions.

Matriks bahasa memungkinkan analisis paralel dan cakupan bahasa lengkap.

Ekstraksi berbasis build untuk bahasa yang dikompilasi

Untuk bahasa yang dikompilasi:

  • CodeQL memantau proses build.
  • Proses build harus berhasil diselesaikan.
  • Autobuild otomatis tidak selalu berfungsi dengan andal untuk semua proyek.

Untuk hasil terbaik, tentukan langkah-langkah build eksplisit sebelum analisis.

Untuk bahasa yang ditafsirkan, CodeQL mengekstrak langsung dari kode sumber tanpa memerlukan build.

Pertimbangan performa

Waktu pembuatan dan analisis database tergantung pada beberapa faktor.

Ukuran repositori

Repositori yang lebih besar membutuhkan lebih banyak waktu ekstraksi dan analisis.

Beberapa bahasa

Gunakan matriks bahasa untuk menganalisis bahasa secara paralel dan mengurangi total runtime.

Sumber daya CI

Analisis CodeQL dapat memerlukan banyak sumber daya.

Meningkatkan CPU atau memori untuk pelari dapat secara signifikan meningkatkan performa.

Cakupan analisis

Anda dapat mengurangi waktu analisis dengan membatasi kode yang dipindai, misalnya dengan mengecualikan:

  • Menguji file
  • Kode yang dihasilkan

Secara umum, waktu analisis sebanding dengan jumlah kode sumber yang sedang diproses.

Pembuatan dan regenerasi database

Database CodeQL mewakili rekam jepret basis kode pada titik waktu tertentu.

  • Database baru dibuat untuk setiap eksekusi analisis.
  • Database tidak diperbarui secara bertahap.
  • Setiap perubahan pada basis kode memerlukan database baru.

Anda biasanya meregenerasi database saat:

  • Penerapan baru didorong.
  • Permintaan pull dibuka atau diperbarui.
  • Buat perubahan konfigurasi.
  • Kumpulan kueri atau perubahan konfigurasi analisis.

Karena pembuatan database adalah bagian dari setiap pemindaian, penting untuk menyelaraskan pemindaian dengan peristiwa yang bermakna, seperti permintaan pull atau eksekusi terjadwal.

Ekstraktor

Ekstraktor adalah alat yang menghasilkan data relasional dan referensi sumber untuk setiap file input, tempat database CodeQL dapat dibuat. Setiap bahasa yang didukung CodeQL memiliki satu ekstraktor. Struktur ini memastikan bahwa proses ekstraksi seakurat mungkin.

Setiap ekstraktor mendefinisikan sekumpulan opsi konfigurasinya sendiri. Memasukkan codeql resolve extractor --format=betterjson menghasilkan data yang diformat seperti contoh berikut:

{
  "extractor_root": "/home/user/codeql/java",
  "extractor_options": {
    "option1": {
      "title": "Java extractor option 1",
      "description": "An example string option for the Java extractor.",
      "type": "string",
      "pattern": "[a-z]+"
    },
    "group1": {
      "title": "Java extractor group 1",
      "description": "An example option group for the Java extractor.",
      "type": "object",
      "properties": {
        "option2": {
          "title": "Java extractor option 2",
          "description": "An example array option for the Java extractor",
          "type": "array",
          "pattern": "[1-9][0-9]*"
        }
      }
    }
  }
}

Untuk mengetahui opsi mana yang tersedia untuk ekstraktor bahasa Anda, masukkan:

  • codeql resolve languages --format=betterjson atau
  • codeql resolve extractor --format=betterjson.

Format output betterjson juga menyediakan akar ekstraktor dan opsi khusus bahasa lainnya.

Data dalam database CodeQL

Database CodeQL adalah satu direktori yang berisi semua data yang diperlukan untuk analisis. Data ini mencakup data relasional, file sumber yang disalin, dan skema database khusus bahasa yang menentukan hubungan timbul dalam data. CodeQL mengimpor data ini setelah ekstraksi.

Database CodeQL menyediakan rekam jepret dari data bahasa tertentu yang dapat dikueri yang diekstrak dari basis kode. Data ini adalah representasi kode yang lengkap dan hierarkis. Ini termasuk:

  • Representasi pohon sintaks abstrak (AST).
  • Grafik aliran data.
  • Grafik aliran kontrol.

Database dihasilkan satu bahasa pada satu waktu untuk basis kode beberapa bahasa. Setiap bahasa memiliki skema database uniknya sendiri. Skema ini menyediakan antarmuka antara analisis leksikal awal selama proses ekstraksi dan analisis kompleks melalui CodeQL.

Database CodeQL menyertakan dua tabel utama:

  • Tabel ekspresi berisi baris untuk setiap ekspresi dalam kode sumber yang dianalisis CodeQL selama proses build.
  • Tabel pernyataan berisi baris untuk setiap pernyataan dalam kode sumber yang dianalisis CodeQL selama proses build.

Pustaka CodeQL mendefinisikan kelas untuk menyediakan lapisan abstraksi atas masing-masing tabel ini. Lapisan ini mencakup tabel tambahan terkait Expr dan Stmt.

Kemungkinan Kelemahan CodeQL

Pembuatan database dalam alur kerja pemindaian kode memiliki beberapa potensi kekurangan. Bagian ini secara khusus membahas penggunaan GitHub CodeQL Action.

Anda perlu menggunakan matriks bahasa untuk pembuatan otomatis untuk membangun setiap bahasa yang dikompilasi yang tercantum dalam matriks. Anda dapat menggunakan matriks untuk membuat pekerjaan untuk lebih dari satu versi bahasa pemrograman, sistem operasi, atau alat yang didukung.

Jika Anda tidak menggunakan matriks, autobuild akan mencoba membangun proyek menggunakan bahasa terkompilasi yang didukung dengan jumlah file sumber terbanyak di repositori. Analisis bahasa yang dikompilasi, selain Go, sering gagal kecuali Anda menyediakan perintah eksplisit untuk membangun kode sebelum melakukan langkah analisis.

Perilaku langkah pembuatan otomatis bervariasi tergantung pada sistem operasi tempat ekstraktor bahasa berjalan. Langkah autobuild mencoba mendeteksi secara otomatis metode build yang sesuai untuk bahasa tersebut berdasarkan sistem operasi. Perilaku ini dapat menyebabkan hasil yang tidak dapat diandalkan untuk bahasa yang dikompilasi dan sering kali dapat mengakibatkan eksekusi yang gagal.

Kami menyarankan agar Anda mengonfigurasi langkah build dalam file alur kerja pemindaian kode yang berjalan sebelum analisis, daripada membiarkan pembuatan otomatis mencoba membangun bahasa yang dikompilasi. Dengan cara ini, file alur kerja disesuaikan dengan persyaratan build sistem dan proyek Anda untuk pemindaian yang lebih andal.

Anda dapat membaca selengkapnya tentang bahasa tertentu dan langkah-langkah pembuatan otomatis dalam dokumentasi pembuatan otomatis CodeQL.

Ekstensi Visual Studio Code

Anda dapat menggunakan Visual Studio Code (VISUAL Code) dan ekstensi CodeQL untuk mengkompilasi dan menjalankan kueri, selama Anda menggunakan VISUAL Code 1.39 atau yang lebih baru. Anda dapat mengunduh ekstensi dari Visual Studio Code Marketplace atau dengan mengunduh file CodeQL VSIX.

Ekstensi ini menggunakan CLI yang telah diinstal yang ditemukan di PATH jika tersedia. Jika tidak, ekstensi secara otomatis mengelola akses ke file CLI yang dapat dieksekusi untuk Anda. Manajemen otomatis memastikan bahwa CLI kompatibel dengan ekstensi CodeQL.