Saya telah mengerjakan proyek pribadi dalam C # yang tujuannya kurang lebih memungkinkan pengguna untuk mengeksekusi skrip yang ditulis oleh pengguna lain dan membatasi izin skrip itu. Program saya mengkompilasi skrip menggunakan perpustakaan pihak ketiga, kotak pasir mereka menggunakan mekanisme Keamanan Akses Kode NET. Dan memastikan bahwa mereka hanya memiliki izin yang ingin diberikan pengguna.
Secara umum, persyaratan keamanan saya adalah:
- pengguna harus dapat membatasi akses skrip yang tidak dipercaya hanya ke bagian-bagian tertentu dari sistem file, termasuk melarang semua akses sistem file
- pengguna harus dapat membatasi koneksi jaringan skrip yang tidak dipercaya hanya untuk alamat IP atau nama host tertentu, termasuk melarang semua koneksi jaringan
- tidak apa-apa jika skrip pengguna berhasil menggantung atau menghentikan aplikasi host, tetapi skrip pengguna tidak dapat menghindari batasan izin (mis. penolakan layanan tidak apa-apa, pelanggaran tidak)
Saya ingin mencoba melakukan sesuatu yang serupa di C ++, sebagai semacam latihan pribadi. Jelas, hal-hal lebih rumit ketika menjalankan kode asli secara langsung, bahkan jika skrip pengguna ditulis dalam bahasa skrip seperti Lua.
Pendekatan pertama yang bisa saya pikirkan adalah untuk memasukkan kait saya sendiri di lingkungan perpustakaan standar fungsi scripting. Misalnya, jika bahasa skrip Lua, alih-alih mengekspos io.open secara normal, saya harus mengekspos pembungkus yang memeriksa argumen terhadap izin skrip sebelum meneruskannya ke implementasi asli.
Kekhawatiran saya dengan pendekatan ini adalah bahwa secara drastis meningkatkan jumlah kode saya sendiri yang bertanggung jawab atas keamanan dan, oleh karena itu, potensi kerentanan keamanan yang saya tulis sendiri. Dengan kata lain, ketika bekerja dengan .NET CAS, saya dapat percaya bahwa Microsoft melakukan tugasnya dengan baik dalam kode sandboxing, sebagai lawan harus mempercayai kode sandboxing saya sendiri.
Apakah ada alternatif yang tidak saya sadari?
Jawaban:
Seperti yang telah dinyatakan orang lain, menjalankan kode asing adalah masalah terbesar terkait implementasi semacam ini. Seperti komentar Kain0_0 yang disarankan, VM akan menjadi cara yang paling tepat untuk mempertahankan kebebasan kode asing tanpa membahayakan mesin host (terlalu banyak). Ini pada dasarnya apa yang dilakukan layanan Integrasi Berkelanjutan seperti CircleCI.
Ini juga membuatnya lebih mudah untuk mengimplementasikan antarmuka karena Anda dapat menarik gambar dengan semua fitur konfigurasi dan keamanan yang Anda inginkan. Anda juga tidak perlu khawatir jika kode mereka akan berjalan di host Anda.
Jadi untuk ini, saya akan:
Membuat snapshot dari lingkungan skrip pengguna yang ingin saya bahas dengan Docker (satu lingkungan untuk C #, satu untuk Python, dll, dengan konfigurasi keamanan yang sesuai)
Atas permintaan pengguna, putar instance Docker yang relevan melalui pemicu kode, menyuntikkan skrip asing di entri entry instance Docker.
Kode dijalankan dalam contoh Docker dengan izin pengguna, file ditulis, mungkin koneksi dibuat di sana-sini, dapatkan output dan lingkungan kemudian dihancurkan
Karena wadah Docker dijalankan sebagai proses, mereka dapat diakhiri dengan cukup mudah yaitu jika mereka melebihi batas waktu tertentu. Jika ada kesalahan, mereka dapat segera diakhiri.
Pada dasarnya, minta kode utama Anda mengelola pemicu pengguna, injeksi titik masuk, dan logika penghancuran otomatis untuk Docker, yang bertugas melakukan sandboxing untuk operasi semacam ini.
sumber