Klasių krautuvai ir pavadinimų vietos
Kiekvienai įkeliamai klasei JVM stebi, kuris klasės krautuvas - ar pirminis, ar objektinis - įkėlė klasę. Kai įkelta klasė pirmą kartą nurodo kitą klasę, virtualioji mašina prašo nurodytos klasės iš tos pačios klasės pakrovėjo, kuris iš pradžių įkėlė nuorodų klasę. Pavyzdžiui, jei virtuali mašina įkelia klasę Vulkanas
per tam tikrą klasės krautuvą jis bandys įkelti bet kurias klases Vulkanas
reiškia per tos pačios klasės krautuvą. Jei Vulkanas
reiškia klasę, pavadintą Lava
, galbūt klasėje pasitelkiant metodą Lava
, virtuali mašina paprašys Lava
nuo pakrautos klasės krautuvo Vulkanas
. Lava
klasės krautuvo grąžinta klasė yra dinamiškai susieta su klase Vulkanas
.
Kadangi JVM laikosi šio požiūrio į klasių įkėlimą, klasės pagal numatytuosius nustatymus gali matyti tik kitas klases, kurias įkėlė tas pats klasės krautuvas. Tokiu būdu „Java“ architektūra leidžia sukurti kelis pavadinimai-erdvės vienos „Java“ programos viduje. Vardas-erdvė yra unikalių klasių pavadinimų rinkinys, kurį įkėlė tam tikras klasės krautuvas. Kiekvienam klasės krautuvui JVM palaiko pavadinimo erdvę, kurią užpildo visų klasių, kurios buvo įkeltos per tą klasės krautuvą, pavadinimai.
Kai JVM įkels klasę, pavadintą Vulkanas
Pavyzdžiui, į tam tikrą pavadinimo erdvę neįmanoma įkelti kitos klasės pavadinimo Vulkanas
į tą pačią pavadinimo erdvę. Galite įkelti kelis Vulkanas
klases į JVM, nes „Java“ programoje galite sukurti kelias pavadinimų erdves. Tai galite padaryti paprasčiausiai sukūrę kelių klasių krautuvus. Jei veikiančioje „Java“ programoje sukursite tris atskirus pavadinimų tarpus (po vieną kiekvienam iš trijų klasės krautuvų), tada įkelkite vieną Vulkanas
klasę į kiekvieną pavadinimo erdvę, jūsų programa gali įkelti tris skirtingas Vulkanas
klases į jūsų programą.
„Java“ programa gali iš karto sukurti kelis tos pačios klasės arba kelių klasių krautuvo objektus. Todėl jis gali sukurti tiek (ir tiek įvairių rūšių) klasės krautuvo objektų, kiek jam reikia. Skirtingų klasių krautuvų įkeltos klasės yra skirtingose pavadinimų erdvėse ir negali pasiekti viena kitos, nebent tai aiškiai leidžia programa. Kai rašote „Java“ programą, galite atskirti klases, įkeltas iš skirtingų šaltinių, į skirtingas pavadinimų erdves. Tokiu būdu galite naudoti „Java“ klasės krautuvo architektūrą valdyti bet kokią sąveiką tarp kodo, įkelto iš skirtingų šaltinių. Galite užkirsti kelią priešiškam kodui gauti prieigą prie draugiško kodo ir jį sugadinti.
Klasių krautuvai programėlėms
Vienas iš dinaminio plėtinio su klasės krautuvais pavyzdžių yra žiniatinklio naršyklė, kuri naudoja klasės krautuvo objektus, kad tinkle galėtų atsisiųsti programėlės klasės failus. Žiniatinklio naršyklė suaktyvina „Java“ programą, kuri įdiegia klasės krautuvo objektą - paprastai vadinamą programėlių klasės krautuvas - žino, kaip prašyti klasės failų iš HTTP serverio. Appletai yra dinaminio plėtinio pavyzdys, nes paleidus „Java“ programą, ji nežino, kurios klasės failus naršyklė paprašys atsisiųsti visame tinkle. Klasės failai, kuriuos reikia atsisiųsti, nustatomi vykdymo metu, nes naršyklė susiduria su puslapiais, kuriuose yra „Java“ programėlių.
Žiniatinklio naršyklės paleista „Java“ programa kiekvienai tinklo vietai, iš kurios gauna klasės failus, paprastai sukuria skirtingą programėlių klasės krautuvo objektą. Dėl to skirtingų failų objektai įkelia klasės failus iš skirtingų šaltinių. Tai juos talpina skirtingose pavadinimų erdvėse pagrindinės „Java“ programos viduje. Kadangi įvairių šaltinių programėlių klasės failai dedami į atskiras pavadinimo vietas, kenkėjiškos programėlės kodas negali kištis tiesiogiai į klasės failus, atsisiųstus iš bet kurio kito šaltinio.
Klasių krautuvų bendradarbiavimas
Dažnai klasės krautuvo objektas pasikliauja kitais klasės krautuvais, bent jau su pirmykščiu klasės krautuvu, kad padėtų jam įvykdyti kai kurias klasės krovinių užklausas. Pvz., Įsivaizduokite, kad rašote „Java“ programą, kuri įdiegia klasės krautuvą, kurio konkretus klasės failų įkėlimo būdas pasiekiamas juos atsisiunčiant tinkle. Tarkime, kad vykdant „Java“ programą jūsų klasės krautuvas pateikia užklausą pakrauti pavadintą klasę Vulkanas
.
Vienas iš būdų, kaip galėtumėte parašyti klasės krautuvą, yra tai, kad jis pirmiausia paprašytų pirmykščio klasės krautuvo surasti ir įkelti klasę iš patikimos saugyklos. Šiuo atveju nuo Vulkanas
nėra „Java“ API dalis, tarkime, kad pradinis klasės krautuvas negali rasti klasės pavadinimo Vulkanas
. Kai pirminis klasės krautuvas atsako, kad jis negali įkelti klasės, jūsų klasės krautuvas gali bandyti įkelti Vulkanas
klasę įprastu būdu, atsisiųsdami ją per tinklą. Darant prielaidą, kad jūsų klasės krautuvas galėjo atsisiųsti klasę Vulkanas
, tai Vulkanas
klasė galėtų atlikti vaidmenį ateityje vykdant programą.
Tęsdami tą patį pavyzdį, tarkime, kad po kurio laiko klasės metodas Vulkanas
yra iškviečiamas pirmą kartą ir kad metodas nurodo klasę Stygos
iš „Java“ API. Kadangi pirmą kartą nuorodą naudoja vykdoma programa, virtualioji mašina klausia jūsų klasės krautuvo (to, kuris įkėlė Vulkanas
) pakrauti Stygos
. Kaip ir anksčiau, jūsų klasės krautuvas pirmiausia perduoda užklausą pirminės klasės krautuvui, tačiau šiuo atveju pirmykštės klasės krautuvas gali grąžinti Stygos
klasę atgal į savo klasės krautuvą.
Pirminės klasės krautuvui greičiausiai nereikėjo krauti Stygos
šiuo metu, nes, atsižvelgiant į tai Stygos
yra tokia pagrindinė „Java“ programų klasė, ji beveik neabejotinai buvo naudojama anksčiau, todėl jau buvo įkelta. Labiausiai tikėtina, kad pirmykštės klasės krautuvas ką tik grąžino Stygos
klasę, kurią anksčiau buvo įkėlusi iš patikimos saugyklos.
Kadangi pradinis klasės krautuvas sugebėjo rasti klasę, jūsų klasės krautuvas nemėgina jos atsisiųsti visame tinkle; jis tiesiog pereina į virtualią mašiną Stygos
klasę grąžino pirmykštės klasės krautuvas. Nuo to momento virtuali mašina tuo naudojasi Stygos
klasė, kai tik klasė Vulkanas
nurodo klasę, pavadintą Stygos
.
Klasės krautuvai smėlio dėžėje
„Java“ smėlio dėžėje klasės krautuvo architektūra yra pirmoji gynybos linija nuo kenkėjiškų kodų. Galų gale tai yra klasės krautuvas, kuris įneša kodą į JVM - kodą, kuris gali būti priešiškas.
Klasės krautuvo architektūra prisideda prie „Java“ smėlio dėžės dviem būdais:
- Tai neleidžia kenksmingam kodui kištis į geranorišką kodą.
- Jis saugo patikimų klasių bibliotekų sienas.
Klasės krautuvo architektūra saugo patikimų klasių bibliotekų sienas užtikrindama, kad nepatikimos klasės negalėtų apsimesti pasitikėjimu. Jei kenkėjiška klasė galėtų sėkmingai apgauti JVM, manydama, kad tai yra patikima „Java“ API klasė, ta kenkėjiška klasė gali prasibrauti per smėlio dėžės barjerą. Užkertant kelią nepatikimoms klasėms apsimetinėti patikimomis klasėmis, klasės krautuvo architektūra blokuoja vieną potencialų požiūrį į „Java“ vykdymo laiko saugumo pažeidimą.
Vardų erdvės ir skydai
Klasės krautuvo architektūra neleidžia kenksmingam kodui kištis į geranorišką kodą, suteikdama apsaugotas pavadinimų vietas klasėms, kurias įkrauna skirtingi klasių krautuvai. Kaip paminėta aukščiau, vardas-erdvė yra unikalių įkeltų klasių pavadinimų rinkinys, kurį prižiūri JVM.
Vardų erdvės prisideda prie saugumo, nes iš tikrųjų galite įdėti skydą tarp klasių, įkeltų į skirtingas pavadinimų erdves. JVM viduje klasės toje pačioje pavadinimo erdvėje gali tiesiogiai bendrauti. Tačiau skirtingose pavadinimų erdvėse esančios klasės net negali aptikti vienas kito buvimo, nebent jūs aiškiai pateikiate mechanizmą, leidžiantį klasėms sąveikauti. Jei įkelta kenkėjiška klasė garantavo prieigą prie visų kitų virtualios mašinos šiuo metu įkeltų klasių, ta klasė galėjo išmokti dalykų, kurių neturėjo žinoti, arba tai gali trukdyti tinkamai vykdyti jūsų programą.
Saugios aplinkos kūrimas
Rašydami programą, naudojančią klasės krautuvus, sukuriate aplinką, kurioje veikia dinamiškai įkeltas kodas. Jei norite, kad aplinkoje nebūtų saugumo spragų, rašydami savo programą ir klasės krautuvus turite laikytis tam tikrų taisyklių. Apskritai norėsite parašyti savo paraišką taip, kad kenkėjiškas kodas būtų apsaugotas nuo geranoriško kodo. Taip pat norėsite parašyti klasių krautuvus taip, kad jie apsaugotų patikimų klasių bibliotekų, pvz., „Java“ API, sienas.
Pavadinimų tarpai ir kodų šaltiniai
Norėdami gauti vardų tarpų teikiamą saugumo naudą, turite įsitikinti, kad klases iš skirtingų šaltinių įkėlėte per skirtingus klasių krautuvus. Tai aukščiau aprašyta schema, kurią naudoja „Java“ palaikančios interneto naršyklės. „Java“ programa, paleista žiniatinklio naršyklės, kiekvienam tinklui atsisiųstamam klasių šaltiniui paprastai sukuria skirtingą programėlių klasės krautuvo objektą. Pvz., Naršyklė naudos vieną klasės krautuvo objektą, norėdamas atsisiųsti klases iš //www.niceapplets.com, o kitą klasės krautuvo objektą - iš //www.meanapplets.com.
Ribotų pakuočių apsauga
„Java“ leidžia to paties paketo klasėms suteikti viena kitai specialias prieigos teises, kurios nėra suteikiamos ne paketo klasėms. Taigi, jei jūsų klasės krautuvas gauna užklausą įkelti klasę, kuri savo vardu įžūliai skelbiasi esanti „Java“ API dalis (pavyzdžiui, klasė pavadinta java.lang.Virus
), jūsų klasės krautuvas turėtų elgtis atsargiai. Jei bus pakrauta, tokia klasė galėtų gauti specialią prieigą prie patikimų klasių java.lang
ir galbūt galėtų naudoti tą specialią prieigą apsukriems tikslams.
Todėl paprastai parašykite klasės krautuvą, kad jis tiesiog atsisakytų įkelti bet kurią klasę, kuri teigia esanti „Java“ API dalis (ar bet kuri kita patikima vykdymo laiko biblioteka), bet kurios nėra vietinėje patikimoje saugykloje. Kitaip tariant, po to, kai jūsų klasės krautuvas perduoda užklausą pirmykščiam klasės krautuvui, o pradinis klasės krautuvas nurodo, kad jis negali įkelti klasės, jūsų klasės krautuvas turėtų patikrinti, ar klasė nepaskelbia esanti narė patikimo paketo. Jei taip, jūsų klasės krautuvas turėtų užuot bandęs atsisiųsti klasę visame tinkle, išimtis dėl saugumo.
Draudžiamų pakuočių apsauga
Be to, galite būti įdiegę keletą paketų patikimoje saugykloje, kuriuose yra klasės, kurias norite, kad jūsų programa galėtų įkelti per pirminį klasės pakrovėją, tačiau nenorite būti prieinami klasėms, įkeliamoms per savo klasės krautuvą. Pvz., Tarkime, kad sukūrėte paketą pavadinimu absoliuti jėga
ir įdiegė jį į vietinę saugyklą, prieinamą pirmykštės klasės krautuvu. Taip pat tarkime, kad nenorite, kad klasės krautuvas įkeltas klases galėtų įkelti bet kurią klasę iš absoliuti jėga
pakuotė. Tokiu atveju savo klasės krautuvą turėtumėte parašyti taip, kad pirmas dalykas, kurį jis daro, yra įsitikinti, kad prašoma klasė nedeklaruoja savęs kaip absoliuti jėga
pakuotė. Jei prašoma tokios klasės, jūsų klasės krautuvas, užuot perdavęs klasės pavadinimą pirminiam klasės krautuvui, turėtų išmesti saugumo išimtį.
Vienintelis būdas, kaip klasės krautuvas gali žinoti, ar klasė yra iš riboto paketo, pvz., java.lang
, arba draudžiama pakuotė, pvz absoliuti jėga
, yra klasės pavadinimas. Taigi klasės krautuvui turi būti pateiktas ribotų ir draudžiamų paketų pavadinimų sąrašas. Nes klasės pavadinimas java.lang.Virus
rodo, kad jis yra iš java.lang
pakuotė ir java.lang
yra ribojamų paketų sąraše, jūsų klasės krautuvas turėtų išmesti saugumo išimtį, jei pirminės klasės krautuvas negali jos įkelti. Panašiai, nes klasės pavadinimas absoliuti galia.FancyClassLoader
rodo, kad tai yra absoliuti jėga
paketą ir absoliuti jėga
paketas yra draudžiamų paketų sąraše, jūsų klasės krautuvas turėtų išmesti saugumo išimtį.
Saugiai mąstantis klasės krautuvas
Dažniausias būdas rašyti saugų klasių krautuvą yra naudoti šiuos keturis veiksmus:
Jei egzistuoja paketai, iš kurių neleidžiama įkelti šios klasės krautuvo, klasės krautuvas patikrina, ar prašoma klasė yra vienoje iš aukščiau paminėtų draudžiamų paketų. Jei taip, tai sukuria saugumo išimtį. Jei ne, jis tęsia antrą žingsnį.
Klasės krautuvas perduoda užklausą pirminiam klasės krautuvui. Jei pradinis klasės krautuvas sėkmingai grąžina klasę, klasės krautuvas grąžina tą pačią klasę. Priešingu atveju jis tęsia trečią žingsnį.
Jei egzistuoja patikimi paketai, prie kurių šiam klasės krautuvui neleidžiama pridėti klasių, klasės krautuvas patikrina, ar prašoma klasė yra viename iš tų ribotų paketų. Jei taip, tai sukuria saugumo išimtį. Jei ne, tai tęsiama ketvirtu žingsniu.
- Galiausiai klasės krautuvas bando klasę įkelti įprastu būdu, pavyzdžiui, atsisiųsdamas ją per tinklą. Jei pavyks, tai grąžins klasę. Jei nepavyksta, tai iškelia klaidą „nerasta klasės apibrėžimo“.
Atlikdamas pirmąjį ir trečiąjį veiksmus, kaip aprašyta aukščiau, klasės krautuvas saugo patikimų paketų sienas. Pirmasis žingsnis neleidžia apskritai įkelti klasės iš draudžiamo paketo. Atlikus trečią veiksmą, nepatikima klasė neleidžia įterpti į patikimą paketą.
Išvada
Klasės krautuvo architektūra prisideda prie JVM saugos modelio dviem būdais:
- atskiriant kodą į kelias pavadinimų erdves ir dedant „skydą“ tarp kodo skirtingose pavadinimų erdvėse
- saugant patikimų klasių bibliotekų, tokių kaip „Java“ API, sienas
Programuotojai turi tinkamai naudoti abi šias „Java“ klasės krautuvų architektūros galimybes, kad galėtų pasinaudoti jų siūloma saugumo nauda. Norint pasinaudoti pavadinimo ir erdvės skydo privalumais, kodą iš skirtingų šaltinių reikia įkelti per skirtingus klasės krautuvo objektus. Norint pasinaudoti patikimos paketų sienos apsaugos galimybėmis, turi būti parašyti klasių pakrovėjai, kad jie patikrintų prašomų klasių pavadinimus pagal ribojamų ir draudžiamų paketų sąrašą.
Norėdami sužinoti, kaip rašyti klasės krautuvą, įskaitant kodo pavyzdį, žr. Chucką McManį „JavaWorld“ straipsnis „Java klasės krautuvų pagrindai“.
Kitą mėnesį
Ateinančio mėnesio straipsnyje aš tęsiu diskusiją apie JVM saugumo modelį, aprašydamas klasės tikrintoją.
Billas Vennersas profesionaliai rašė programinę įrangą 12 metų. Silicio slėnyje įsikūręs jis teikia programinės įrangos konsultavimo ir mokymo paslaugas „Artima Software Company“ vardu. Per daugelį metų jis sukūrė programinę įrangą buitinės elektronikos, švietimo, puslaidininkių ir gyvybės draudimo pramonei. Jis programavo daugeliu kalbų daugelyje platformų: surinkimo kalba įvairiuose mikroprocesoriuose, C „Unix“, C ++ „Windows“, „Java“ internete. Jis yra knygos „Inside the Java Virtual Machine“, kurią išleido McGraw-Hill, autorius.Sužinokite daugiau apie šią temą
- Knyga „Java“ virtualiosios mašinos specifikacija (//www.aw.com/cp/lindholm-yellin.html), autoriai Tim Lindholm ir Frank Yellin (ISBN 0-201-63452-X), „Java“ serijos dalis (//www.aw.com/cp /javaseries.html) iš Addison-Wesley yra galutinė „Java“ virtualiosios mašinos nuoroda.
- Saugus skaičiavimas naudojant „JavaNow“ ir ateitį (baltas popierius) // www.javasoft.com/marketing/collateral/security.html
- Apletų saugos DUK
//www.javasoft.com/sfaq/
- Žemas saugumo lygis „Java“, pateikė Frankas Yellinas //www.javasoft.com/sfaq/verifier.html
- Pagrindinis „Java Security“ puslapis
//www.javasoft.com/security/
- Žr. „Hostile Applets“ pagrindinį puslapį
//www.math.gatech.edu/~mladue/HostileApplets.html
- Knyga „Java SecurityHostile“ programėlės, skylės ir priešnuodžiai, Dr. Gary McGraw ir Edas Feltonas pateikia išsamią su Java susijusių problemų analizę. //www.rstcorp.com/java-security.html
- Ankstesni straipsniai „Po gaubtu“:
- „Lean“, „Mean Virtual Machine“ - pateikia „Java“ virtualiosios mašinos įvadą.
- „Java“ klasės failų gyvenimo būdas - pateikia „Java“ klasės failo, failo formato, į kurį sudaromos visos „Java“ programos, apžvalgą.
- „Java's Garbage- Collected Heap“ - apžvelgia šiukšlių surinkimą apskritai ir „Java“ virtualiosios mašinos šiukšlių surinktą kaupą.
- „Bytecode“ pagrindai - pristato „Java“ virtualiosios mašinos baitų kodus ir ypač aptariami primityvūs tipai, konversijos operacijos ir kamino operacijos.
- Kintamojo taško aritmetika - apibūdina „Java“ virtualiosios mašinos slankiojo kablelio palaikymą ir baitekodus, kurie atlieka slankiojo kablelio operacijas.
- Logika ir aritmetika - apibūdina „Java“ virtualiosios mašinos palaikymą loginei ir sveikojo skaičiaus aritmetikai bei susijusius baitų kodus.
- Objektai ir masyvai - apibūdina, kaip „Java“ virtualioji mašina elgiasi su objektais ir masyvais, ir aptaria atitinkamus baitų kodus.
- Išimtys - apibūdina, kaip „Java“ virtuali mašina tvarko išimtis, ir aptaria atitinkamus baitų kodus.
- „Pabandykite pagaliau“ - apibūdina, kaip „Java“ virtuali mašina įgyvendina bandomąsias išlygas, ir aptaria atitinkamus baitų kodus.
- Valdymo srautas - apibūdina, kaip „Java“ virtuali mašina įgyvendina valdymo srautą, ir aptaria atitinkamus baitekodus.
- Agletų architektūra - apibūdina agletų, IBM autonominės „Java“ pagrindu sukurtos programinės įrangos agento technologijos, vidinį darbą.
- „Aglets“ taškas - analizuojamas realus mobiliųjų agentų, tokių kaip agletai, IBM autonominės „Java“ pagrindu sukurtos programinės įrangos agento technologijos, naudingumas.
- Metodo iškvietimas ir grąžinimas - apibūdina keturis būdus, kuriais „Java“ virtuali mašina naudoja metodus, įskaitant atitinkamus baitų kodus.
- Gijų sinchronizavimas - parodo, kaip gijų sinchronizavimas veikia „Java“ virtualioje mašinoje. Aptariami monitorių įėjimo ir išėjimo baitų kodai.
- „Java“ saugumo architektūra - apžvelgia JVM įmontuotą saugos modelį ir apžvelgia JVM įmontuotas saugos funkcijas.
Šią istoriją „Sauga ir klasės krautuvo architektūra“ iš pradžių paskelbė „JavaWorld“.