Τι
περιλαμβάνει το μοντέλο ασφάλειας της JAVA
Το μοντέλο ασφάλειας της Java διαφέρει ριζικά απ’ τις παραδοσιακές
προσεγγίσεις. Τα περισσότερα λειτουργικά συστήματα επιτρέπουν
στις εφαρμογές να έχουν πλήρη σχεδόν πρόσβαση στους πόρους
του συστήματος. Οι διαχειριστές θα πρέπει να βασίζονται στους
χρήστες για να διασφαλίσουν ότι οι πόροι είναι αρκούντως προστατευμένοι.
Δεύτερον, είναι συνήθως υποχρέωση του χρήστη και κάνει έναν
έλεγχο του προγράμματος (π.χ. για ύπαρξη ιών) πριν την εκτέλεση.
Αυτή η τακτική έχει δύο προφανή μειονεκτήματα, επαφίεται στην
καλή διάθεση του χρήστη για να κάνει τον έλεγχο και ακόμη
βασίζεται στην ακρίβεια του προγράμματος ανίχνευσης ιών.
Όπως θα δούμε η Java λαμβάνει μια πιο δυναμική προσέγγιση.
Εδώ συνδυάζει ένα σύνολο συστατικών που συνεργάζονται μεταξύ
τους, και ποικίλουν από διαχειριστές ασφάλειας οι οποίοι εκτελούνται
σαν μέρος της εφαρμογής, έως μετρήσεις ασφάλειας ενσωματωμένες
μέσα στην Java. Για να δούμε λοιπόν αυτά τα συστατικά με μεγαλύτερη
λεπτομέρεια.
Class Loader
Πρώτο συστατικό είναι ο class loader. Όπως έχουμε αναφέρει
τα applets εκτελούνται σαν μέρος μιας ιστοσελίδας και μάλιστα
χωρίς ο χρήστης να αντιλαμβάνεται οτιδήποτε (διαφανώς). Για
να φορτωθεί το applet, ο Browser καλεί πρώτα και υποχρεωτικά
τον class loader. Εδώ αρχίζει η πρώτη γραμμή άμυνας του μοντέλου.
Ο class loader καθορίζει πως και πότε ένα applet μπορεί να
φορτώσει μια κλάση δηλαδή κώδικα που πρόκειται να εκτελεστεί.
Οι βασικές λειτουργίες του είναι οι ακόλουθες, φέρνει τον
κώδικα του applet από το απομακρυσμένο μηχάνημα, ορίζει μια
ιεραρχία namespace (δηλαδή χώρων ξεχωριστών για κάθε είδος
κλάσης, που από εδώ και πέρα θα ονομάζονται περιοχές).
Μια από τις πιο βασικές λειτουργίες του είναι να διασφαλίσει
ότι τα εκτελούμενα applets δεν αντικαθιστούν συστατικά του
συστήματος. Πιο συγκεκριμένα αποτρέπει τα applets απ’ το να
δημιουργήσουν τους δικούς τους class loaders. Επίσης αποτρέπει
τα applets απ’ το να καλούν μεθόδους οι οποίες είναι μέρος
του class loader. Το εκτελέσιμο (run-time) περιβάλλον την
Java, επιτρέπει σε πολλαπλούς class loaders να συνυπάρχουν
ταυτόχρονα ο καθένας όμως να βρίσκεται στην δικιά του περιοχή.
Το περιβάλλον της Java επιτρέπει να ομαδοποιούνται οι κλάσεις
με βάση την προέλευση τους, αλλού οι τοπικές, αλλού οι απομακρυσμένες
από έμπιστα μηχανήματα, αλλού οι ύποπτες. Θέτοντας τέτοιους
περιορισμούς στις περιοχές ο class loader αποτρέπει “ύποπτα”
applets απ’ το να αποκτήσουν πρόσβαση σε πόρους του συστήματος.
Έτσι αυτές οι περιοχές αποτελούν την πρώτη γραμμή άμυνας που
παρέχει το αμμοδοχείο.
Όπως έχουν σχεδιαστεί οι class loaders φορτώνουν τα applets
και τις αντίστοιχες κλάσεις. Όταν εκτελείται το applet ο Browser
καλεί το applet class loader το οποίο φέρνει το applet. Φυσιολογικά
τα applets δεν μπορούν να εγκαταστήσουν νέους class loaders
έτσι ο αρχικός class loader ελέγχει το περιβάλλον. Αυτός ο
class loader δημιουργεί τις ξεχωριστές περιοχές μια για κάθε
applet. Έτσι τα applets έχουν πρόσβαση μόνο στις δικές τους
κλάσεις και σε κλάσεις που ανήκουν στις τυποποιημένες βιβλιοθήκες
της Java. Έτσι δεν έχουν πρόσβαση σε κλάσεις που ανήκουν σε
άλλα applets. Αυτό έχει δύο πλεονεκτήματα, οι ξεχωριστές περιοχές
κάνουν δύσκολο για τα applets να μοιραστούν τους πόρους που
καταλαμβάνουν και έτσι να κάνουν μια οργανωμένη επίθεση και
επίσης οι προγραμματιστές των applets δεν χρειάζεται αν ασχολούνται
με όμοια ονόματα, μιας και κάθε όνομα αρκεί να είναι μοναδικό
μέσα σε ένα και μόνο applet.
Τα προβλήματα που μπορεί να προκύψουν είναι δύο, στο περιβάλλον
του Browser συνήθως τον class loader τον παρέχει ο κατασκευαστής
του Browser. Παρ’ όλο που οι συγκεκριμένοι class loaders βασίζονται
σε πίνακες οι οποίοι δίνονται απ’ την μητρική εταιρεία την
Sun πολλές φορές η υλοποίηση τους δεν είναι το ίδιο ασφαλής.
Επίσης οι εφαρμογές της Java έχουν το δικαίωμα να δημιουργήσουν
τους δικούς τους class loaders. Θα πρέπει να προσέξουμε όταν
σχεδιάζουμε class loaders να ακολουθούμε όλες τις αρχές που
έχουν καθοριστεί απ’ το JDK (Java Development Kit). Αν γίνει
αυτό οι δυσκολίες θα είναι ελάχιστες.
ByteCode Verifier
Το δεύτερο συστατικό στοιχείο που προσδίδει ασφάλεια στο αμμοδοχείο
είναι ο Bytecode Verifier. Έχουμε πει ότι ο πηγαίος κώδικας
της Java μετατρέπεται με τον compiler σε έναν διαπλατφορμικό
ψηφιοκώδικα (Byte Code). Πριν ο Class Loader επιτρέψει στο
applet να εκτελεστεί, ο κώδικας του πρέπει να ελεγχθεί απ’
τον Bytecode Verifier. Ο ελεγκτής αυτός μπορεί να διαπιστώσει
ότι ο κώδικας του applet ο οποίος μπορεί να μην έχει δημιουργηθεί
από έναν Java compiler ακολουθεί όλους τους κανόνες της γλώσσας.
Ο ελεγκτής εκτελεί διάφορους ελέγχους. Σε ένα βασικό επίπεδο
βεβαιώνει ότι ο κώδικας είναι σύμφωνος με τους κανόνες και
τις προδιαγραφές της γλώσσας. Σε ένα πιο σύνθετο επίπεδο ο
ελεγκτής εφαρμόζει ένα ενσωματωμένο θεώρημα σε σχέση με τον
κώδικα. Με το παραπάνω διασφαλίζεται ότι το applet ανάμεσα
στα άλλα δεν πλαστογραφεί δείκτες, δεν καταστρατηγεί τους
κανόνες πρόσβασης ή δεν αποκτά πρόσβαση σε αντικείμενα μέσα
από παράνομα αντίγραφα. Ο Bytecode Verifier σε συνδυασμό με
χαρακτηριστικά ασφάλειας που είναι ενσωματωμένα μέσα στην
γλώσσα μπορεί να διασφαλίσει ότι:
Όλες οι προσβάσεις σε μέλη κλάσεων είναι νομότυπες. Αυτό
σημαίνει ότι τα ιδιωτικά δεδομένα ενός αντικειμένου παραμένουν
ιδιωτικά.
Security Manager
Το τρίτο και πιο σημαντικό συστατικό του μοντέλου ασφάλειας
της Java είναι ο Security Manager. Η δουλειά του είναι να
κάνει ελέγχους κατά τον χρόνο εκτέλεσης για όλες αυτές τις
μεθόδους που θα χαρακτηρίζαμε επικίνδυνες, μεθόδους δηλαδή
που αιτούνται Ε/Ε αρχείων, πρόσβαση στο δίκτυο ή αυτές που
θέλουν να ορίσουν έναν νέο class loader. Σε όλες αυτές τις
περιπτώσεις ο Security Manager μπορεί να ασκήσει βέτο σε οποιαδήποτε
αίτηση. Για παράδειγμα εάν ένα applet καλέσει μια μέθοδο “ανάγνωσης”,
η JVM συμβουλεύεται τον Security Manager. Εάν το applet είναι
έμπιστο (trusted) τότε η αίτηση θα επιτραπεί, εαν όχι η αίτηση
θα απορριφθεί. Κάποια απ’ τα καθήκοντα του Security Manager
περιλαμβάνουν: