Keamanan dan arsitektur pemuat kelas

Sebelumnya 1 2 Halaman 2 Halaman 2 dari 2

Pemuat kelas dan ruang nama

Untuk setiap kelas yang dimuatnya, JVM melacak pemuat kelas mana - apakah primordial atau objek - yang memuat kelas. Saat kelas yang dimuat pertama kali merujuk ke kelas lain, mesin virtual meminta kelas yang dirujuk dari loader kelas yang sama yang awalnya memuat kelas referensi. Misalnya, jika mesin virtual memuat kelas Volcanomelalui pemuat kelas tertentu, ia akan mencoba memuat semua kelas yang Volcanodirujuk melalui pemuat kelas yang sama. Jika Volcanomerujuk ke kelas bernama Lava, mungkin dengan memanggil metode di kelas Lava, mesin virtual akan meminta Lavadari kelas loader yang dimuat Volcano. The Lavakelas dikembalikan oleh loader kelas secara dinamis terkait dengan kelas Volcano.

Karena JVM mengambil pendekatan ini untuk memuat kelas, kelas secara default hanya dapat melihat kelas lain yang dimuat oleh pemuat kelas yang sama. Dengan cara ini, arsitektur Java memungkinkan Anda membuat beberapa ruang nama di dalam satu aplikasi Java. Ruang nama adalah sekumpulan nama unik dari kelas yang dimuat oleh pemuat kelas tertentu. Untuk setiap pemuat kelas, JVM mempertahankan ruang nama, yang diisi oleh nama semua kelas yang telah dimuat melalui pemuat kelas tersebut.

Setelah JVM memuat kelas yang diberi nama Volcanoke dalam ruang nama tertentu, misalnya, tidak mungkin untuk memuat kelas lain yang diberi nama Volcanoke dalam ruang nama yang sama. Anda dapat memuat banyak Volcanokelas ke dalam JVM, karena Anda dapat membuat beberapa ruang nama di dalam aplikasi Java. Anda dapat melakukannya hanya dengan membuat beberapa pemuat kelas. Jika Anda membuat tiga ruang nama terpisah (satu untuk masing-masing dari tiga pemuat kelas) dalam aplikasi Java yang sedang berjalan, maka, dengan memuat satu Volcanokelas ke dalam setiap ruang nama, program Anda dapat memuat tiga Volcanokelas yang berbeda ke dalam aplikasi Anda.

Aplikasi Java dapat membuat instance beberapa objek loader kelas baik dari kelas yang sama atau dari beberapa kelas. Oleh karena itu, ia dapat membuat objek loader kelas sebanyak (dan sebanyak mungkin jenis yang berbeda) sesuai kebutuhan. Kelas yang dimuat oleh pemuat kelas yang berbeda berada dalam ruang nama yang berbeda dan tidak dapat memperoleh akses satu sama lain kecuali jika aplikasi secara eksplisit mengizinkannya. Saat Anda menulis aplikasi Java, Anda dapat memisahkan kelas yang dimuat dari sumber yang berbeda ke dalam ruang nama yang berbeda. Dengan cara ini, Anda dapat menggunakan arsitektur pemuat kelas Java untuk mengontrol interaksi apa pun antara kode yang dimuat dari sumber yang berbeda. Anda dapat mencegah kode yang tidak bersahabat untuk mendapatkan akses dan menumbangkan kode yang bersahabat.

Pemuat kelas untuk applet

Salah satu contoh ekstensi dinamis dengan pemuat kelas adalah browser Web, yang menggunakan objek pemuat kelas untuk mengunduh file kelas untuk applet di seluruh jaringan. Browser Web menjalankan aplikasi Java yang menginstal objek pemuat kelas - biasanya disebut pemuat kelas applet - yang tahu cara meminta file kelas dari server HTTP. Applet adalah contoh dari ekstensi dinamis, karena ketika aplikasi Java dimulai, ia tidak tahu file kelas mana yang akan diminta oleh browser untuk diunduh di seluruh jaringan. File kelas yang akan diunduh ditentukan pada waktu proses, karena browser menemukan halaman yang berisi applet Java.

Aplikasi Java yang dimulai oleh browser Web biasanya membuat objek loader kelas applet yang berbeda untuk setiap lokasi di jaringan tempat file kelas diambil. Akibatnya, file kelas dari sumber berbeda dimuat oleh objek loader kelas yang berbeda. Ini menempatkannya ke dalam ruang nama yang berbeda di dalam aplikasi Java host. Karena file kelas untuk applet dari sumber yang berbeda ditempatkan di ruang nama yang terpisah, kode dari applet berbahaya dibatasi dari gangguan langsung dengan file kelas yang diunduh dari sumber lain.

