Δημιουργία ενός ασφαλούς, αποτελεσματικού sandbox για την ενεργοποίηση του Codex στα Windows
Από τον David Wiesen, μέλος του Τεχνικού Επιτελείου
Όταν εντάχθηκα στην ομάδα μηχανικής του Codex τον Σεπτέμβριο του 2025, το Codex για Windows δεν διέθετε υλοποίηση sandbox, πράγμα που σήμαινε ότι οι χρήστες Windows αναγκάζονταν να επιλέξουν ανάμεσα σε δύο υποδεέστερες επιλογές όταν χρησιμοποιούσαν τους πράκτορες προγραμματισμού της OpenAI:
- Να εγκρίνουν σχεδόν κάθε εντολή (ακόμα και αναγνώσεις) που ήθελε να εκτελέσει ένας πράκτορας προγραμματισμού, κάτι αναποτελεσματικό και ενοχλητικό. Ένα σημαντικό πλεονέκτημα της χρήσης του Codex είναι ότι δεν χρειάζεται να κάνετε μόνοι σας όλη την κουραστική δουλειά.
- Να ενεργοποιήσουν τη λειτουργία Full Access: να αφήσουν το Codex να εκτελεί όλες τις εντολές χωρίς έγκριση ή περιορισμούς, κάτι που αφαιρεί την τριβή εις βάρος της εποπτείας.
ΤοCodex, ο πράκτορας προγραμματισμού μας, εκτελείται σε φορητούς υπολογιστές προγραμματιστών — μέσω του CLI, της επέκτασης IDE ή της εφαρμογής desktop. Διαχειρίζεται μια συνομιλία μεταξύ ενός ανθρώπου στο πληκτρολόγιο και ενός μοντέλου που εκτελείται στο cloud για την εξαγωγή συμπερασμάτων.
Το Codex εκτελείται από προεπιλογή με τα δικαιώματα ενός πραγματικού χρήστη, πράγμα που σημαίνει ότι μπορεί να κάνει ό,τι μπορεί να κάνει και ο χρήστης. Αυτό είναι ισχυρό και δυνητικά επικίνδυνο. Το μοντέλο προγραμματισμού μπορεί να πει στο harness να εκτελέσει εντολές τοπικά, από την εκτέλεση δοκιμών μέχρι την ανάγνωση ή επεξεργασία ενός αρχείου ή τη δημιουργία ενός κλάδου Git, οπότε η προεπιλεγμένη λειτουργία του Codex προσπαθεί να βρει τη σωστή ισορροπία ανάμεσα στην αποτελεσματικότητα και την ασφάλεια. Αυτή η προεπιλεγμένη λειτουργία επιτρέπει στο Codex να διαβάζει αρχεία σχεδόν οπουδήποτε και να γράφει αρχεία μέσα στον χώρο εργασίας σας (δηλαδή, στον κατάλογο όπου εκτελείτε το Codex), χωρίς πρόσβαση στο internet εκτός αν δηλώσετε ότι τη θέλετε. Για να επιτευχθεί αυτός ο αυτόματος περιορισμός της εγγραφής αρχείων και της πρόσβασης στο δίκτυο εντός ασφαλών ορίων, το Codex χρειάζεται ένα περιβάλλον sandbox που να επιβάλλει πραγματικά αυτούς τους περιορισμούς.
Ένα sandbox είναι ένα περιορισμένο περιβάλλον εκτέλεσης. Όταν ένας προγραμματιστής χρησιμοποιεί το Codex, το λειτουργικό σύστημα του υπολογιστή του εκκινεί μια εντολή με μειωμένα δικαιώματα και αυτοί οι περιορισμοί μεταδίδονται σε όλο το δέντρο διεργασιών. Κάθε εντολή του Codex είναι απομονωμένη σε sandbox εξαρχής, και κάθε διεργασία-απόγονος παραμένει εντός του ίδιου ορίου.
Το Codex χρειάζεται δυνατότητες απομόνωσης που επιβάλλονται από το λειτουργικό σύστημα του υπολογιστή για να υλοποιήσει ένα αποτελεσματικό sandbox. Ορισμένα λειτουργικά συστήματα παρέχουν βοηθητικά εργαλεία που το κάνουν αυτό καλά (π.χ. Seatbelt στο MacOs, seccomp ή bubblewrap στο Linux). Ωστόσο, τα Windows προς το παρόν δεν παρέχουν αυτού του είδους τη δυνατότητα έτοιμη προς χρήση.
Για να κάνουμε το Codex εξίσου ασφαλές και ευχάριστο στη χρήση στα Windows όσο είναι ήδη οπουδήποτε αλλού, έπρεπε να υλοποιήσουμε το δικό μας sandbox.
Τα Windows προσφέρουν ορισμένα εργαλεία και βασικούς μηχανισμούς για απομόνωση. Παρότι κανένα τους δεν κάλυπτε ακριβώς τις απαιτήσεις μας, εξετάσαμε αρκετές πιθανές λύσεις — συγκεκριμένα τα AppContainer, Windows Sandbox και την επισήμανση Mandatory Integrity Control.
AppContainer
- Τι είναι: Το AppContainer είναι το εγγενές sandbox των Windows, ένα μοντέλο απομόνωσης βασισμένο σε δυνατότητες και σχεδιασμένο για εφαρμογές που γνωρίζουν εκ των προτέρων ακριβώς σε τι πρέπει να έχουν πρόσβαση.
- Γιατί: Είναι καλή λύση, επειδή προσφέρει ένα πραγματικό όριο λειτουργικού συστήματος αντί για περιορισμούς βέλτιστης προσπάθειας.
- Γιατί όχι: Το Codex δεν είναι μία εφαρμογή με αυστηρά οριοθετημένο εύρος. Υποστηρίζει ροές εργασίας ανάπτυξης ανοικτού τύπου: κελύφη, Git, Python, διαχειριστές πακέτων, εργαλεία build και οποιαδήποτε άλλα εκτελέσιμα δυαδικά αρχεία αποφασίσει ο πράκτορας ότι χρειάζεται. Στην πράξη, αυτό κατέστησε το AppContainer ακατάλληλο για το συγκεκριμένο πρόβλημα. Επρόκειτο για ισχυρή απομόνωση, αλλά για μια πολύ στενότερη κατηγορία φόρτων εργασίας από το «να αφήνεις έναν πράκτορα να λειτουργεί σαν προγραμματιστής».
Windows Sandbox
- Τι είναι: Το Windows Sandbox είναι η ελαφριά εικονική μηχανή μίας χρήσης της Microsoft. Έχετε μια φρέσκια επιφάνεια εργασίας Windows με ισχυρό όριο απομόνωσης, και ό,τι κάνετε μέσα της εξαφανίζεται όταν τελειώσει η συνεδρία.
- Γιατί: Έχει ενδιαφέρον για προφανείς λόγους — είναι πολύ πιο συμβατό με αυθαίρετο λογισμικό από το AppContainer, και από πλευράς ασφάλειας προσφέρει ένα πολύ ισχυρότερο πλαίσιο.
- Γιατί όχι: Το Codex πρέπει να δρα απευθείας πάνω στο πραγματικό checkout, τα εργαλεία και το περιβάλλον του χρήστη, όχι μέσα σε μια ξεχωριστή, προσωρινή επιφάνεια εργασίας που θα απαιτούσε ρύθμιση και γεφύρωση host/guest. Έχει, επίσης, ένα θεμελιώδες πρόβλημα σε επίπεδο προϊόντος: το Windows Sandbox δεν είναι καν διαθέσιμο στα SKU των Windows Home.
Επισήμανση ακεραιότητας Mandatory Integrity Control (MIC)
- Τι είναι: Τα Windows διαθέτουν μια έννοια που ονομάζεται «επίπεδα ακεραιότητας», όπως χαμηλό, μεσαίο και υψηλό, τα οποία καθορίζουν πόσο εμπιστεύεται το σύστημα τα αντικείμενα και τις διεργασίες. Ο βασικός κανόνας είναι ότι μια διεργασία με χαμηλότερο επίπεδο ακεραιότητας δεν μπορεί να γράψει σε ένα αντικείμενο με υψηλότερο επίπεδο ακεραιότητας, ακόμη και αν η κανονική λίστα ελέγχου πρόσβασης (ACL) θα το επέτρεπε υπό άλλες συνθήκες. Για παράδειγμα, μια διεργασία χαμηλής ακεραιότητας αντιμετωπίζεται ως λιγότερο αξιόπιστη, επομένως τα Windows την εμποδίζουν να γράφει σε κανονικά αντικείμενα μεσαίας ακεραιότητας, εκτός εάν αυτά τα αντικείμενα επανασημανθούν ρητά ώστε να το επιτρέπουν.
- Γιατί: Το MIC έμοιαζε ωραία λύση στη θεωρία — να εκτελείται το Codex σε χαμηλή ακεραιότητα, να επαναεπισημαίνονται τα εγγράψιμα root ως χαμηλής ακεραιότητας και να αφήνουμε τα Windows να επιβάλλουν απαγόρευση εγγραφών οπουδήποτε αλλού. Αυτό θα μας έδινε μια οδό χωρίς δικαιώματα διαχειριστή, με έναν πραγματικό μηχανισμό του λειτουργικού συστήματος να την υποστηρίζει.
- Γιατί όχι: Όπως και οι ACL, οι ετικέτες ακεραιότητας τροποποιούν το πραγματικό σύστημα αρχείων του κεντρικού υπολογιστή και, σε αυτήν την περίπτωση, η σημασιολογική αλλαγή είναι ιδιαίτερα εκτεταμένη. Η επισήμανση ενός χώρου εργασίας ως χαμηλής ακεραιότητας δεν σημαίνει απλώς ότι «το Codex μπορεί να γράφει εδώ». Σημαίνει ότι οι διεργασίες χαμηλής ακεραιότητας γενικά μπορούν να πραγματοποιούν εγγραφή εκεί. Σε ένα πραγματικό μηχάνημα προγραμματιστή, αυτό μετατρέπει το πραγματικό checkout του χρήστη σε αποδέκτη χαμηλής ακεραιότητας για τον host, κάτι που είναι πολύ πιο επικίνδυνο από την παραχώρηση προσεκτικά στοχευμένων λιστών ελέγχου πρόσβασης (ACL) σε μία σχεδίαση sandbox. Ακόμη κι αν τα εργαλεία προγραμματιστών μέσης ακεραιότητας συνεχίσουν να λειτουργούν, το υποκείμενο μοντέλο εμπιστοσύνης του χώρου εργασίας έχει αλλάξει με τρόπο που είναι δύσκολο να περιοριστεί και ακόμη δυσκολότερο να δικαιολογηθεί.
Αφού αξιολογήσαμε όλες τις επιλογές ως αδιέξοδες, αρχίσαμε να σχεδιάζουμε τη δική μας λύση για να προσφέρουμε μια καλή εμπειρία Codex στους χρήστες Windows.
Το πρώτο λειτουργικό μας πρωτότυπο χρησιμοποίησε έναν συνδυασμό εννοιών και εργαλείων των Windows για να υλοποιήσει την απομόνωση που χρειαζόμασταν. Από την αρχή, ένας στόχος ήταν να λειτουργεί χωρίς να απαιτούνται αυξημένα δικαιώματα, δηλαδή χωρίς το Codex να χρειάζεται να ζητά από τον χρήστη δικαιώματα διαχειριστή μόνο και μόνο για να ρυθμίσει ή να εκτελέσει το sandbox. Αυτό σήμαινε ότι έπρεπε να βρούμε πώς να θέσουμε λογικά όρια σε δύο πράγματα: τις εγγραφές αρχείων και την πρόσβαση στο δίκτυο.
Αν δεν περιορίζαμε καθόλου τις εγγραφές αρχείων, θα είχαμε πρόβλημα ασφάλειας. Αν τις περιορίζαμε υπερβολικά, το sandbox θα έβλαπτε την παραγωγικότητα του χρήστη, ζητώντας διαρκώς έγκριση. Για να λύσουμε αυτό το πρόβλημα, βασιστήκαμε σε δύο σημαντικά δομικά στοιχεία των Windows: τα SID και τα token με περιορισμό εγγραφής.
Ένα SID, ή αναγνωριστικό ασφαλείας, είναι η ταυτότητα στην οποία τα Windows αποδίδουν δικαιώματα. Κάθε χρήστης έχει ένα SID, οι ομάδες έχουν πολλά SID, και ακόμη και μια μεμονωμένη συνεδρία σύνδεσης έχει το δικό της SID. Για παράδειγμα, μια τρέχουσα συνδεδεμένη συνεδρία μπορεί να έχει ένα SID όπως S-1-5-5-X-Y. Το SID που έχει εκχωρηθεί στην ομάδα τοπικών διαχειριστών ενδέχεται να είναι το S-1-5-32-544.
Τα Windows σάς επιτρέπουν επίσης να δημιουργείτε συνθετικά SID που δεν αντιστοιχούν σε πραγματικό χρήστη αλλά μπορούν παρ’ όλα αυτά να εμφανίζονται σε ACL (λίστες ελέγχου πρόσβασης), τα οποία ορίζουν ποιος μπορεί να διαβάζει/γράφει/εκτελεί συγκεκριμένα αρχεία ή καταλόγους. Αυτό κάνει τα SID ένα χρήσιμο βασικό μηχανισμό για το sandbox μας: μπορούμε να δημιουργήσουμε SID αποκλειστικά για χρήση από το sandbox του Codex, χωρίς να παρεμβαίνουμε σε οτιδήποτε άλλο στο μηχάνημα.
Τα token επεξεργασίας είναι αντικείμενα ασφάλειας στα Windows που ορίζουν ταυτότητα και δικαιώματα για μια εκτελούμενη διεργασία. Καθορίζουν ποιες ενέργειες μπορεί να εκτελέσει μια διεργασία. Ένα token με περιορισμό εγγραφής είναι ένας συγκεκριμένος τύπος token επεξεργασίας που κάνει τα Windows να εκτελούν έναν επιπλέον έλεγχο πρόσβασης σε πράξεις εγγραφής.
Για να πετύχει μια εγγραφή, πρέπει να περάσουν δύο έλεγχοι:
- Η κανονική ταυτότητα χρήστη (ο «κάτοχος» του token) πρέπει να επιτρέπεται να το κάνει
- Τουλάχιστον ένα SID στη λίστα περιορισμένων SID του token πρέπει επίσης να έχει πρόσβαση
Στην πράξη, αυτοί οι έλεγχοι μάς επέτρεψαν να χρησιμοποιήσουμε ACL για να ορίσουμε ακριβώς πού θα μπορούσε το sandbox να τροποποιεί το σύστημα αρχείων, προσφέροντας τη λεπτομέρεια που χρειαζόμασταν γύρω από τις πράξεις εγγραφής.
Με SID και token με περιορισμό εγγραφής, το sandbox μας χωρίς αυξημένα δικαιώματα λειτουργούσε ως εξής:
- Η ρύθμιση του sandbox δημιουργούσε ένα συνθετικό SID με όνομα
sandbox-write. - Στο SID
sandbox-writeεκχωρήθηκε πρόσβαση εγγραφής, εκτέλεσης και διαγραφής:- Στον τρέχοντα κατάλογο εργασίας
- Σε τυχόν πρόσθετα
writable_rootsπου έχουν διαμορφωθεί στοconfig.toml.
- Η ρύθμιση του sandbox απαγόρευε ρητά στο ίδιο SID πρόσβαση εγγραφής σε τοποθεσίες «μόνο για ανάγνωση μέσα σε εγγράψιμες», όπως:
<cwd>/.git<cwd>/.codex<cwd>/.agents
- Το Codex εκκινούσε εντολές κάτω από ένα token με περιορισμό εγγραφής του οποίου η λίστα περιορισμένων SID περιλαμβάνει τα
Everyone, το SID της τρέχουσας συνδεδεμένης συνεδρίας και το συνθετικό SIDsandbox-write.
Αυτή η ροή έλυνε αποτελεσματικά τον περιορισμό των εγγραφών αρχείων και φαινόταν πολλά υποσχόμενη. Τώρα, χρειαζόμασταν μια λύση για τον περιορισμό της πρόσβασης του sandbox στο δίκτυο.
Ο περιορισμός της πρόσβασης στο δίκτυο είναι σημαντικό μέρος του sandbox. Χωρίς αυτόν, κακόβουλος κώδικας θα μπορούσε να αποσπά δεδομένα από το μηχάνημα προς το Internet. Επειδή θέλαμε να αποφύγουμε την απαίτηση αυξημένων δικαιωμάτων, είχαμε περιορισμένες επιλογές για να μπλοκάρουμε ισχυρά την κίνηση δικτύου. Τα εργαλεία που θέλαμε να χρησιμοποιήσουμε, όπως το Windows Firewall, γενικά δεν μπορούσαν να εγκατασταθούν χωρίς δικαιώματα διαχειριστή.
Χωρίς το Τείχος Προστασίας των Windows ως επιλογή, περιορίστηκε και το τι μπορούσαμε να ελέγξουμε. Προσπαθήσαμε να κάνουμε το θυγατρικό περιβάλλον να αποτυγχάνει με fail-closed τρόπο για τα είδη δικτυωμένων εργαλείων που χρησιμοποιούν πραγματικά οι προγραμματιστές, ώστε οι εντολές Git, οι εγκαταστάτες πακέτων κ.λπ. να αποτυγχάνουν μέσα στο sandbox και ο χρήστης να πρέπει να εγκρίνει οποιεσδήποτε λειτουργίες που βλέπουν προς το Internet. Η ιδέα ήταν να δηλητηριάσουμε τις προφανείς οδούς διαφυγής: να στέλνουμε την κίνηση που γνωρίζει από proxy σε ένα νεκρό τελικό σημείο, να κάνουμε το HTTP(S) transport του Git να κάνει το ίδιο και να κάνουμε το Git over SSH να αποτυγχάνει αμέσως. Επιπλέον, προσθέσαμε στην αρχή του PATH έναν μικρό κατάλογο denybin και αναδιατάξαμε το PATHEXT, ώστε τα stub script για SSH και SCP να επιλύονται πριν από τα πραγματικά εκτελέσιμα αρχεία.
Για παράδειγμα, εδώ είναι μερικές από τις συγκεκριμένες παρακάμψεις περιβάλλοντος που χρησιμοποιήσαμε για να περιορίσουμε την πρόσβαση στο δίκτυο:
HTTPS_PROXY=http://127.0.0.1:9ALL_PROXY=http://127.0.0.1:9GIT_HTTPS_PROXY=http://127.0.0.1:9NO_PROXY=localhost,127.0.0.1,::1GIT_SSH_COMMAND=cmd /c exit 1
Αυτό απέτρεπε μεγάλο μέρος της κανονικής, εργαλειοκαθοδηγούμενης κίνησης, αλλά παρέμενε μόνο συμβουλευτικό. Μια διεργασία μπορούσε να αγνοήσει το περιβάλλον, να παρακάμψει το PATH ή απλώς να ανοίξει απευθείας socket — κάτι υπερβολικά ριψοκίνδυνο.
Όπως κάθε ενδιαφέρουσα υλοποίηση λογισμικού, το πρώτο πρωτότυπο είχε ορισμένα πλεονεκτήματα και μειονεκτήματα. Παρότι έκανε τη δουλειά χρησιμοποιώντας μόνο λίγες τυπικές δυνατότητες των Windows, επέτρεπε πολύ ρητές και λεπτομερείς εγγραφές στο σύστημα αρχείων και εκτελούνταν χωρίς αυξημένα δικαιώματα —μειώνοντας την ανάγκη οι χρήστες να αποδέχονται υπερβολικά πολλές προτροπές ανύψωσης ή να είναι διαχειριστές στο τοπικό τους μηχάνημα— είχε ορισμένα πραγματικά μειονεκτήματα για να αποτελέσει τον τελικό μας σχεδιασμό:
- Ταχύτητα ρύθμισης: Η εφαρμογή ACL στον χώρο εργασίας μπορεί να είναι δαπανηρή ανάλογα με την τοπολογία του καταλόγου του χώρου εργασίας.
- Αποτύπωμα: Εφαρμόσαμε πραγματικά ACL στο σύστημα του προγραμματιστή, αν και το αποτύπωμα δεν είναι ιδιαίτερα επεμβατικό, επειδή όλα τα εφαρμοσμένα ACL αφορούν ένα συνθετικό SID που δημιουργείται ειδικά και χρησιμοποιείται μόνο από το sandbox.
- Σημασιολογία που αλλάζει δύσκολα: Η εξάρτηση από ACL για περιορισμούς βασισμένους σε αρχεία σημαίνει ότι είναι ακριβό και περίπλοκο να αλλάξει η σημασιολογία του sandbox. Ενώ στο macOS μπορούμε να αλλάζουμε δυναμικά τον τρόπο με τον οποίο δημιουργούμε το αρχείο
.sbplπου χρησιμοποιείται για τη διαμόρφωση του Seatbelt, το sandbox των Windows μπορεί να απαιτεί αργή και εντατική λειτουργία για την προσαρμογή των ACL. - Η προστασία δικτύου είναι αδύναμη. Όπως αναφέρθηκε προηγουμένως, ήταν «συμβουλευτική», θα παρακαμπτόταν σίγουρα από ορισμένα προγράμματα που υλοποιούσαν τη δική τους στοίβα δικτύωσης και δεν είχε σχεδιαστεί για να αντέχει σε αντίπαλο κώδικα.
Τα πρώτα τρία ζητήματα είναι εγγενή σε μια προσαρμοσμένη υλοποίηση sandbox που είναι αρκετά ευέλικτη για ροές με πράκτορα. Η υπόθεση της καταστολής δικτύου, ωστόσο, ήταν διαφορετική.
Πέρα από το ότι ένας κακόβουλος πράκτορας θα μπορούσε εύκολα να παρακάμψει την καταστολή δικτύου που βασιζόταν στο περιβάλλον, άφθονος καλοπροαίρετος κώδικας ή/ και δυαδικά θα την παρέκαμπταν επίσης απλώς, αν δεν τηρούσαν τις μεταβλητές proxy περιβάλλοντος ή αν υλοποιούσαν τον δικό τους κώδικα δικτύωσης βασισμένο σε socket. Θεωρήσαμε ότι αυτή η πτυχή από μόνη της αρκούσε για να επενδύσουμε σε μια καλύτερη λειτουργία sandbox.
Για να πετύχουμε καλύτερη καταστολή δικτύου, θέλαμε να χρησιμοποιήσουμε το Windows Firewall, το οποίο μας επιτρέπει να μπλοκάρουμε εξερχόμενη κίνηση δικτύου για χρήστες ή προγράμματα. Δυστυχώς, δεν μπορούσαμε να δημιουργήσουμε αποτελεσματικά έναν λειτουργικό κανόνα firewall που να εφαρμόζεται μόνο στις εντολές που ξεκινούσε το harness του Codex για μερικούς λόγους:
- Τα Windows δεν επιτρέπουν αντιστοίχιση κανόνα firewall στη μη κύρια ταυτότητα ενός token με περιορισμό. Αυτό σημαίνει ότι δεν μπορούσαμε να εφαρμόσουμε κανόνα firewall σε «οποιοδήποτε token περιλαμβάνει το συνθετικό μας SID στη λίστα περιορισμένων SID του».
- Παρότι θα μπορούσαμε να δημιουργήσουμε κανόνα firewall που να αντιστοιχεί σε ένα συγκεκριμένο δυαδικό, αυτό μας επιτρέπει μόνο να περιορίσουμε τη δικτύωση για το ίδιο το
codex.exe. Δεν θα εφαρμοζόταν στις διεργασίες που ξεκινά ο πράκτορας για λογαριασμό του χρήστη, όπως διεργασίες Git ή Python. - Και άλλες διαστάσεις αντιστοίχισης του firewall ήταν επίσης ακατάλληλες. Οι κανόνες με εύρος χρήστη εξακολουθούσαν να αντιστοιχούν στον πραγματικό χρήστη των Windows στο σχέδιο χωρίς αυξημένα δικαιώματα, όχι μόνο στην περιορισμένη θυγατρική διεργασία. Οι κανόνες διαδρομής προγράμματος ήταν υπερβολικά γενικοί: μπορούσαν να αποκλείσουν το
codex.exeή τοpython.exeγενικά, αλλά όχι τη συγκεκριμένη εκτέλεση τουpython.exeσε sandbox. Οι κανόνες βάσει θύρας ή διεύθυνσης ήταν επίσης εντελώς λανθασμένη πολιτική. Για παράδειγμα, δεν θέλαμε να μπλοκάρουμε τη θύρα 443. Θέλαμε να μπλοκάρουμε αυθαίρετη εξερχόμενη πρόσβαση για αυτό το συγκεκριμένο δέντρο περιορισμένων διεργασιών.
Για να εφαρμόσουμε έναν κανόνα firewall ειδικά στις sandboxed εντολές μας, έπρεπε να τις εκτελούμε ως ξεχωριστή κύρια ταυτότητα και όχι ως τον «πραγματικό» χρήστη. Αυτή η προσέγγιση μάς οδήγησε σε μια νέα κατεύθυνση, στην οποία χαλαρώσαμε τον περιορισμό μας «χωρίς αυξημένα δικαιώματα».
Η επόμενη έκδοση του sandbox, δηλαδή του περιβάλλοντος απομόνωσης που αποτελεί την τρέχουσα υλοποίησή μας, απαιτεί αυξημένα δικαιώματα διαχειριστή κατά τη ρύθμιση. Γι’ αυτό το αποκαλώ «το περιβάλλον απομόνωσης με αυξημένα δικαιώματα». Στο όριο όπου το Codex εκκινεί μια εντολή στο σύστημα, το sandbox με αυξημένα δικαιώματα μοιάζει με εκείνο χωρίς αυξημένα δικαιώματα. Εξακολουθεί να εκτελεί θυγατρικές διεργασίες υπό ένα περιορισμένο token—παρομοίως, ένα token write_restricted με την ίδια περιορισμένη λίστα SID των [Everyone, Logon, Synthetic]—ωστόσο, η κύρια οντότητα αυτού του token δεν είναι πλέον ο πραγματικός χρήστης των Windows, αλλά ένας από τους δύο τοπικούς χρήστες που δημιουργήθηκαν από το ίδιο το Codex:
CodexSandboxOffline(εκείνος στον οποίο στοχεύουν οι κανόνες firewall)CodexSandboxOnline(εκείνος στον οποίο δεν στοχεύουν οι κανόνες firewall)
Αυτή η φαινομενικά μικρή λεπτομέρεια έχει στην πραγματικότητα μεγάλες επιπτώσεις για το sandbox, για το ποιος μπορεί να το χρησιμοποιήσει και για την πολυπλοκότητα της ρύθμισης και της εκτέλεσής του κατά τον χρόνο λειτουργίας.
Οπτικά είναι παρόμοιο με το πρωτότυπο χωρίς αυξημένα δικαιώματα, με την εισαγωγή κανόνων firewall και ενός αποκλειστικού χρήστη Windows, ο οποίος εκτελεί πράγματι τις εντολές. (Ωστόσο, η εισαγωγή αυτών των νέων εννοιών σημαίνει ότι υπάρχει περισσότερη εργασία ρύθμισης πριν το sandbox μπορέσει να αρχίσει να εκτελεί και να προστατεύει εντολές.)
Ο σχεδιασμός του sandbox χωρίς αυξημένα δικαιώματα είχε ένα απλό βήμα ρύθμισης, αλλά ήταν σχετικά μικρό:
- Δημιουργία ενός συνθετικού SID, αν χρειάζεται
- Εφαρμογή ACL για το συνθετικό SID sandbox-write
Το sandbox με αυξημένα δικαιώματα, όμως, έχει περισσότερα να κάνει.
- Δημιουργία ενός συνθετικού SID, αν δεν έχει ήδη δημιουργηθεί
- Δημιουργία των online και offline χρηστών sandbox, αν δεν έχουν ήδη δημιουργηθεί
- Αποθήκευση τοπικά των διαπιστευτηρίων των νεοδημιουργημένων χρηστών και κρυπτογράφησή τους με το Windows Data Protection API (DPAPI) σε σημείο όπου οι χρήστες sandbox δεν μπορούν πραγματικά να διαβάσουν
- Δημιουργία κανόνων firewall που μπλοκάρουν κάθε εξερχόμενη πρόσβαση δικτύου για τον χρήστη
CodexSandboxOfflineή, αν υπάρχουν ήδη, επικύρωση ότι είναι σωστοί
Υπάρχει μια επιπλέον περιπλοκή στο στάδιο της ρύθμισης. Το περιβάλλον απομόνωσης του Codex αναμένεται να έχει πρόσβαση ανάγνωσης ισοδύναμη με εκείνη του πραγματικού χρήστη των Windows. Στο sandbox χωρίς αυξημένα δικαιώματα, όπου το SID της κύριας ταυτότητας του περιορισμένου token ήταν ο χρήστης Windows, αυτό επιτυγχανόταν. Ωστόσο, δεν γίνεται χωρίς κόστος όταν η κύρια οντότητα γίνεται νέος χρήστης του CodexSandbox. Πολλοί σχετικοί κατάλογοι στα Windows εκχωρούν δικαιώματα ανάγνωσης/εκτέλεσης στους «Χρήστες με έλεγχο ταυτότητας». Ένα χαρακτηριστικό παράδειγμα είναι ο κατάλογος προφίλ του χρήστη. Από προεπιλογή, οι χρήστες των Windows δεν μπορούν να διαβάσουν τους καταλόγους προφίλ άλλων χρηστών των Windows, επομένως ακόμη και απλές λειτουργίες ανάγνωσης αρχείων θα αποτύγχαναν σε πολλά σενάρια.
Για να αντιμετωπίσουμε αυτό το ζήτημα, προσθέσαμε ακόμη ένα επίπεδο στη διαδικασία ρύθμισης του sandbox — ένα επίπεδο για την παραχώρηση ACL ανάγνωσης στους χρήστες sandbox εκεί όπου τέτοια ACL ενδέχεται να μην υπάρχουν ήδη. Για παράδειγμα, σε ορισμένους συχνά χρησιμοποιούμενους καταλόγους των Windows:
C:\Users\<real-user>C:\Windows\C:\Program Files\C:\Program Files (x86)\C:\ProgramData\
Επειδή αυτή η λίστα καταλόγων είναι βέλτιστης προσπάθειας και η εγκατάσταση ACL σε καθέναν από αυτούς μπορεί να είναι αρκετά δαπανηρή, εκτελούμε αυτή τη λογική ασύγχρονα ώστε το βήμα ρύθμισης του sandbox, που μπλοκάρει τους χρήστες, να μη χρειάζεται να περιμένει την ολοκλήρωσή τους.
Ενσωματώσαμε τη λογική ρύθμισης στο δικό της δυαδικό εν μέρει για να περνάμε το όριο UAC μόνο όταν χρειάζεται. Αλλά ο βαθύτερος λόγος ήταν αρχιτεκτονικός: η ρύθμιση του sandbox έχει μια θεμελιωδώς διαφορετική αποστολή από το codex.exe. Η διατήρηση της λογικής ρύθμισης του sandbox σε ένα αποκλειστικό δυαδικό επέτρεψε στο codex.exe να παραμένει ένα κανονικό harness χωρίς αυξημένα δικαιώματα, απέτρεψε το Windows-only μηχάνημα ρύθμισης από το να διογκώνει το codex.exe σε άλλες πλατφόρμες, αποσύνδεσε τη μακρύτερης διάρκειας εργασία ρύθμισης από τη διάρκεια ζωής της κύριας διεργασίας, και μας έδωσε ένα μέρος για να χειριζόμαστε τις διαφορετικές διαδρομές ρύθμισης που χρειαζόταν το sandbox.
Λόγω του τρόπου με τον οποίο λειτουργούν τα όρια σύνδεσης χρηστών και token στα Windows, δεν μπορούσαμε να συνεχίσουμε να δημιουργούμε ένα περιορισμένο token και να ξεκινάμε μια διεργασία κάτω από αυτόν με τον τρόπο που μπορούσαμε στο sandbox χωρίς αυξημένα δικαιώματα. Για να εκκινούμε πράγματι εντολές ως διαφορετικός χρήστης Windows, η πρώτη μας ιδέα ήταν η εξής ροή:
- Το
codex.exeεκτελείται ως ο πραγματικός χρήστης των Windows. Στη συνέχεια, διαδοχικά, το Codex:- Καλεί τη συνάρτηση
LogonUserW(...)για τον χρήστη του sandbox. - Καλεί το
CreateRestrictedToken(...)σε αυτό το token χρήστη sandbox. - Χρησιμοποιώντας εκείνο το περιορισμένο token χρήστη sandbox, καλεί το
CreateProcessAsUserW(...)για να εκκινήσει την τελική θυγατρική διεργασία.
- Καλεί τη συνάρτηση
Στην πράξη, αυτή η επιθυμητή ροή δεν λειτούργησε λόγω ενός φραγμού προνομίων στο CreateProcessAsUserW(...). Αυτό σημαίνει ότι το codex.exe μπορούσε να δημιουργήσει ένα περιορισμένο token για τον χρήστη του sandbox, αλλά δεν μπορούσε να εκκινήσει αξιόπιστα μια θυγατρική διεργασία με αυτό το token από την πλευρά του πραγματικού χρήστη του ορίου. Χρειαζόμασταν μια διεργασία που να εκτελείται ήδη ως ο χρήστης sandbox — αυτό θα επέτρεπε το βήμα περιορισμού και η τελική εκκίνηση να συμβαίνουν στην πλευρά του χρήστη sandbox του ορίου αντί στην πλευρά του πραγματικού χρήστη.
Αυτή η απαίτηση οδήγησε στο codex-command-runner.exe, ένα νέο δυαδικό εκτελέσιμο αρχείο του οποίου η μοναδική λειτουργία είναι να δημιουργεί ένα περιορισμένο token και να εκκινεί την εντολή που ζητήθηκε. Αντί να ζητάμε από το codex.exe να κάνει μόνο του ολόκληρη τη ροή (πραγματικός χρήστης → χρήστης sandbox → περιορισμένο token → θυγατρική διεργασία), χωρίσαμε τη ροή στα δύο:
Μέρος 1
- Το
codex.exeκαλεί τοCreateProcessWithLogonW(...)για να εκκινήσει τοcodex-command-runner.exeως τον χρήστη sandbox, χωρίς ακόμη να χρησιμοποιεί περιορισμένο token.
Μέρος 2
- Μέσα στον runner, το
OpenProcessToken(GetCurrentProcess(), ...)ανοίγει το δικό του token, το οποίο ανήκει ήδη στον χρήστη sandbox. - Ο runner καλεί το
GetTokenInformation(...)για να εξαγάγει το sandbox logon SID και, στη συνέχεια, τοCreateRestrictedToken(...)για να δημιουργήσει το τελικό περιορισμένο token. - Πάλι μέσα στον runner, καλεί το
CreateProcessAsUserW(...)με εκείνο το περιορισμένο token για να εκκινήσει την πραγματική θυγατρική διεργασία.
Ο Άλμπερτ Αϊνστάιν είπε: «Όλα πρέπει να γίνονται όσο το δυνατόν πιο απλά, αλλά όχι απλούστερα». Με αυτό το πνεύμα, ο σχεδιασμός μας έλυσε επαρκώς κάθε πρόβλημα. Η τελική αρχιτεκτονική έχει τα τέσσερα επίπεδα που έχουμε ήδη καλύψει:
- Το ίδιο το
codex.exe - Το
codex-windows-sandbox-setup.exeγια τον χειρισμό όλης της εργασίας ρύθμισης που σχετίζεται με αυξημένα δικαιώματα - Το
codex-command-runner.exeγια την εκτέλεση εντολών περιορισμένου token - Τη θυγατρική διεργασία
Όταν πρωτοασχολήθηκα με αυτό το έργο, δεν ήξερα πραγματικά πού θα κατέληγε. Η προσέγγισή μου ήταν να ξεκινήσω ενσωματώνοντας τη δυνατότητα sandboxing στο όριο ανάμεσα στο Codex και το λειτουργικό σύστημα. Αυτή η προσέγγιση ταιριάζει πολύ με το πώς υλοποιείται το sandbox του Codex σε MacOs και Linux.
Καθώς μάθαινα περισσότερα για τα συγκεκριμένα εργαλεία που παρέχουν τα Windows, και μέσα από δεκάδες αποφάσεις που ισορροπούσαν ανάμεσα στην ασφάλεια και την ευχρηστία, το σύστημα εξελίχθηκε στην τρέχουσα μορφή του — πολλαπλά δυαδικά, προσαρμοσμένοι χρήστες, κανόνες firewall, ένα βήμα ρύθμισης με αυξημένα δικαιώματα, ασύγχρονες διεργασίες και άλλα.
Δεν είναι ένα ιδιαίτερα απλό σύστημα, αλλά κάθε στοιχείο πολυπλοκότητας προστέθηκε από ανάγκη, για να δημιουργηθεί ένα sandbox που είναι και ασφαλές και, όσο γίνεται, δεν στέκεται εμπόδιο στον χρήστη.
Καθώς εργαζόμασταν για να προσφέρουμε μια καλή εμπειρία χρήστη για τους χρήστες του Codex στα Windows, στόχος μας ήταν να δημιουργήσουμε κάτι ασφαλές που δεν θα συμβιβαζόταν ως προς τη χρησιμότητα — όλο το νόημα της χρήσης του Codex είναι να μπορούν οι πράκτορες να κάνουν δουλειά χωρίς τη συνεχή προσοχή σας.
Ένα από τα μεγαλύτερα μαθήματα από αυτό το έργο ήταν ότι τα Windows δεν μας έδωσαν έναν βασικό μηχανισμό που να αντιστοιχεί καθαρά στο «ασφαλής αυτόνομος πράκτορας προγραμματισμού». Συνθέσαμε αρκετά εργαλεία και έννοιες για να χτίσουμε κάτι συνεκτικό. Ορισμένες πρώτες ιδέες ήταν αδιέξοδες. Ο τελικός σχεδιασμός ήταν ένα υβρίδιο προηγούμενων πρωτοτύπων που το καθένα έλυνε ένα μέρος του προβλήματος.
Το άλλο μάθημα ήταν ότι η ασφάλεια για έναν πράκτορα προγραμματισμού είναι διαφορετική υπόθεση από την πιο κλασική ασφάλεια εφαρμογών. Το Codex πρέπει να λειτουργεί για πραγματικές ροές εργασίας προγραμματιστών. Η μηχανική εργασία αφορούσε την ισορροπία ανάμεσα στη συμβατότητα με φόρτους εργασίας με πράκτορα και στην πραγματική επιβολή. Αυτή η ένταση διαμόρφωσε τους συμβιβασμούς στον τελικό σχεδιασμό.
Έχετε την περιέργεια να δείτε το sandbox του Codex σε δράση; Δοκιμάστε το.


