Είναι γεγονός ότι η χρήση προτύπων ασφαλείας ιστού δεν δημιουργεί κατ ανάγκην ασφαλείς δικτυακές υπηρεσίες και εφαρμογές, γι’ αυτό και απαιτείται να εφαρμόζονται σωστές πρακτικές κατά το σχεδιασμό αλλά και την υλοποίηση των υπηρεσιών αυτών.

Ο ορισμός που δίνει το W3C για τα Web Services είναι ότι αποτελούν «συστήματα λογισμικού, που σκοπό έχουν να υποστηρίξουν τη διαλειτουργική αλληλεπίδραση συστημάτων σε ένα δίκτυο». Τα Web services παρέχουν γενικούς μηχανισμούς, που απλοποιούν τη χαμηλού επιπέδου προγραμματιστική δουλειά η οποία συνήθως απαιτείται για την ανάπτυξη δικτυακών ή κατανεμημένων εφαρμογών. Μπορούν να θεωρηθούν σαν Web APIs, τα οποία μπορούν να προσπελαστούν μέσω ενός δικτύου όπως το Διαδίκτυο και να εκτελεστούν σε ένα απομακρυσμένο σύστημα, το οποίο φιλοξενεί τις συγκεκριμένες υπηρεσίες.

Θα περίμενε λοιπόν κάποιος ότι όλη αυτή η αφαίρεση (abstraction) θα οδηγούσε στην ανάπτυξη ασφαλέστερων εφαρμογών, ειδικά αν αναλογιστεί την πληθώρα των προτύπων ασφαλείας που είναι διαθέσιμα για την ανάπτυξη εφαρμογών (Σχήμα 1). Ενδεικτικά αναφέρουμε μερικά πρότυπα, αν και αυτή η λίστα σε καμιά περίπτωση δεν μπορεί να θεωρηθεί πλήρης. Για παράδειγμα, το πρότυπο WS-Security παρέχει «μια σειρά μηχανισμών για την υλοποίηση λειτουργιών ασφαλείας, όπως είναι η ακεραιότητα και η εμπιστευτικότητα μηνυμάτων που ανταλλάσσονται από εφαρμογές υπηρεσιών ιστού» [1]. Οι Υπηρεσίες Ψηφιακών Υπογραφών (Digital Security Services – DSS) περιλαμβάνουν τις κατάλληλες διεπαφές (interfaces) για την παραγωγή και την πιστοποίηση μιας υπογραφής από κάποιο web service, αλλά και τον έλεγχο ότι η υπογραφή δημιουργήθηκε σε συγκεκριμένο χρονικό διάστημα [2].

Το XML Encryption καθορίζει «διαδικασίες για την κρυπτογράφηση/ αποκρυπτογράφηση ψηφιακού περιεχομένου (συμπεριλαμβανομένων αρχείων XML και τμημάτων αυτών)» καθώς και ένα συντακτικό που μπορεί να χρησιμοποιηθεί για τον παραπάνω σκοπό [3]. Αντίστοιχα, το XML-Signature σκοπό έχει την «ανάπτυξη δομών XML που μπορούν να χρησιμοποιηθούν για την αναπαράσταση υπογραφών, αλλά και διαδικασίες υπολογισμού και ελέγχου τέτοιων υπογραφών» [4]. Άλλα πρότυπα περιλαμβάνουν τα Security Assertion Markup Language (SAML), eXtensible Access Control Markup Language (XACML), XML Key Management Specification (XKMS) κ.λπ.
Αν και όλα αυτά τα πρότυπα θα έπρεπε να κάνουν πιο εύκολη τη δημιουργία ασφαλών Web εφαρμογών και υπηρεσιών, εύκολα μπορεί κάποιος να χρησιμοποιήσει λάθος πρότυπο ή ένα πρότυπο που δεν καλύπτει τις ζητούμενες απαιτήσεις ασφάλειας. Όλα αυτά και ακόμη περισσότερα, ελπίζουμε να γίνουν κατανοητά με τη χρήση μερικών παραδειγμάτων.

