Sigurnost i arhitektura učitavača klasa

Prethodna 1 2 Stranica 2 Stranica 2 od 2

Učitavači razreda i razmaci s imenima

Za svaku klasu koju učita, JVM prati koji je učitavač klase - bez obzira je li izvorni ili objektni - učitao klasu. Kada se učitana klasa prvi put odnosi na drugu klasu, virtualni stroj zahtijeva referenciranu klasu od istog učitavača klase koji je izvorno učitao referentnu klasu. Na primjer, ako virtualni stroj učita klasu Volcanokroz učitavač određene klase, pokušat će učitati sve klase na koje se Volcanoodnosi putem istog učitavača klase. Ako se Volcanoodnosi na klasu pod nazivom Lava, možda pozivanjem metode u klasi Lava, virtualni stroj zatražit će Lavaod učitača klase koji se učitao Volcano. LavaKlasa vraća klase utovarivač dinamički povezan s klase Volcano.

Budući da JVM koristi ovaj pristup učitavanju klasa, klase prema zadanim postavkama mogu vidjeti samo druge klase koje je učitao isti učitavač klasa. Na taj način, Javina arhitektura omogućuje vam stvaranje više prostora imena unutar jedne Java aplikacije. Prostor imena je skup jedinstvenih imena klasa učitanih od strane određenog učitavača klasa. Za svaki učitavač klasa, JVM održava prostor imena koji se popunjava imenima svih klasa učitanih kroz taj učitavač klasa.

Jednom kada je JVM učitao klasu imenovanu Volcanou određeni prostor imena, na primjer, nemoguće je učitati drugu klasu imenovanu Volcanou taj isti prostor imena. VolcanoMeđutim, možete učitati više klasa u JVM, jer možete stvoriti više prostora imena unutar Java aplikacije. To možete učiniti jednostavno stvaranjem višestrukih učitavača klase. Ako izradite tri odvojena prostora imena (po jedan za svaki od tri učitavača razreda) u pokrenutoj Java aplikaciji, tada bi učitavanjem jedne Volcanoklase u svaki prostor imena vaš program mogao učitati tri različite Volcanoklase u vašu aplikaciju.

Java aplikacija može instancirati više objekata učitavača klasa ili iz iste klase ili iz više klasa. Stoga može stvoriti onoliko objekata (i onoliko različitih vrsta) učitavača klase koliko mu je potrebno. Klase učitane različitim učitavačima klasa nalaze se u različitim prostorima imena i ne mogu dobiti pristup jedni drugima, osim ako to aplikacija izričito ne dopušta. Kada pišete Java aplikaciju, možete razdvojiti klase učitane iz različitih izvora u različite prostore imena. Na taj način možete koristiti Java-ovu arhitekturu učitavača klasa za kontrolu bilo koje interakcije između koda učitanih iz različitih izvora. Možete spriječiti neprijateljski kôd da dobije pristup i podmeće prijateljski kôd.

Razredni utovarivači za aplete

Jedan od primjera dinamičkog proširenja s učitavačima klasa je web preglednik koji koristi objekte učitavača klasa za preuzimanje datoteka klase za aplet preko mreže. Web preglednik otpušta Java program koji instalira objekt učitača klase - koji se obično naziva učitavač klase apleta - koji zna kako zatražiti datoteke klase s HTTP poslužitelja. Apleti su primjer dinamičkog proširenja, jer kada se Java program pokrene, ne zna koje će datoteke klase preglednik tražiti da ih preuzme preko mreže. Datoteke klase za preuzimanje određuju se tijekom izvođenja, jer preglednik nailazi na stranice koje sadrže Java aplete.

Java aplikacija koju pokreće web preglednik obično stvara različiti objekt učitavača klase apleta za svako mjesto na mreži s koje dohvaća datoteke klase. Kao rezultat toga, datoteke klase iz različitih izvora učitavaju se različitim objektima učitavača klasa. To ih smješta u različite prostore imena unutar domaće Java aplikacije. Budući da su datoteke klase za aplete iz različitih izvora smještene u zasebne prostore imena, kodu zlonamjernog apleta ograničeno je izravno ometanje datoteka klase preuzetih iz bilo kojeg drugog izvora.

Suradnja između klasa utovarivača

Često se objekt učitavača klase oslanja na druge učitavače klase - u najmanju ruku, na osnovni učitavač klase - kako bi mu pomogao da ispuni neke zahtjeve za učitavanje klase koji se pojave. Na primjer, zamislite da napišete Java program koji instalira učitavač klase čiji se određeni način učitavanja datoteka klase postiže njihovim preuzimanjem preko mreže. Pretpostavimo da se tijekom izvođenja Java programa postavlja vaš učitavač klase za učitavanje klase s imenom Volcano.

Jedan od načina na koji biste mogli napisati učitavač klase je da prvo zatražite od osnovnog učitavača klase da pronađe i učita klasu iz svog pouzdanog spremišta. U ovom slučaju, budući Volcanoda nije dio Java API-ja, pretpostavimo da osnovni učitavač klasa ne može pronaći klasu s imenom Volcano. Kada osnovni učitavač klase odgovori da ne može učitati klasu, vaš učitavač klase tada može pokušati učitati Volcanoklasu na svoj prilagođeni način, preuzimajući je preko mreže. Pod pretpostavkom da je vaš učitač razreda uspio preuzeti klasu Volcano, ta bi Volcanoklasa tada mogla igrati ulogu u budućem tijeku izvršavanja aplikacije.

Da biste nastavili s istim primjerom, pretpostavimo da se nešto kasnije metoda klase Volcanoprvi put poziva i da se metoda poziva na klasu Stringiz Java API-ja. Budući da pokrenuti program prvi put koristi referencu, virtualni stroj traži da učita učitavač klase (onaj koji se učitao Volcano) String. Kao i prije, vaš učitavač klase prvo prosljeđuje zahtjev osnovnom učitavaču klase, ali u ovom slučaju, osnovni učitavač klase može vratiti Stringklasu natrag u vaš učitavač klase.

Učitavač osnovne klase najvjerojatnije se Stringu ovom trenutku zapravo nije trebao učitati jer je, s obzirom na to da Stringje to tako temeljna klasa u Java programima, gotovo sigurno korišten prije i stoga već učitan. Najvjerojatnije je osnovni učitavač klase upravo vratio Stringklasu koju je prethodno učitao iz pouzdanog spremišta.

Budući da je osnovni učitavač klase uspio pronaći klasu, vaš učitavač klase ne pokušava je preuzeti preko mreže; samo prelazi na virtualni stroj Stringklasu koju je vratio osnovni učitavač klase. Od tog trenutka, virtualni stroj koristi tu Stringklasu kad god se klasa Volcanoodnosi na klasu s imenom String.

Razredni utovarivači u pješčaniku

U Java-ovom pješčaniku, arhitektura učitavača klasa prva je linija obrane od zlonamjernog koda. Napokon je učitavač klase taj koji u JVM unosi kod koji može biti neprijateljski raspoložen.

Arhitektura učitavača klasa doprinosi Java-ovom pješčaniku na dva načina:

  1. Sprječava da se zlonamjerni kod ometa dobroćudnim kodom.
  2. Čuva granice pouzdanih knjižnica razreda.

Arhitektura učitavača klasa čuva granice knjižnica pouzdanih klasa osiguravajući da se pouzdane klase ne mogu pretvarati da su pouzdane. Ako bi zlonamjerna klasa uspješno mogla prevariti JVM da povjeruje da je to pouzdana klasa iz Java API-ja, ta bi zlonamjerna klasa potencijalno mogla probiti barijeru pješčanika. Sprečavajući nepouzdane klase da se predstavljaju kao pouzdane klase, arhitektura učitavača klasa blokira jedan potencijalni pristup ugrožavanju sigurnosti Java izvođenja.

Prostori imena i štitovi

