Pertimbangan Keamanan untuk Refleksi

Refleksi menyediakan kemampuan untuk memperoleh informasi tentang jenis dan anggota, serta untuk mengakses anggota (yaitu, untuk memanggil metode dan konstruktor, untuk mendapatkan dan menetapkan nilai properti, untuk menambah dan menghapus penangan aktivitas, dan seterusnya). Penggunaan refleksi untuk memperoleh informasi tentang jenis dan anggota tidak dibatasi. Semua kode dapat menggunakan refleksi untuk melakukan tugas-tugas berikut:

  • Menghitung jenis dan anggota, dan memeriksa metadata mereka.
  • Menghitung serta memeriksa rakitan dan modul.

Menggunakan refleksi untuk mengakses anggota, sebaliknya, tunduk pada pembatasan. Mulai dari .NET Framework 4, hanya kode tepercaya yang dapat menggunakan refleksi untuk mengakses anggota yang penting bagi keamanan. Selain itu, hanya kode tepercaya yang dapat menggunakan refleksi untuk mengakses anggota nonpublik yang tidak dapat diakses secara langsung oleh kode yang dikompilasi. Terakhir, kode yang menggunakan refleksi untuk mengakses anggota kritis aman harus memiliki izin apa pun yang diminta anggota kritis aman, seperti halnya kode yang dikompilasi.

Tunduk pada izin yang diperlukan, kode dapat menggunakan refleksi untuk melakukan jenis akses berikut:

  • Akses anggota publik yang tidak penting bagi keamanan.

  • Akses anggota nonpublik yang dapat diakses oleh kode yang dikompilasi, jika anggota tersebut tidak penting bagi keamanan. Contoh anggota nonpublik tersebut meliputi:

    • Anggota kelas dasar kode panggilan yang dilindungi. (Sebagai refleksi, ini disebut sebagai akses tingkat keluarga.)

    • internal anggota (Friend anggota dalam Visual Basic) dalam perakitan kode panggilan. (Dalam refleksi, ini disebut sebagai akses tingkat perakitan.)

    • Anggota pribadi dari instans kelas lain yang berisi kode panggilan.

Misalnya, kode yang dijalankan di domain aplikasi kotak pasir terbatas pada akses yang dijelaskan dalam daftar ini, kecuali domain aplikasi memberikan izin tambahan.

Mulai dari .NET Framework 2.0 Service Pack 1, mencoba mengakses anggota yang biasanya tidak dapat diakses menghasilkan permintaan untuk set pemberian objek target ditambah ReflectionPermission dengan tanda ReflectionPermissionFlag.MemberAccess. Kode yang berjalan dengan kepercayaan penuh (misalnya, kode dalam aplikasi yang diluncurkan dari baris perintah) selalu dapat memenuhi izin ini. (Kode ini tunduk pada batasan dalam mengakses anggota yang penting bagi keamanan, seperti yang dijelaskan nanti dalam artikel ini.)

Opsional, domain aplikasi kotak pasir dapat memberikan ReflectionPermission dengan bendera ReflectionPermissionFlag.MemberAccess, seperti yang dijelaskan di bagian Mengakses Anggota yang Biasanya Tidak Dapat Diakses, nanti di artikel ini.

Mengakses Anggota yang Penting Bagi Keamanan

Seorang anggota dikatakan penting bagi keamanan jika memiliki SecurityCriticalAttribute, jika termasuk dalam jenis yang memiliki SecurityCriticalAttribute, atau jika berada dalam perakitan yang penting bagi keamanan. Mulai dari .NET Framework 4, aturan untuk mengakses anggota yang penting bagi keamanan adalah sebagai berikut:

  • Kode transparan tidak dapat menggunakan refleksi untuk mengakses anggota yang penting bagi keamanan, bahkan jika kode tersebut sepenuhnya dipercaya. MethodAccessException, FieldAccessException, atau TypeAccessException ditampilkan.

  • Kode yang berjalan dengan kepercayaan parsial diperlakukan sebagai transparan.

Aturan-aturan ini sama, apakah anggota yang penting bagi keamanan diakses secara langsung dengan kode yang dikompilasi, atau diakses dengan menggunakan refleksi.

Kode aplikasi yang dijalankan dari baris perintah berjalan dengan penuh kepercayaan. Selama tidak ditandai sebagai transparan, kode dapat menggunakan refleksi untuk mengakses anggota yang penting bagi keamanan. Ketika kode yang sama dijalankan dengan kepercayaan parsial (misalnya, dalam domain aplikasi kotak pasir) tingkat kepercayaan perakitan menentukan apakah dapat mengakses kode yang penting bagi keamanan: Jika rakitan memiliki nama yang kuat dan diinstal di cache rakitan global, itu adalah majelis tepercaya dan dapat memanggil anggota yang penting bagi keamanan. Jika tidak dipercaya, kode akan menjadi transparan meskipun tidak ditandai sebagai transparan, dan tidak dapat mengakses anggota yang penting bagi keamanan.

Refleksi dan Transparansi

Mulai dari .NET Framework 4, runtime bahasa umum menentukan tingkat transparansi jenis atau anggota dari beberapa faktor, termasuk tingkat kepercayaan rakitan dan tingkat kepercayaan domain aplikasi. Refleksi menyediakan properti IsSecurityCritical, IsSecuritySafeCritical, dan IsSecurityTransparent guna memungkinkan Anda menemukan tingkat transparansi suatu jenis. Tabel berikut menunjukkan kombinasi yang valid dari properti ini.