Σκοπός των προτύπων
Ο κύριος ρόλος των προτύπων (ασφαλείας ή άλλων) είναι η επίτευξη της διαλειτουργικότητας μεταξύ διαφορετικών συστημάτων και προμηθευτών. Για παράδειγμα, όταν ένας χρήστης χρησιμοποιεί το Mozilla Firefox για να προσπελάσει μία σελίδα μέσω HTTPS, περιμένει ότι το ίδιο θα μπορεί να συμβεί ακόμα και αν χρησιμοποιήσει το Microsoft Explorer ή η εφαρμογή τρέξει σε κάποιο διαφορετικό server. Όσον αφορά όμως τα πρότυπα ασφαλείας, εκτός από τη διαλειτουργικότητα περιμένουμε να παρέχονται και κάποιες εγγυήσεις ασφαλείας. Για παράδειγμα, κάθε φορά που στέλνουμε δεδομένα στο διαδίκτυο μέσω του SSL/TLS πρωτοκόλλου, περιμένουμε ότι οι client και server έχουν πειστεί ο ένας για την ταυτότητα του άλλου (mutual authentication) και ότι κανείς δεν μπορεί να υποκλέψει τις μεταξύ τους επικοινωνίες. Δυστυχώς όμως, πολλά πρότυπα αφήνουν πολλές επιλογές στον εκάστοτε διαχειριστή συστημάτων, ακριβώς επειδή οι απαιτήσεις δεν είναι ίδιες για όλες τις επιχειρήσεις και τους οργανισμούς. Έτσι, αν και τα πρότυπα παρέχουν ένα κοινό πλαίσιο για την επίτευξη κάποιων στόχων ασφαλείας, ωστόσο πρέπει να περιμένουμε ότι η χρήση ενός προτύπου μόνο, δεν αρκεί για την ανάπτυξη ασφαλών εφαρμογών. Ας δούμε λοιπόν τι μπορεί να πάει στραβά στην πράξη.

Πόσο ασφαλές είναι το πρότυπο;
Υπάρχουν περιπτώσεις όπου το ίδιο το πρότυπο μπορεί να μην είναι ασφαλές. Ένα τυπικό παράδειγμα αποτελεί το Wired Equivalent Privacy (WEP) πρότυπο, που πρωτοεμφανίστηκε το 1999 για να ασφαλίσει ΙΕΕΕ 802.11 ασύρματα δίκτυα. Το WEP χρησιμοποιεί τον RC4 αλγόριθμο για κρυπτογράφηση και ένα απλό CRC έλεγχο για την ακεραιότητα των δεδομένων. Ο RC4 είναι ένας stream cipher, ο οποίος λειτουργεί επεκτείνοντας ένα μικρό κλειδί σε μια μεγάλη ψευδοτυχαία ακολουθία από bits (keystream). Ο αποστολέας κάνει XOR το keystream με το αρχικό μήνυμα (plaintext), για να παραγάγει το κρυπτογραφημένο κείμενο (ciphertext). Ο παραλήπτης, χρησιμοποιώντας την αντίστροφη διαδικασία αναπαράγει το αρχικό plaintext (Σχήμα 2). Δυστυχώς, αυτός ο τρόπος λειτουργίας καθιστά τον RC4 τρωτό σε διάφορες επιθέσεις. Εάν ένας επιτιθέμενος αλλάξει κάποια bits στο ciphertext, το αντίστοιχο κομμάτι στο plaintext θα αλλάξει και αυτό. Επίσης, εάν κάποιος αποκτήσει δύο ciphertexts που έχουν κρυπτογραφηθεί με το ίδιο keystream, μπορεί μέσω στατιστικής ανάλυσης να ανακτήσει και τα αρχικά plaintexts. Το WEP εφαρμόζει κάποιες γραμμές άμυνας ενάντια και στις δύο επιθέσεις. Για να εξασφαλίσει ότι ένα πακέτο δεν έχει τροποποιηθεί κατά τη μεταφορά, χρησιμοποιεί έναν απλό έλεγχο ακεραιότητας (CRC) στο πακέτο. Για να αποφευχθεί η δημιουργία δύο ciphertexts με το ίδιο keystream, χρησιμοποιεί μία τιμή αρχικοποίησης (Initialization Vector – IV) για την παραγωγή ενός διαφορετικού keystream για κάθε πακέτο.