Arhitektura učitavača klasa sprječava da se zlonamjerni kod ometa dobroćudnim kodom pružajući zaštićene prostore imena za klase učitane različitim učitavačima klasa. Kao što je gore spomenuto, prostor imena je skup jedinstvenih imena za učitane klase koje održava JVM.

Prostori imena doprinose sigurnosti jer zapravo možete postaviti štit između klasa učitanih u različite prostore imena. Unutar JVM-a, razredi u istom prostoru imena mogu izravno međusobno komunicirati. Međutim, klase u različitim prostorima imena ne mogu detektirati međusobnu prisutnost, osim ako izričito ne navedete mehanizam koji omogućuje klasama interakciju. Ako je zlonamjerna klasa, jednom učitana, imala zajamčen pristup svakoj drugoj klasi koju trenutno učitava virtualni stroj, ta bi klasa potencijalno mogla naučiti stvari koje ne bi trebala znati ili bi mogla ometati pravilno izvršavanje vašeg programa.

Stvaranje sigurnog okruženja

Kada napišete aplikaciju koja koristi učitavače klasa, kreirate okruženje u kojem se pokreće dinamički učitani kôd. Ako želite da okruženje bude bez sigurnosnih rupa, morate slijediti određena pravila prilikom pisanja programa za učitavanje programa i klase. Općenito, morat ćete napisati svoju aplikaciju tako da zlonamjerni kôd bude zaštićen od dobronamjernog koda. Također, morat ćete napisati učitavače klasa tako da štite granice pouzdanih knjižnica klasa, poput Java API-ja.

Prostori imena i izvori koda

Da biste ostvarili sigurnosne pogodnosti koje nude prostori imena, morate osigurati učitavanje klasa iz različitih izvora putem različitih učitavača klasa. To je gore opisana shema koju koriste web preglednici s omogućenom Javom. Java aplikacija koju je pokrenuo web preglednik obično stvara drugačiji objekt učitavača klasa apleta za svaki izvor klasa koje preuzima preko mreže. Na primjer, preglednik će koristiti jedan objekt učitavača klasa za preuzimanje klasa s //www.niceapplets.com, a drugi objekt učitavača klasa za preuzimanje klasa s //www.meanapplets.com.

Čuvanje ograničenih paketa

Java dopušta da klase u istom paketu međusobno dodjeljuju posebne privilegije pristupa koje se ne dodjeljuju klasama izvan paketa. Dakle, ako vaš učitavač klasa primi zahtjev za učitavanje klase koja se svojim imenom drsko deklarira kao dio Java API-ja (na primjer, klasa imenovana java.lang.Virus), vaš učitavač klasa treba postupiti oprezno. Ako se učita, takva bi klasa mogla dobiti poseban pristup pouzdanim klasama java.langi možda bi mogla koristiti taj poseban pristup u prikrivene svrhe.

Slijedom toga, normalno biste napisali učitavač klasa tako da jednostavno odbija učitati bilo koju klasu koja tvrdi da je dio Java API-ja (ili bilo koje druge pouzdane runtime knjižnice), ali koja ne postoji u lokalnom pouzdanom spremištu. Drugim riječima, nakon što vaš učitavač klase proslijedi zahtjev osnovnom učitavaču klase, a osnovni učitavač klase naznači da ne može učitati klasu, vaš učitavač klase treba provjeriti je li klasa ne izjavila se članom pouzdanog paketa. Ako se dogodi, vaš učitavač klasa, umjesto pokušaja preuzimanja klase preko mreže, trebao bi izbaciti sigurnosnu iznimku.

Čuvanje zabranjenih paketa

Uz to, možda ste instalirali neke pakete u pouzdano spremište koji sadrže klase koje želite da vaša aplikacija može učitati kroz osnovni učitavač klasa, ali da ne želite biti dostupni klasama učitanim kroz vaš učitavač klasa. Na primjer, pretpostavimo da ste stvorili paket s imenom absolutepoweri instalirali ga na lokalno spremište kojem je pristupio osnovni učitavač klase. Pretpostavimo također da ne želite da klase učitane od strane vašeg učitača klasa mogu učitati bilo koju klasu iz absolutepowerpaketa. U ovom biste slučaju svoj učitavač klasa napisali tako da prvo što učini jest osigurati da se tražena klasa ne deklarira kao članabsolutepowerpaket. Ako se zatraži takva klasa, vaš učitavač klase, umjesto da prosljeđuje ime klase prvobitnom učitavaču klase, trebao bi izbaciti sigurnosnu iznimku.