Kerja sama antar pemuat kelas

Seringkali, objek pemuat kelas bergantung pada pemuat kelas lain - paling tidak, pada pemuat kelas primordial - untuk membantunya memenuhi beberapa permintaan pemuatan kelas yang datang. Misalnya, bayangkan Anda menulis aplikasi Java yang menginstal pemuat kelas yang cara tertentu memuat file kelas dicapai dengan mendownloadnya melalui jaringan. Asumsikan bahwa selama menjalankan aplikasi Java, permintaan dibuat dari loader kelas Anda untuk memuat kelas bernama Volcano.

Salah satu cara Anda dapat menulis pemuat kelas adalah dengan meminta dahulu pemuat kelas primordial untuk mencari dan memuat kelas dari repositori tepercaya. Dalam kasus ini, karena Volcanobukan merupakan bagian dari Java API, asumsikan loader kelas primordial tidak dapat menemukan kelas bernama Volcano. Jika pemuat kelas primordial merespons bahwa ia tidak dapat memuat kelas, pemuat kelas Anda kemudian dapat mencoba memuat Volcanokelas dengan cara kustomnya, dengan mendownloadnya melalui jaringan. Dengan asumsi class loader Anda dapat mendownload class Volcano, Volcanoclass tersebut kemudian dapat berperan dalam proses eksekusi aplikasi di masa mendatang.

Untuk melanjutkan dengan contoh yang sama, asumsikan bahwa beberapa waktu kemudian metode kelas Volcanodipanggil untuk pertama kalinya, dan metode tersebut mereferensikan kelas Stringdari Java API. Karena ini adalah pertama kalinya referensi digunakan oleh program yang sedang berjalan, mesin virtual meminta pemuat kelas Anda (yang dimuat Volcano) untuk dimuat String. Seperti sebelumnya, pemuat kelas Anda terlebih dahulu meneruskan permintaan ke pemuat kelas primordial, tetapi dalam kasus ini, pemuat kelas primordial dapat mengembalikan sebuah Stringkelas ke pemuat kelas Anda.

Loader kelas primordial kemungkinan besar tidak harus benar-benar memuat Stringpada saat ini karena, mengingat itu Stringadalah kelas fundamental dalam program Java, hampir pasti digunakan sebelumnya dan oleh karena itu sudah dimuat. Kemungkinan besar, pemuat kelas primordial baru saja mengembalikan Stringkelas yang sebelumnya dimuat dari repositori tepercaya.

Karena pemuat kelas primordial dapat menemukan kelas tersebut, pemuat kelas Anda tidak berusaha untuk mengunduhnya melalui jaringan; itu hanya meneruskan ke mesin virtual Stringkelas yang dikembalikan oleh loader kelas primordial. Sejak saat itu, mesin virtual menggunakan Stringkelas itu setiap kali kelas Volcanomereferensikan kelas bernama String.

Pemuat kelas di kotak pasir

Di kotak pasir Java, arsitektur pemuat kelas adalah garis pertahanan pertama terhadap kode berbahaya. Ini adalah pemuat kelas, bagaimanapun, yang membawa kode ke JVM - kode yang bisa jadi bermusuhan.

Arsitektur pemuat kelas berkontribusi pada kotak pasir Java dalam dua cara:

  1. Ini mencegah kode berbahaya dari mengganggu kode baik hati.
  2. Itu menjaga perbatasan perpustakaan kelas tepercaya.

Arsitektur pemuat kelas menjaga batas pustaka kelas tepercaya dengan memastikan bahwa kelas yang tidak tepercaya tidak dapat berpura-pura dipercaya. Jika kelas berbahaya berhasil mengelabui JVM agar percaya bahwa itu adalah kelas tepercaya dari Java API, kelas berbahaya tersebut berpotensi dapat menembus penghalang kotak pasir. Dengan mencegah kelas tidak tepercaya meniru kelas tepercaya, arsitektur loader kelas memblokir satu pendekatan potensial untuk membahayakan keamanan runtime Java.

Ruang nama dan perisai