Όμως, τα συγκεκριμένα μέτρα ασφαλείας δεν είναι αρκετά και, όπως αποδείχθηκε αμέσως μετά την εμφάνισή του, το πρωτόκολλο μπορεί να «σπάσει» εύκολα μέσα σε λίγα λεπτά από τη στιγμή που χρησιμοποιείται [5]. Δυστυχώς, παρ’ όλες τις αδυναμίες του, το WEP εξακολουθεί να χρησιμοποιείται ακόμη και σήμερα και να αποτελεί συχνά την πρώτη επιλογή που δίνεται σε ένα χρήστη ενός ασύρματου δικτύου. Το σκεπτικό «λίγη ασφάλεια είναι καλύτερη από καθόλου ασφάλεια» αποδεικνύεται λοιπόν εσφαλμένο, καθότι δημιουργεί μια ψευδή αίσθηση ασφάλειας, που μπορεί εύκολα να οδηγήσει στην παραβίαση της εμπιστευτικότητας των δεδομένων ενός χρήστη.
Ένα άλλο παράδειγμα λανθασμένου προτύπου αποτέλεσαν οι πρώτες εκδόσεις του SSL (χρησιμοποιούμε SSL όταν κάνουμε πληρωμές μέσω διαδικτύου), στις οποίες, ένα λάθος στη γεννήτρια τυχαίων αριθμών είχε σαν αποτέλεσμα να είναι προβλέψιμα τα κλειδιά που χρησιμοποιούνταν από τους αλγόριθμους κρυπτογράφησης των υπό μετάδοση δεδομένων.
Ο κύριος λόγος που συμβαίνουν αυτά τα λάθη είναι γιατί κάποιες φορές εκείνο που μας ενδιαφέρει είναι να βγει γρήγορα ένα προϊόν ή πρότυπο, για να προλάβει τις εξελίξεις στην αγορά, υπονομεύοντας όμως την ασφάλεια. Άλλος λόγος είναι η επίτευξη κάποιου κοινού επιπέδου ασφαλείας, όχι απαραίτητα του καλύτερου, καθότι κάτι τέτοιο θα απαιτούσε μεγάλο διαχειριστικό κόστος και επενδύσεις σε υποδομές. Για παράδειγμα, η χρήση passwords για πρόσβαση σε συστήματα, δεν είναι η καλύτερη – είναι όμως η πιο διαδεδομένη, καθότι τα ρίσκα είναι συγκεκριμένα και πιθανό να μη δικαιολογούν την επένδυση σε καλύτερες μεθόδους αυθεντικοποίησης. Άλλοι λόγοι μπορεί να περιλαμβάνουν τη δημιουργία προτύπων όταν η τεχνολογία δεν είναι ακόμα ώριμη ή το γεγονός ότι δεν είναι πάντα εύκολο να βρεις ανθρώπους με μια βαθύτερη κατανόηση και γνώση των προβλημάτων ασφάλειας. Έτσι, σχεδιάζονται πρωτόκολλα και πρότυπα, που δεν είναι πάντα 100% ασφαλή.

