Manajemen ketergantungan

Dokumen ini menjelaskan dependensi aplikasi dan praktik terbaik untuk mengelolanya, termasuk pemantauan kerentanan, verifikasi artefak, mengurangi jejak dependensi, dan dukungan build yang dapat direproduksi.

Dependensi software adalah software yang diperlukan aplikasi Anda agar berfungsi seperti library software atau plugin. Menyelesaikan dependensi dapat terjadi saat Anda mengompilasi kode, mem-build, menjalankan, mendownload, atau menginstal software.

Dependensi dapat mencakup komponen yang Anda buat, software pihak ketiga eksklusif, dan software open source. Pendekatan yang Anda lakukan untuk mengelola dependensi dapat memengaruhi keamanan dan keandalan aplikasi Anda.

Spesifikasi untuk mengimplementasikan praktik terbaik dapat bervariasi berdasarkan format artefak dan alat yang Anda gunakan, tetapi prinsip umumnya masih berlaku.

Dependensi langsung dan transitif

Aplikasi Anda dapat menyertakan dependensi langsung dan transitif:

Dependensi langsung
Komponen software yang dirujuk aplikasi secara langsung.
Dependensi transitif
Komponen software yang diperlukan dependensi langsung aplikasi secara fungsional. Setiap dependensi dapat memiliki dependensi langsung dan tidak langsungnya sendiri, membuat pohon rekursif dependensi transitif yang semuanya memengaruhi aplikasi.

Bahasa pemrograman yang berbeda menawarkan tingkat visibilitas yang berbeda pula terhadap dependensi dan hubungannya. Selain itu, beberapa bahasa menggunakan pengelola paket untuk me-resolve hierarki dependensi saat menginstal atau men-deploy paket.

Dalam ekosistem Node.js, pengelola paket npm dan benang menggunakan file kunci untuk mengidentifikasi versi dependensi untuk membuat modul dan versi dependensi yang didownload oleh pengelola paket untuk penginstalan modul tertentu. Dalam ekosistem bahasa lain seperti Java, dukungan untuk introspeksi dependensi lebih terbatas. Selain itu, sistem build harus menggunakan pengelola dependensi tertentu untuk mengelola dependensi secara sistematis.

Sebagai contoh, pertimbangkan modul npm glob versi 8.0.2. Anda mendeklarasikan dependensi langsung untuk modul npm dalam file package.json. Dalam file package.json untuk glob, bagian dependencies mencantumkan dependensi langsung untuk paket yang dipublikasikan. Bagian devDepdencies mencantumkan dependensi untuk pengembangan dan pengujian lokal oleh pengelola dan kontributor glob

  • Di situs npm, halaman glob mencantumkan dependensi langsung dan dependensi pengembangan, tetapi tidak menunjukkan apakah modul tersebut juga memiliki dependensinya sendiri.

  • Anda dapat menemukan informasi dependensi tambahan tentang glob di situs Open Source Insights. Daftar dependensi untuk glob mencakup dependensi langsung dan dependensi tidak langsung (transitif).

    Dependensi transitif dapat berada di beberapa lapisan dalam hierarki dependensi. Contoh:

    1. glob 8.0.2 memiliki dependensi langsung pada minimatch 5.0.1.
    2. minimatch 5.0.1 memiliki dependensi langsung brace-expression 2.0.1.
    3. brace-expression 2.0.1 memiliki dependensi langsung pada balanced-match 1.0.2.

Tanpa visibilitas ke dependensi tidak langsung, sangat sulit untuk mengidentifikasi serta merespons kerentanan dan masalah lain yang berasal dari komponen yang tidak direferensikan secara langsung oleh kode Anda.

Saat Anda menginstal paket glob, npm akan me-resolve seluruh hierarki dependensi dan menyimpan daftar versi tertentu yang didownload dalam file package.lock.json, sehingga Anda memiliki data semua dependensi. Penginstalan berikutnya di lingkungan yang sama akan mengambil versi yang sama.

Alat untuk insight dependensi

Anda dapat menggunakan alat berikut untuk membantu memahami dependensi open source dan mengevaluasi postur keamanan project Anda. Alat-alat ini menyediakan informasi dalam berbagai format paket.