Učitavač klase jedini način na koji može znati je li klasa iz ograničenog paketa, kao što je java.lang, ili zabranjeni paket, poput absolutepowernaziva klase. Dakle, učitavač klasa mora dobiti popis imena ograničenih i zabranjenih paketa. Budući da naziv klase java.lang.Virusoznačava da je iz java.langpaketa i java.langnalazi se na popisu ograničenih paketa, vaš učitavač klasa trebao bi izbaciti sigurnosnu iznimku ako ga osnovni učitavač klase ne može učitati. Isto tako, budući da naziv klase absolutepower.FancyClassLoaderoznačava da je dio absolutepowerpaketa, a absolutepowerpaket se nalazi na popisu zabranjenih paketa, vaš učitavač klasa trebao bi izbaciti sigurnosnu iznimku.

Utovarivač klase usmjeren na sigurnost

Uobičajeni način pisanja učitača klasa koji razmišljaju o sigurnosti je korištenje sljedeća četiri koraka:

  1. Ako postoje paketi iz kojih se ovaj učitavač klasa ne smije učitati, učitavač klase provjerava je li tražena klasa u jednom od gore spomenutih zabranjenih paketa. Ako je tako, to donosi sigurnosnu iznimku. Ako ne, nastavlja se na drugi korak.

  2. Učitavač klase prosljeđuje zahtjev prvobitnom učitavaču klase. Ako osnovni učitavač klase uspješno vrati klasu, učitavač klase vraća istu tu klasu. Inače se nastavlja na treći korak.

  3. Ako postoje pouzdani paketi kojima ovaj učitavač klasa ne smije dodavati klase, učitavač klasa provjerava je li tražena klasa u jednom od tih ograničenih paketa. Ako je tako, to donosi sigurnosnu iznimku. Ako ne, nastavlja se na četvrti korak.

  4. Konačno, učitavač klasa pokušava učitati klasu na prilagođeni način, na primjer preuzimanjem putem mreže. Ako je uspješno, vraća klasu. Ako je neuspješan, izbaciće pogrešku "nije pronađena definicija klase".

Izvođenjem prvog i tri koraka kako je gore navedeno, učitavač klase čuva granice pouzdanih paketa. Prvim korakom sprječava učitavanje klase iz zabranjenog paketa. S trećim korakom ne dopušta da se nepovjerena klasa umetne u pouzdani paket.

Zaključak

Arhitektura učitavača klasa doprinosi JVM-ovom sigurnosnom modelu na dva načina:

  1. odvajanjem koda u više prostora imena i postavljanjem "štita" između koda u različite prostore imena
  2. čuvanjem granica pouzdanih knjižnica klasa, kao što je Java API

Obje ove mogućnosti Java-ove arhitekture učitavača klasa programeri moraju pravilno koristiti kako bi iskoristili sigurnosnu korist koju nude. Da bi se iskoristila zaštita prostora imena, kôd iz različitih izvora treba učitati kroz različite objekte učitavača klase. Da bi iskoristili prednost pouzdanog čuvanja granica paketa, učitavači klasa moraju biti napisani kako bi provjerili imena traženih klasa na popisu ograničenih i zabranjenih paketa.

Za šetnju kroz postupak pisanja učitača klasa, uključujući uzorak koda, pogledajte članak JavaWorlda Chucka McManisa , "Osnove učitača klase Java".

Sljedeći mjesec

U članku sljedećeg mjeseca nastavit ću raspravu o JVM-ovom sigurnosnom modelu opisujući provjeru klase.