Arsitektur pemuat kelas mencegah kode berbahaya mengganggu kode baik dengan menyediakan ruang nama yang dilindungi untuk kelas yang dimuat oleh pemuat kelas yang berbeda. Seperti disebutkan di atas, name-space adalah sekumpulan nama unik untuk kelas yang dimuat yang dikelola oleh JVM.

Ruang nama berkontribusi pada keamanan karena Anda dapat, pada dasarnya, menempatkan perisai antar kelas yang dimuat ke dalam ruang nama yang berbeda. Di dalam JVM, kelas dalam ruang nama yang sama dapat berinteraksi satu sama lain secara langsung. Kelas dalam ruang nama yang berbeda, bagaimanapun, bahkan tidak dapat mendeteksi keberadaan satu sama lain kecuali Anda secara eksplisit menyediakan mekanisme yang memungkinkan kelas untuk berinteraksi. Jika kelas berbahaya, setelah dimuat, telah menjamin akses ke setiap kelas lain yang saat ini dimuat oleh mesin virtual, kelas tersebut berpotensi dapat mempelajari hal-hal yang seharusnya tidak diketahui, atau dapat mengganggu pelaksanaan program Anda dengan benar.

Menciptakan lingkungan yang aman

Saat Anda menulis aplikasi yang menggunakan pemuat kelas, Anda membuat lingkungan tempat kode yang dimuat secara dinamis berjalan. Jika Anda ingin lingkungan bebas dari lubang keamanan, Anda harus mengikuti aturan tertentu saat menulis aplikasi dan pemuat kelas. Secara umum, Anda mungkin ingin menulis aplikasi Anda sehingga kode berbahaya akan terlindung dari kode yang baik. Selain itu, Anda mungkin ingin menulis pemuat kelas sedemikian rupa sehingga mereka melindungi perbatasan pustaka kelas tepercaya, seperti yang ada di Java API.

Spasi nama dan sumber kode

Untuk mendapatkan manfaat keamanan yang ditawarkan oleh ruang nama, Anda perlu memastikan bahwa Anda memuat kelas dari sumber yang berbeda melalui pemuat kelas yang berbeda. Ini adalah skema, dijelaskan di atas, digunakan oleh browser Web yang mendukung Java. Aplikasi Java yang dijalankan oleh browser Web biasanya membuat objek loader kelas applet yang berbeda untuk setiap sumber kelas yang diunduh di seluruh jaringan. Misalnya, browser akan menggunakan satu objek loader kelas untuk mengunduh kelas dari //www.niceapplets.com, dan objek loader kelas lain untuk mengunduh kelas dari //www.meanapplets.com.

Menjaga paket terbatas

Java mengizinkan kelas dalam paket yang sama untuk saling memberikan hak akses khusus yang tidak diberikan ke kelas di luar paket. Jadi, jika pemuat kelas Anda menerima permintaan untuk memuat sebuah kelas yang dengan namanya dengan berani mendeklarasikan dirinya sebagai bagian dari Java API (misalnya, sebuah kelas bernama java.lang.Virus), pemuat kelas Anda harus melanjutkan dengan hati-hati. Jika dimuat, kelas semacam itu dapat memperoleh akses khusus ke kelas tepercaya java.langdan mungkin dapat menggunakan akses khusus itu untuk tujuan yang licik.

Akibatnya, Anda biasanya akan menulis pemuat kelas sehingga pemuat kelas tersebut menolak untuk memuat setiap kelas yang mengklaim sebagai bagian dari Java API (atau pustaka waktu proses tepercaya lainnya) tetapi tidak ada di repositori tepercaya lokal. Dengan kata lain, setelah pemuat kelas Anda meneruskan permintaan ke pemuat kelas primordial, dan pemuat kelas primordial menunjukkan bahwa ia tidak dapat memuat kelas, pemuat kelas Anda harus memeriksa untuk memastikan bahwa kelas tidak mendeklarasikan dirinya sebagai anggota. dari paket tepercaya. Jika ya, pemuat kelas Anda, alih-alih mencoba mengunduh kelas di seluruh jaringan, harus melontarkan pengecualian keamanan.

Menjaga paket terlarang