Perlindungan Pengiriman Software
Solusi keamanan supply chain software yang terkelola sepenuhnya di Google Cloud yang memungkinkan Anda melihat insight keamanan untuk artefak Anda di Cloud Build, Cloud Run, dan GKE, termasuk kerentanan, informasi dependensi, software bill of materials (SBOM), dan provenance build. Software Delivery Shield juga menyediakan layanan dan fitur lainnya untuk meningkatkan postur keamanan Anda di seluruh siklus proses pengembangan software.
Alat open source

Ada sejumlah alat open source yang tersedia, termasuk:

  • Open Source Insights: Situs yang memberikan informasi tentang dependensi langsung dan tidak langsung yang diketahui, kerentanan yang diketahui, dan informasi lisensi untuk software open source. Project Open Source Insights juga membuat data ini tersedia sebagai Set Data Google Cloud. Anda dapat menggunakan BigQuery untuk mempelajari dan menganalisis data.

  • Database Kerentanan Open Source: Database kerentanan yang dapat ditelusuri yang menggabungkan kerentanan dari database lain ke dalam satu lokasi.

  • Kartu skor Alat otomatis yang dapat Anda gunakan untuk mengidentifikasi praktik supply chain software yang berisiko dalam project GitHub Anda. Fungsi ini melakukan pemeriksaan terhadap repositori dan memberi setiap pemeriksaan skor dari 0 hingga 10. Anda kemudian dapat menggunakan skor tersebut untuk mengevaluasi kondisi keamanan proyek Anda.

  • Allstar: Aplikasi GitHub yang terus memantau organisasi atau repositori GitHub kepatuhan terhadap kebijakan yang dikonfigurasi. Misalnya, Anda dapat menerapkan kebijakan ke organisasi GitHub Anda yang memeriksa kolaborator di luar organisasi yang memiliki administrator atau akses push.

Pendekatan untuk memasukkan dependensi

Ada beberapa metode umum untuk menyertakan dependensi dengan aplikasi Anda:

Instal langsung dari sumber publik
Instal dependensi open source langsung dari repositori publik, seperti Docker Hub, npm, PyPI, atau Maven Central. Pendekatan ini praktis karena Anda tidak perlu mempertahankan dependensi eksternal. Namun, karena Anda tidak mengontrol dependensi eksternal ini, supply chain software Anda lebih rentan terhadap serangan supply chain open source.
Menyimpan salinan dependensi di repositori sumber Anda
Pendekatan ini juga dikenal sebagai vendor. Daripada menginstal dependensi eksternal dari repositori publik selama proses build, Anda sebaiknya mendownload dan menyalinnya ke dalam hierarki sumber project. Anda memiliki lebih banyak kontrol atas dependensi vendor yang digunakan, tetapi ada beberapa kelemahan:
  • Dependensi yang di-vendor meningkatkan ukuran repositori sumber dan menghasilkan lebih banyak churn.
  • Anda harus memasukkan dependensi yang sama ke dalam setiap aplikasi terpisah. Jika repositori sumber atau proses build Anda tidak mendukung modul sumber yang dapat digunakan kembali, Anda mungkin perlu mengelola beberapa salinan dependensi.
  • Mengupgrade dependensi vendor bisa jadi lebih sulit.
Menyimpan dependensi dalam registry pribadi
Registry pribadi, seperti Artifact Registry, memberikan kemudahan penginstalan dari repositori publik serta kontrol atas dependensi Anda. Dengan Artifact Registry, Anda dapat:
  • Sentralisasikan artefak build dan dependensi untuk semua aplikasi Anda.
  • Konfigurasikan klien paket Docker dan bahasa Anda untuk berinteraksi dengan repositori pribadi di Artifact Registry dengan cara yang sama seperti yang mereka lakukan dengan repositori publik.
  • Memiliki kontrol yang lebih besar atas dependensi Anda di repositori pribadi:
  • Batasi akses ke setiap repositori dengan Identity and Access Management.
  • Gunakan repositori jarak jauh untuk meng-cache dependensi dari sumber publik upstream dan memindainya untuk menemukan kerentanan (pratinjau pribadi).
  • Gunakan repositori virtual untuk mengelompokkan repositori jarak jauh dan pribadi di belakang satu titik akhir. Tetapkan prioritas pada setiap repositori untuk mengontrol urutan penelusuran saat mendownload atau menginstal artefak (pratinjau pribadi).
  • Gunakan Artifact Registry dengan mudah bersama layanan Google Cloud lainnya di Software Delivery Shield, termasuk Cloud Build, Cloud Run, dan Google Kubernetes Engine. Gunakan pemindaian kerentanan otomatis di seluruh siklus proses pengembangan software, buat provenance build, kontrol deployment, dan lihat insight tentang postur keamanan Anda.