Χρησιμοποιώντας το πρότυπο με λάθος τρόπο
Ας εξετάσουμε τώρα την περίπτωση όπου κάποιος μπορεί να χρησιμοποιήσει ένα πρότυπο με λάθος ή ελλιπή τρόπο, για να επιτύχει κάποιο συγκεκριμένο στόχο όσον αφορά την ασφάλεια μιας εφαρμογής. Έστω λοιπόν ένα web service, στο οποίο μας ενδιαφέρει μόνο η αυθεντικότητα των μηνυμάτων. Η προφανής λύση είναι να χρησιμοποιηθούν XML υπογραφές. Για να γίνει όμως αυτό, κάθε οντότητα θα πρέπει να εξοπλιστεί με ένα δημόσιο (public) και ένα ιδιωτικό (private) κλειδί, με τα οποία θα γίνεται αντίστοιχα ο έλεγχος και η υπογραφή των μηνυμάτων. Πώς όμως κάποιος θα ξέρει ποιο δημόσιο κλειδί να χρησιμοποιήσει για να πιστοποιήσει μια υπογραφή; Η απλή λύση του να στέλνει κανείς μαζί με τα μηνύματα και το δημόσιο κλειδί του, είναι επιρρεπής σε επιθέσεις, στις οποίες ένας επιτιθέμενος μπορεί να τροποποιήσει το μήνυμα και να εισαγάγει το δικό του κλειδί, ώστε να πιστοποιούνται τα μηνύματα που στέλνονται από τον ίδιο.
Μία υποδομή δημόσιου κλειδιού (Public Key Infrastructure – PKI) θα έλυνε πολλά από τα παραπάνω προβλήματα, αλλά θα εισήγαγε νέα, όπως τη χρήση πιστοποιητικών (certificates) για κάθε δημόσιο κλειδί, την ύπαρξη αρχών πιστοποίησης κ.λπ. Ας υποθέσουμε λοιπόν ότι χρησιμοποιούμε πιστοποιητικά και ας δούμε τι μπορεί να πάει στραβά σε αυτήν την περίπτωση, με ένα απλό παράδειγμα. Έστω ότι χρησιμοποιούμε το πρωτόκολλο HTTPS για την ασφάλεια συναλλαγών μέσω του διαδικτύου. Αυτό σημαίνει ότι ο server πρέπει να έχει ένα εγκατεστημένο πιστοποιητικό, υπογεγραμμένο από κάποια αρχή, την οποία ένας client εμπιστεύεται. Συνήθως αυτό είναι ένα πιστοποιητικό από μία εμπορική αρχή πιστοποίησης, όπως η Verisign, αλλά θα μπορούσε να είναι και ένα self-signed πιστοποιητικό για λόγους οικονομίας. Το αποτέλεσμα είναι ότι όταν ένας χρήστης συνδέεται με κάποιο browser, βλέπει ένα παράθυρο σαν αυτό που φαίνεται στο Σχήμα 3.
Το απλούστερο σε αυτήν την περίπτωση είναι να δοθεί σε ένα χρήστη η οδηγία «απλά πιέστε ΟΚ». Αλλά, αν ο χρήστης πάντα ακολουθεί αυτήν τη συμβουλή, πώς θα μπορέσει να αντιληφθεί μία επίθεση και να ξεχωρίσει ένα πλαστό από ένα αυθεντικό site; Ακόμα και αν ο χρήστης προσπαθήσει να εξετάσει το πιστοποιητικό, θα πρέπει να ξέρει ακριβώς τι γυρεύει, κάτι που ένας μέσος χρήστης δεν μπορεί ή δεν χρειάζεται να γνωρίζει.