Selain itu, Anda mungkin telah menginstal beberapa paket di repositori tepercaya yang berisi kelas yang Anda inginkan agar dapat dimuat aplikasi Anda melalui pemuat kelas primordial, tetapi Anda tidak ingin dapat diakses ke kelas yang dimuat melalui pemuat kelas Anda. Misalnya, asumsikan Anda telah membuat sebuah paket bernama absolutepowerdan menginstalnya di repositori lokal yang dapat diakses oleh pemuat kelas primordial. Asumsikan juga bahwa Anda tidak ingin class dimuat oleh class loader Anda untuk dapat memuat class apa pun dari absolutepowerpaket. Dalam kasus ini, Anda akan menulis loader kelas Anda sedemikian rupa sehingga hal pertama yang dilakukannya adalah memastikan kelas yang diminta tidak mendeklarasikan dirinya sebagai anggotaabsolutepowerpaket. Jika kelas seperti itu diminta, pemuat kelas Anda, daripada meneruskan nama kelas ke pemuat kelas primordial, harus melontarkan pengecualian keamanan.

Satu-satunya cara agar class loader dapat mengetahui apakah suatu class berasal dari paket terbatas, seperti java.lang, atau paket terlarang, seperti absolutepower, adalah dengan nama class. Dengan demikian, class loader harus diberi daftar nama paket yang dibatasi dan yang dilarang. Karena nama kelas java.lang.Virusmenunjukkan itu dari java.langpaket, dan java.langada di daftar paket terbatas, pemuat kelas Anda harus menampilkan pengecualian keamanan jika pemuat kelas primordial tidak dapat memuatnya. Demikian juga, karena nama kelas absolutepower.FancyClassLoadermenunjukkan bahwa itu adalah bagian dari absolutepowerpaket, dan absolutepowerpaket tersebut ada di daftar paket terlarang, pemuat kelas Anda harus menampilkan pengecualian keamanan.

Pemuat kelas yang berpikiran keamanan

Cara umum untuk menulis pemuat kelas yang berpikiran keamanan adalah dengan menggunakan empat langkah berikut:

  1. Jika ada paket yang tidak diizinkan memuat pemuat kelas ini, pemuat kelas akan memeriksa apakah kelas yang diminta termasuk dalam salah satu paket terlarang yang disebutkan di atas. Jika demikian, itu melontarkan pengecualian keamanan. Jika tidak, lanjutkan ke langkah kedua.

  2. Pemuat kelas meneruskan permintaan ke pemuat kelas primordial. Jika pemuat kelas primordial berhasil mengembalikan kelas tersebut, pemuat kelas akan mengembalikan kelas yang sama. Jika tidak, ini berlanjut ke langkah ketiga.

  3. Jika ada paket tepercaya yang tidak diizinkan untuk menambahkan kelas pemuat kelas ini, pemuat kelas akan memeriksa apakah kelas yang diminta ada dalam salah satu paket terbatas tersebut. Jika demikian, itu melontarkan pengecualian keamanan. Jika tidak, lanjutkan ke langkah keempat.

  4. Terakhir, pemuat kelas mencoba memuat kelas dengan cara kustom, seperti dengan mendownloadnya melalui jaringan. Jika berhasil, itu mengembalikan kelas. Jika tidak berhasil, kesalahan "tidak ditemukan definisi kelas".

Dengan melakukan langkah satu dan tiga seperti yang dijelaskan di atas, class loader menjaga batas dari paket tepercaya. Dengan langkah pertama, ini mencegah kelas dari paket terlarang dimuat sama sekali. Dengan langkah ketiga, itu tidak mengizinkan kelas tak tepercaya untuk memasukkan dirinya ke dalam paket tepercaya.

Kesimpulan

Arsitektur class loader berkontribusi pada model keamanan JVM dalam dua cara:

  1. dengan memisahkan kode menjadi beberapa ruang nama dan menempatkan "pelindung" di antara kode dalam ruang nama yang berbeda
  2. dengan menjaga batas perpustakaan kelas tepercaya, seperti Java API

Kedua kemampuan arsitektur pemuat kelas Java ini harus digunakan dengan benar oleh pemrogram untuk mendapatkan keuntungan keamanan yang mereka tawarkan. Untuk memanfaatkan perisai ruang nama, kode dari sumber yang berbeda harus dimuat melalui objek pemuat kelas yang berbeda. Untuk memanfaatkan perlindungan perbatasan paket tepercaya, pemuat kelas harus ditulis sehingga mereka memeriksa nama kelas yang diminta terhadap daftar paket yang dibatasi dan dilarang.

Untuk panduan proses penulisan pemuat kelas, termasuk kode contoh, lihat artikel JavaWorld Chuck McManis , "Dasar-dasar pemuat kelas Java."

Bulan depan