Jika memungkinkan, gunakan registry pribadi untuk dependensi Anda. Jika Anda tidak dapat menggunakan registry pribadi, pertimbangkan untuk mem-vendor dependensi sehingga Anda memiliki kendali atas konten dalam supply chain software Anda.

Versi disematkan

Penyematan versi berarti membatasi dependensi aplikasi ke versi atau rentang versi tertentu. Idealnya, Anda menyematkan satu versi dependensi.

Penyematan versi dependensi membantu memastikan bahwa build aplikasi Anda dapat direproduksi. Namun, ini juga berarti bahwa build Anda tidak menyertakan update pada dependensi, termasuk perbaikan keamanan, perbaikan bug, atau peningkatan.

Anda dapat memitigasi masalah ini menggunakan alat pengelolaan dependensi otomatis yang memantau dependensi di repositori sumber untuk rilis baru. Alat ini memperbarui file persyaratan Anda untuk mengupgrade dependensi sesuai kebutuhan, sering kali menyertakan informasi log perubahan atau detail tambahan.

Penyematan versi hanya berlaku untuk dependensi langsung, bukan dependensi transitif. Misalnya, jika Anda menyematkan versi paket my-library, pin tersebut akan membatasi versi my-library, tetapi tidak membatasi versi software yang memiliki dependensi oleh my-library. Anda dapat membatasi hierarki dependensi untuk paket dalam beberapa bahasa menggunakan file kunci.

Verifikasi tanda tangan dan hash

Ada sejumlah metode yang dapat Anda gunakan untuk memverifikasi keaslian artefak yang Anda gunakan sebagai dependensi.

Verifikasi hash

Hash adalah nilai yang dihasilkan untuk file yang bertindak sebagai ID unik. Anda dapat membandingkan hash artefak dengan nilai hash yang dihitung oleh penyedia artefak untuk mengonfirmasi integritas file. Verifikasi hash membantu Anda mengidentifikasi penggantian, modifikasi, atau kerusakan dependensi, melalui serangan man-in-the-middle atau penyusupan repositori artefak.

Penggunaan verifikasi hash memerlukan keyakinan bahwa hash yang Anda terima dari repositori artefak tidak disusupi.

Verifikasi tanda tangan

Verifikasi tanda tangan memberikan keamanan tambahan pada proses verifikasi. Repositori artefak, pengelola software, atau keduanya dapat menandatangani artefak.

Layanan seperti sigstore menyediakan cara bagi pengelola untuk menandatangani artefak software dan bagi konsumen untuk memverifikasi tanda tangan tersebut.

Otorisasi Biner dapat memverifikasi bahwa image container yang di-deploy ke lingkungan runtime Google Cloud ditandatangani dengan pengesahan untuk berbagai kriteria.

File kunci dan dependensi yang dikompilasi

File kunci adalah file persyaratan yang telah diselesaikan sepenuhnya, yang menentukan secara tepat versi dari setiap dependensi yang harus diinstal untuk aplikasi. Biasanya dihasilkan secara otomatis oleh alat penginstalan, file kunci menggabungkan penentuan versi dan verifikasi tanda tangan atau hash dengan hierarki dependensi penuh untuk aplikasi Anda.

Alat penginstalan membuat hierarki dependensi dengan sepenuhnya menyelesaikan semua dependensi transitif downstream dari dependensi level teratas Anda, lalu menyertakan hierarki dependensi dalam file kunci Anda. Akibatnya, hanya dependensi ini yang dapat diinstal, sehingga build lebih mudah direproduksi dan konsisten.

Mencampur dependensi pribadi dan publik

Aplikasi berbasis cloud modern sering kali bergantung pada open source, kode pihak ketiga, serta library internal open source. Dengan Artifact Registry, Anda dapat membagikan logika bisnis ke beberapa aplikasi, dan menggunakan kembali alat yang sama untuk menginstal library eksternal dan internal.