Bill Venners profesionalno piše softver već 12 godina. Sa sjedištem u Silicijskoj dolini pruža usluge savjetovanja i obuke za softver pod nazivom Artima Software Company. Tijekom godina razvio je softver za potrošačku elektroniku, obrazovanje, poluvodiče i industriju životnog osiguranja. Programirao je na mnogim jezicima na mnogim platformama: montažni jezik na raznim mikroprocesorima, C na Unixu, C ++ na Windowsima, Java na webu. Autor je knjige: Inside Java Virtual Machine, u izdanju McGraw-Hill.

Saznajte više o ovoj temi

  • Knjiga Specifikacija virtualnog stroja Java (//www.aw.com/cp/lindholm-yellin.html), Tim Lindholm i Frank Yellin (ISBN 0-201-63452-X), dio serije Java (// www.aw.com/cp/javaseries.html), tvrtke Addison-Wesley, konačna je referenca Java virtualnog stroja.
  • Sigurno računanje s JavaNow and the Future ( tehnička knjiga ) // www.javasoft.com/marketing/collateral/security.html
  • Česta pitanja o sigurnosti apleta

    //www.javasoft.com/sfaq/

  • Sigurnost na niskoj razini u Javi, Frank Yellin //www.javasoft.com/sfaq/verifier.html
  • Početna stranica Java Security

    //www.javasoft.com/security/

  • Pogledajte početnu stranicu neprijateljskih apleta

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

  • Knjiga Java SecurityHostile Applets, Holes and Antidotes, dr. Garyja McGrawa i Eda Feltona, daje temeljitu analizu sigurnosnih problema koji okružuju Javu. //www.rstcorp.com/java-security.html
  • Prethodni članci "Ispod haube":
  • Lean, Mean Virtual Machine - daje uvod u Java virtualni stroj.
  • Životni stil datoteke Java Class - daje pregled datoteke klase Java, formata datoteke u koji su kompilirani svi Java programi.
  • Java prikupljena gomila smeća - daje pregled sakupljanja smeća općenito, a posebno gomile sakupljenog smeća na virtualnom stroju Java.
  • Osnove bytecode-a - uvodi bytecode-ove Java virtualnog stroja i posebno raspravlja o primitivnim vrstama, operacijama pretvorbe i operacijama stoga.
  • Aritmetika s pokretnom zarezom - opisuje podršku za plutajuću zarez Java virtualnog stroja i bajt kodove koji izvode operacije s pomičnom zarezom.
  • Logika i aritmetika - opisuje podršku Java virtualnog stroja za logičku i cjelobrojnu aritmetiku i srodne bajt kodove.
  • Objekti i nizovi - opisuje kako se Java virtualni stroj bavi objektima i nizovima i razmatra relevantne bajtkodove.
  • Iznimke - opisuje kako se Java virtualni stroj nosi s iznimkama i razmatra relevantne bajtkodove.
  • Try-Final - opisuje kako Java virtualni stroj implementira try-napokon klauzule i razmatra relevantne bajt kodove.
  • Kontrolni tok - opisuje kako Java virtualni stroj implementira kontrolni tok i razmatra relevantne bajt kodove.
  • Arhitektura Agleta - opisuje unutarnji rad agleta, IBM-ove autonomne tehnologije softverskog agenta zasnovanog na Javi.
  • The Point of Aglets - Analizira stvarnu korisnost mobilnih agenata kao što su aglets, IBM-ova autonomna tehnologija softverskog agenta zasnovana na Javi.
  • Pozivanje i povratak metode - opisuje četiri načina na koja Java virtualni stroj poziva metode, uključujući relevantne bajt kodove.
  • Sinkronizacija niti - pokazuje kako sinkronizacija niti djeluje u Java virtualnom stroju. Raspravlja o bajt kodovima za ulazak i izlazak iz monitora.
  • Java-ova sigurnosna arhitektura - daje pregled sigurnosnog modela ugrađenog u JVM i razmatra ugrađene sigurnosne značajke JVM-a.

Ovu priču, "Sigurnost i arhitektura učitavača klasa" izvorno je objavio JavaWorld.