Το πρότυπο τα κάνει όλα;
Η προηγούμενη συζήτηση έδειξε ότι είναι σχετικά εύκολο να υποθέσει κανείς ότι τα πρότυπα παρέχουν ορισμένες ιδιότητες ασφάλειας, οι οποίες όμως δεν επιτυγχάνονται πάντα με εύκολο τρόπο. Εξίσου εύκολο είναι να αγνοηθούν εντελώς οι στόχοι ασφάλειας, που δεν καλύπτονται από το πρότυπο. Για παράδειγμα, μπορεί να είναι γνωστό σε κάποιους ότι το πρότυπο XMLEncrypt πρέπει να συνδυάζεται με άλλες τεχνολογίες, όπως η αυθεντικοποίηση δεδομένων (authentication) για μεγαλύτερη ασφάλεια, αλλά επειδή οι περισσότεροι σχεδιαστές συστημάτων δεν είναι κατ’ ανάγκη και ειδικοί σε θέματα ασφάλειας, πιθανώς να μην ξέρουν τι προβλήματα θα δημιουργηθούν, χρησιμοποιώντας το πρότυπο από μόνο του. Επίσης, όλα τα WS-πρότυπα δίνουν έμφαση στην προστασία των δεδομένων κατά τη μεταφορά τους στο διαδίκτυο, αγνοώντας όμως την προστασία των δεδομένων ενώ αυτά φυλάσσονται σε ένα σύστημα ή βάση δεδομένων.
Ας δούμε τι μπορεί να πάει στραβά με ένα ακόμη παράδειγμα [6]. Φανταστείτε μία υπηρεσία Ιστού, που επιτρέπει στους χρήστες να κάνουν ερωτήσεις σε μια βάση δεδομένων (σχήμα 4). Για μεγαλύτερη ασφάλεια απαιτούμε το αίτημα πρόσβασης στη βάση δεδομένων να υπογράφεται και να κρυπτογραφείται κατά XML. Πριν την εκτέλεση της εντολής, το Web service θα αποκρυπτογραφήσει τα δεδομένα και θα επικυρώσει την υπογραφή για να σιγουρευτεί ότι δεν τροποποιήθηκαν και ότι προέρχονται από έναν εξουσιοδοτημένο χρήστη. Παρέχει όμως αυτή η αρχιτεκτονική, τις απαιτούμενες εγγυήσεις ασφάλειας;
Καταρχήν, το Web Service μπορεί να ελέγξει την υπογραφή, αλλά να μην επικυρώσει ότι πρέπει να εμπιστευθεί τον υπογράφοντα του αιτήματος. Η εμπιστοσύνη εξαρτάται όχι μόνο από ποιος εξέδωσε το πιστοποιητικό που χρησιμοποιήθηκε για να υπογράψει το αίτημα, αλλά και από ποιον αντιπροσωπεύει το πιστοποιητικό και πόσο καλά προστατεύεται το κλειδί που χρησιμοποιείται για τις υπογραφές. Είναι κοινό λάθος να ελέγχεται μόνο η υπογραφή χωρίς επικύρωση των στοιχείων του πιστοποιητικού, με αποτέλεσμα το Web Service να δεχτεί να ικανοποιήσει ένα αίτημα από κάποιον που δεν πρέπει.
Ακόμα όμως και αν όλα τα παραπάνω ικανοποιούνται, τι εμποδίζει έναν κακόβουλο χρήστη να δώσει μια εντολή που θα διαγράψει όλα τα δεδομένα από τη Βάση Δεδομένων; Αφού το Web Service απλά ελέγξει την υπογραφή, στη συνέχεια θα προωθήσει την εντολή για εκτέλεση. Αν αυτή η εντολή περιλαμβάνει το σβήσιμο όλων των στοιχείων της βάσης, τότε κανένας έλεγχος και καμιά υπογραφή δεν θα εμποδίσουν κάτι τέτοιο. Βέβαια, κάποιος θα μπορούσε να περιορίσει τον τύπο των εντολών/ αιτημάτων που μπορούν να δοθούν από τους χρήστες, αλλά πάλι ποιος θα εμπόδιζε ένα χρήστη να δώσει μία περίεργη ακολουθία χαρακτήρων, που θα είχε πάλι το ίδιο αποτέλεσμα (τέτοιου είδους επιθέσεις είναι γνωστές σαν SQL-Injection attacks [7]).

Συμπέρασμα
Η προηγούμενη συζήτηση φανερώνει ότι η δημιουργία ασφαλών WEB υπηρεσιών δεν είναι εύκολη υπόθεση και συχνά απαιτεί σωστές πρακτικές κατά το σχεδιασμό αλλά και την υλοποίηση των υπηρεσιών αυτών. Ενδεικτικά αναφέρουμε μερικά από τα βήματα που πρέπει να ακολουθούνται κατά το σχεδιασμό εφαρμογών ασφαλείας:

  • Συγκεκριμενοποίηση απαιτήσεων εφαρμογής και των στόχων ασφαλείας.
  • Μοντελοποίηση απειλών.
  • Σχεδιασμός.
  • Επαλήθευση στόχων και έλεγχος.
  • Αναθεώρηση αρχιτεκτονικής και ασφάλειας.
  • Αναθεώρηση κώδικα.
  • κ.ο.κ.

Έτσι, πέρα από τη χρήση διαφόρων προτύπων που παρέχουν κάποιο βασικό επίπεδο ασφάλειας, ο καλύτερος τρόπος για τη διαφύλαξη της ασφάλειας των εφαρμογών είναι η χρήση σωστών πρακτικών κατά την ανάπτυξη των εφαρμογών. Αυτό όμως θα είναι το αντικείμενο κάποιου επόμενου άρθρου.

Του Τάσου Δημητρίου

Αναφορές
[1] http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=wss
[2] http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=dss
[3] http://www.w3.org/Encryption
[4] http://www.w3.org/Signature
[5] Nikita Borisov, Ian Goldberg and David Wagner, “Intercepting Mobile Communications: The Insecurity of 802.11”, in 7th Annual International Conference on Mobile Computing and Networking, 2001
[6] John Viega, Jeremy Epstein, ΙΕΕΕ Security & Privacy, Volume 4, Issue 4, July-Aug. 2006 Page(s): 25 – 31
[7] http://en.wikipedia.org/wiki/SQL_injection