Namun, saat menggabungkan dependensi pribadi dan publik, supply chain software Anda lebih rentan terhadap serangan kebingungan dependensi. Dengan memublikasikan project dengan nama yang sama seperti project internal Anda ke repositori open source, penyerang mungkin dapat memanfaatkan penginstal yang salah dikonfigurasi untuk menginstal kode berbahaya, bukan dependensi internal Anda.

Untuk menghindari serangan kebingungan dependensi, Anda dapat melakukan sejumlah langkah:

  • Verifikasi tanda tangan atau hash dependensi Anda dengan menyertakannya dalam file kunci.
  • Pisahkan penginstalan dependensi pihak ketiga dan dependensi internal menjadi dua langkah yang berbeda.
  • Cerminkan dependensi pihak ketiga secara eksplisit yang Anda perlukan ke repositori pribadi Anda, baik secara manual maupun dengan proxy pull-through. Repositori jarak jauh Artifact Registry adalah proxy pull-through untuk repositori publik upstream.
  • Gunakan repositori virtual untuk menggabungkan repositori Artifact Registry jarak jauh dan standar di belakang satu endpoint. Anda dapat mengonfigurasi prioritas untuk repositori upstream sehingga versi artefak pribadi Anda akan selalu diprioritaskan daripada artefak publik dengan nama yang sama.
  • Gunakan sumber tepercaya untuk paket publik dan image dasar.

Menghapus dependensi yang tidak digunakan

Seiring dengan perubahan kebutuhan dan aplikasi Anda berkembang, Anda mungkin mengubah atau berhenti menggunakan beberapa dependensi. Terus menginstal dependensi yang tidak digunakan dengan aplikasi akan meningkatkan jejak dependensi dan meningkatkan risiko bagi Anda disusupi oleh kerentanan dalam dependensi tersebut.

Setelah aplikasi Anda bekerja secara lokal, praktik yang umum adalah menyalin setiap dependensi yang Anda instal selama proses pengembangan ke dalam file persyaratan untuk aplikasi Anda. Kemudian, deploy aplikasi dengan semua dependensi tersebut. Pendekatan ini membantu memastikan bahwa aplikasi yang di-deploy berfungsi, tetapi kemungkinan juga akan menimbulkan dependensi yang tidak Anda perlukan dalam produksi.

Hati-hati saat menambahkan dependensi baru ke aplikasi Anda. Masing-masing memiliki potensi untuk memperkenalkan lebih banyak kode yang tidak Anda miliki kontrol penuhnya. Sebagai bagian dari pipeline pengujian dan analisis lint reguler Anda, integrasikan alat yang mengaudit file persyaratan untuk menentukan apakah Anda benar-benar menggunakan atau mengimpor dependensi.

Beberapa bahasa memiliki alat untuk membantu Anda mengelola dependensi. Misalnya, Anda dapat menggunakan Plugin Maven Dependency untuk menganalisis dan mengelola dependensi Java.

Pemindaian kerentanan

Merespons kerentanan dengan cepat dalam dependensi akan membantu Anda melindungi supply chain software.

Pemindaian kerentanan memungkinkan Anda menilai secara otomatis dan konsisten apakah dependensi Anda memunculkan kerentanan pada aplikasi Anda atau tidak. Alat pemindaian kerentanan menggunakan file kunci untuk menentukan dengan tepat artefak yang Anda andalkan, dan memberi tahu Anda saat kerentanan baru muncul, bahkan terkadang dengan jalur upgrade yang disarankan.

Misalnya, Artifact Analysis mengidentifikasi kerentanan paket OS dalam image container. Fitur ini dapat memindai image saat diupload ke Artifact Registry dan terus memantaunya untuk menemukan kerentanan baru hingga 30 hari setelah mengirim image.

Anda juga dapat menggunakan Pemindaian On-Demand untuk memindai image container secara lokal guna mengetahui kerentanan OS, Go, dan Java. Dengan begitu, Anda dapat mengidentifikasi kerentanan lebih awal, sehingga Anda dapat mengatasinya sebelum menyimpannya di Artifact Registry.

Langkah selanjutnya