Di artikel bulan depan, saya akan melanjutkan pembahasan model keamanan JVM dengan menjelaskan verifikator kelas.

Bill Venners telah menulis perangkat lunak secara profesional selama 12 tahun. Berbasis di Silicon Valley, dia menyediakan layanan konsultasi dan pelatihan perangkat lunak dengan nama Artima Software Company. Selama bertahun-tahun ia telah mengembangkan perangkat lunak untuk elektronik konsumen, pendidikan, semikonduktor, dan industri asuransi jiwa. Dia telah memprogram dalam banyak bahasa di banyak platform: bahasa assembly di berbagai mikroprosesor, C di Unix, C ++ di Windows, Java di Web. Dia adalah penulis buku: Inside the Java Virtual Machine, diterbitkan oleh McGraw-Hill.

Pelajari lebih lanjut tentang topik ini

  • Buku The Java virtual machine Specification (//www.aw.com/cp/lindholm-yellin.html), oleh Tim Lindholm dan Frank Yellin (ISBN 0-201-63452-X), bagian dari The Java Series (// www.aw.com/cp/javaseries.html), dari Addison-Wesley, adalah referensi mesin virtual Java yang pasti.
  • Komputasi Aman dengan JavaNow and the Future (whitepaper) // www.javasoft.com/marketing/collateral/security.html
  • FAQ Keamanan Applet

    //www.javasoft.com/sfaq/

  • Keamanan Tingkat Rendah di Java, oleh Frank Yellin //www.javasoft.com/sfaq/verifier.html
  • Halaman Beranda Keamanan Java

    //www.javasoft.com/security/

  • Lihat Halaman Beranda Hostile Applet

    //www.math.gatech.edu/~mladue/HostileApplets.html

  • Buku Java SecurityHostile Applets, Holes, and Antidotes, oleh Dr. Gary McGraw dan Ed Felton, memberikan analisis menyeluruh tentang masalah keamanan di sekitar Jawa. //www.rstcorp.com/java-security.html
  • Artikel "Di Balik Terpal" sebelumnya:
  • The Lean, Mean Virtual Machine - Memberikan pengantar tentang mesin virtual Java.
  • Gaya Hidup File Kelas Java - Memberikan gambaran umum tentang file kelas Java, format file tempat semua program Java dikompilasi.
  • Java's Garbage- Collected Heap - Memberikan gambaran umum tentang pengumpulan sampah secara umum dan heap yang dikumpulkan dari mesin virtual Java pada khususnya.
  • Dasar-dasar Bytecode - Memperkenalkan bytecode mesin virtual Java, dan secara khusus membahas tipe primitif, operasi konversi, dan operasi stack.
  • Floating Point Arithmetic - Menjelaskan dukungan floating-point mesin virtual Java dan bytecode yang melakukan operasi floating-point.
  • Logika dan Aritmatika - Menjelaskan dukungan mesin virtual Java untuk aritmatika logis dan integer, dan bytecode terkait.
  • Objek dan Array - Menjelaskan cara mesin virtual Java menangani objek dan array, dan membahas bytecode yang relevan.
  • Pengecualian - Menjelaskan bagaimana mesin virtual Java menangani pengecualian, dan membahas bytecode yang relevan.
  • Try-Akhirnya - Menjelaskan bagaimana mesin virtual Java mengimplementasikan klausa coba-akhirnya, dan membahas bytecode yang relevan.
  • Alur Kontrol - Menjelaskan bagaimana mesin virtual Java mengimplementasikan aliran kontrol dan membahas bytecode yang relevan.
  • The Architecture of Aglets - Menjelaskan cara kerja aglets, teknologi agen perangkat lunak berbasis Java yang otonom dari IBM.
  • The Point of Aglets - Menganalisis utilitas dunia nyata dari agen seluler seperti aglets, teknologi agen perangkat lunak berbasis Java yang otonom dari IBM.
  • Method Invocation and Return - Menjelaskan empat cara mesin virtual Java memanggil metode, termasuk bytecode yang relevan.
  • Sinkronisasi Utas - Menunjukkan cara kerja sinkronisasi utas di mesin virtual Java. Membahas bytecode untuk masuk dan keluar monitor.
  • Arsitektur Keamanan Java - Memberikan gambaran umum tentang model keamanan yang dibangun ke dalam JVM dan melihat fitur keamanan bawaan JVM.

Artikel ini, "Keamanan dan arsitektur pemuat kelas", awalnya diterbitkan oleh JavaWorld.