Tingkat keamanan IsSecurityCritical IsSecuritySafeCritical IsSecurityTransparent
Kritis true false false
Sangat aman true true false
Transparan false false true

Menggunakan properti ini jauh lebih sederhana daripada memeriksa anotasi keamanan rakitan dan jenisnya, memeriksa tingkat kepercayaan saat ini, dan mencoba menduplikasi aturan runtime. Misalnya, jenis yang sama dapat menjadi penting bagi keamanan saat dijalankan dari baris perintah, atau transparan terhadap keamanan saat dijalankan di domain aplikasi kotak pasir.

Ada properti serupa di kelas MethodBase, FieldInfo, TypeBuilder, MethodBuilder, dan DynamicMethod. (Untuk refleksi dan refleksi memancarkan abstraksi lainnya, atribut keamanan diterapkan ke metode terkait; misalnya, dalam kasus properti mereka diterapkan ke pengakses properti.)

Mengakses Anggota yang Biasanya Tidak Dapat Diakses

Untuk menggunakan refleksi guna memanggil anggota yang tidak dapat diakses menurut aturan aksesibilitas runtime bahasa umum, kode Anda harus diberikan salah satu dari dua izin:

  • Untuk mengizinkan kode memanggil anggota nonpublik: Kode Anda harus diberikan ReflectionPermission dengan bendera ReflectionPermissionFlag.MemberAccess.

    Catatan

    Secara default, kebijakan keamanan menolak izin ini untuk kode yang berasal dari Internet. Izin ini tidak boleh diberikan kepada kode yang berasal dari Internet.

  • Untuk mengizinkan kode memanggil anggota nonpublik mana pun, selama kumpulan hibah majelis yang berisi anggota yang dipanggil sama dengan, atau subset dari, kumpulan hibah majelis yang berisi kode pemanggilan: Kode Anda harus diberikan ReflectionPermission dengan bendera ReflectionPermissionFlag.RestrictedMemberAccess.

Misalnya, Anda memberikan izin Internet domain aplikasi plus ReflectionPermission dengan bendera ReflectionPermissionFlag.RestrictedMemberAccess, lalu menjalankan aplikasi Internet dengan dua rakitan, A dan B.

  • Majelis A dapat menggunakan refleksi untuk mengakses anggota pribadi Majelis B, karena himpunan hibah Majelis B tidak menyertakan izin apa pun yang belum diberikan oleh A.

  • Majelis A tidak dapat menggunakan refleksi untuk mengakses anggota pribadi rakitan .NET Framework seperti mscorlib.dll, karena mscorlib.dll sepenuhnya dipercaya dan oleh karena itu memiliki izin yang belum diberikan kepada Majelis A. A MemberAccessException dilemparkan saat keamanan akses kode berjalan di stack pada saat run time.

Serialisasi

Untuk serialisasi, SecurityPermission dengan tanda SecurityPermissionAttribute.SerializationFormatter memberikan kemampuan untuk mendapatkan dan mengatur anggota dari jenis yang dapat diserialisasikan, terlepas dari aksesibilitasnya. Izin ini memungkinkan kode untuk menemukan dan mengubah status pribadi sebuah instance. (Selain diberikan izin yang sesuai, jenisnya harus ditandai sebagai serial dalam metadata.)

Parameter Jenis MetodeInfo

Hindari menulis anggota publik yang menggunakan parameter MethodInfo, terutama untuk kode tepercaya. Anggota tersebut mungkin lebih rentan terhadap kode berbahaya. Misalnya, pertimbangkan anggota publik dalam kode yang sangat tepercaya yang menggunakan parameter MethodInfo. Asumsikan bahwa anggota publik secara tidak langsung memanggil metode Invoke pada parameter yang disediakan. Jika anggota publik tidak melakukan pemeriksaan izin yang diperlukan, panggilan ke metode Invoke akan selalu berhasil, karena sistem keamanan menentukan bahwa penelepon sangat tepercaya. Bahkan jika kode berbahaya tidak memiliki izin untuk memanggil metode secara langsung, ia masih dapat melakukannya secara tidak langsung dengan memanggil anggota publik.

Informasi Versi

  • Mulai dari .NET Framework 4, kode transparan tidak dapat menggunakan refleksi untuk mengakses anggota yang penting bagi keamanan.

  • Bendera ReflectionPermissionFlag.RestrictedMemberAccess diperkenalkan di .NET Framework 2.0 Paket Layanan 1. Versi .NET Framework yang lebih lama memerlukan bendera ReflectionPermissionFlag.MemberAccess untuk kode yang menggunakan refleksi untuk mengakses anggota nonpublik. Ini adalah izin yang tidak boleh diberikan kepada kode yang dipercaya sebagian.

  • Dimulai dengan .NET Framework 2.0, menggunakan refleksi untuk mendapatkan informasi tentang jenis nonpublik dan anggota tidak memerlukan izin apa pun. Pada versi sebelumnya, ReflectionPermission dengan bendera ReflectionPermissionFlag.TypeInformation diperlukan.

Lihat juga