Aman skrip pengguna sandboxing dalam program C ++

8

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?

Vojislav Stojkovic
sumber
@RobertHarvey Teknik kemasukan Linux seperti Seccomp umumnya hanya membantu ketika menjalankan kode yang tidak dipercaya dalam proses terpisah, tetapi tidak berlaku untuk isolasi dalam proses. Tentu saja, solusi yang cukup sederhana untuk masalah tersebut dapat mencakup hal itu, proses terpisah yang bertindak sebagai layanan untuk program utama dan hanya berkomunikasi melalui mekanisme IPC. Saya ingin tahu apakah Windows memiliki fitur isolasi tingkat OS yang serupa?
amon
1
@amon: Maksud Anda seperti ... Proses Windows ? Tentu saja.
Robert Harvey
Pertama, Anda sudah memperkenalkan kerentanan terbesar ke dalam sistem Anda: Kode Asing . Segala sesuatu yang lain adalah upaya untuk mengurangi bahaya itu. Pada dasarnya Anda sedang membangun seorang penerjemah yang diharapkan mengeksekusi kode asing itu dengan aman. Pergi dan memoles pemahaman Anda tentang interpretasi kemudian menerapkan ide-ide itu untuk menegakkan perilaku dan keamanan relatif yang Anda inginkan. Kedua, jangan menganggap bahwa kotak pasir itu aman, selalu tambahkan lapisan pertahanan tambahan.
Kain0_0
1
@VojislavStojkovic Tidak bisakah Anda menggunakan mesin javascript? Secara default mesin ini tidak memiliki akses ke sistem file (tidak sepenuhnya yakin tentang jaringan tetapi Anda dapat memeriksa). Salah satu contoh adalah QJSEngine . Juga dengan mesin ini Anda dapat menyediakan fungsi kode c ++ khusus untuk javascript untuk interoperabilitas.
RandomGuy

Jawaban:

1

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.

lucasgcb
sumber
1
Jawaban yang bagus Jika ada sesuatu untuk ditambahkan ke jawaban Anda, mungkin semua solusi kotak pasir populer menunjukkan banyak kelemahan yang memungkinkan kode berbahaya keluar dari kotak pasirnya. Ini berlaku untuk CAS (misalnya CVE-2015-2504), dan bahkan lebih benar untuk Java (exploit untuk plugin Java browser terlalu banyak untuk disebutkan di sini). Sementara Docker memang memiliki kerentanan juga, saya memiliki kesan bahwa permukaan serangan jauh lebih rendah dibandingkan dengan apa pun yang diterapkan pada tingkat bahasa / kerangka kerja yang diberikan.
Arseni Mourzenko