Η εφαρμογή Expo αποτυγχάνει σε HTTP στο Android 9: είναι cleartext, όχι το VPN
Ένα build του Expo που καλεί ένα απλό HTTP API αποτυγχάνει στο Android 9 και μετά. Το τούνελ είναι αθώο: η σημαία cleartext ανήκει στη διαμόρφωση του build.
Κυκλοφορήσατε ένα νέο build, περάσατε στο VPN και η ίδια οθόνη σταμάτησε να φορτώνει. Στο Android 9 και μετά η πιο συνηθισμένη εξήγηση είναι πιο βαρετή: η πλατφόρμα αρνείται το απλό HTTP για εφαρμογές που στοχεύουν στο API 28 ή υψηλότερα, και το VPN άλλαξε μόνο αρκετό πλαίσιο για να το αποκαλύψει. Το σφάλμα που θα δείτε εξαρτάται από τον πελάτη HTTP, γι’ αυτό τόσο σπάνια λέει cleartext.
Τι είναι στην πραγματικότητα αυτή η αποτυχία
Από το Android 9 και μετά η πλατφόρμα μπλοκάρει το cleartext εξ ορισμού μόλις μια εφαρμογή στοχεύσει στο επίπεδο API 28 ή υψηλότερα. Το αίτημα προς μια απλή διεύθυνση HTTP απορρίπτεται από την πλατφόρμα πριν βγει από τη συσκευή ούτε ένα πακέτο. Ποιο σφάλμα βλέπετε εξαρτάται από τη βιβλιοθήκη HTTP: μερικές φορές μια γενική αποτυχία δικτύου, μερικές φορές μια λήξη χρόνου, μερικές φορές ένα μήνυμα που ονομάζει το cleartext ευθέως. Αυτό που δεν κάνει ποτέ είναι να φτάσει στον διακομιστή σας. Το Android τεκμηριώνει την προεπιλογή και την εναλλακτική που περιορίζεται σε τομείς στον οδηγό διαμόρφωσης ασφαλείας.
Ένας περιηγητής στην ίδια συσκευή μπορεί ακόμη να φορτώσει τη σελίδα, και αυτό είναι το στοιχείο που οι περισσότεροι χάνουν. Οι περιηγητές δεν υπόκεινται στην πολιτική ασφάλειας δικτύου της εφαρμογής σας.
Γιατί κατηγορείται το VPN
Τρία πράγματα αλλάζουν συνήθως ταυτόχρονα. Η εφαρμογή μπορεί να επιλύσει διαφορετικό όνομα κεντρικού υπολογιστή αφού συνδεθεί το VPN, η συσκευή μπορεί να είναι καινούργια με νεότερο build, ή το ίδιο το build μπορεί να έχει μετακινηθεί σε επίπεδο API προορισμού που ενεργοποιεί την προεπιλογή. Το VPN είναι ορατό και το SDK προορισμού δεν είναι, οπότε το VPN παίρνει το εισιτήριο.
Συγκρίνετε τα επίπεδα προορισμού του παλιού και του νέου build πριν αγγίξετε τη διαμόρφωση δικτύου. Μια εφαρμογή που στοχεύει στο 27 ή χαμηλότερα εξαιρείται, και αυτό εξηγεί κάθε αναφορά του τύπου «δουλεύει στο παλιό μου τηλέφωνο».
Πού καταλήγει στην πραγματικότητα η σημαία του Expo
Σε ένα διαχειριζόμενο έργο Expo, η προσθήκη μιας ρύθμισης στο app.json δεν επεξεργάζεται ένα manifest του Android, επειδή το manifest το παράγουν το prebuild και τα development builds. Το πρόσθετο διαμόρφωσης είναι αυτό που γράφει τη ρύθμιση σε εκείνο το στάδιο. Η υποστηριζόμενη διαδρομή είναι το expo-build-properties, διαμορφωμένο στη διαμόρφωση της εφαρμογής με την επιλογή cleartext κάτω από το android.
{
"plugins": [
["expo-build-properties", {
"android": { "usesCleartextTraffic": true }
}]
]
}Το απόσπασμα ορίζει μόνο την επιλογή του πρόσθετου· το manifest παράγεται αργότερα. Εκτελέστε ένα prebuild ή ένα νέο build του development client, και μετά, πριν δοκιμάσετε ξανά, ελέγξτε το παραγόμενο AndroidManifest.xml για android:usesCleartextTraffic, επειδή μια επαναφόρτωση μόνο με JS κρατά το παλιό manifest. Ταιριάξτε την έκδοση του πρόσθετου με το Expo SDK στο οποίο τρέχει το έργο. Οι επιλογές του πρόσθετου μετακινούνται μεταξύ εκδόσεων, και ένα απόσπασμα αντιγραμμένο από άλλο SDK είναι αξιόπιστη πηγή σιωπηλών no-op.
Η ροή bare και η στενότερη επιλογή
Για bare React Native το αντίστοιχο είναι το android:usesCleartextTraffic στο στοιχείο application, ή μια διαμόρφωση ασφάλειας δικτύου που επιτρέπει cleartext μόνο για ονομασμένους τομείς. Η μορφή με περιορισμό τομέα είναι η προτιμότερη, επειδή επιτρέπει το εσωτερικό API και αφήνει όλα τα άλλα σε HTTPS. Τεκμηριώνει επίσης τη δική της λίστα εξαιρέσεων, και αυτό είναι το μέρος για το οποίο θα ρωτήσει ένας κριτικός.
Καμία από τις δύο προσεγγίσεις δεν αλλάζει την προεπιλογή της πλατφόρμας για οτιδήποτε δεν ονομάσατε.
Αποδείξτε το πρώτα από το αρχείο καταγραφής της συσκευής
Πριν επεξεργαστείτε τη διαμόρφωση, πάρτε την ακριβή αποτυχία. Το adb logcat σε συνδεδεμένη συσκευή δείχνει την απόρριψη cleartext της πλατφόρμας και ονομάζει το στοιχείο που την προκάλεσε. Ένας απορριφθείς υποδοχέας, ένα όνομα που δεν επιλύεται ή μια αποτυχημένη χειραψία TLS δείχνουν κάπου εντελώς αλλού, και η ενεργοποίηση του cleartext θα αποδυνάμωνε την εφαρμογή χωρίς λόγο.
Έπειτα κρατήστε την παραγωγή έντιμη. Το cleartext είναι αποδεκτό για ένα τελικό σημείο εργαστηρίου που δεν μπορεί να προσφέρει TLS, και μόνο για το συντομότερο διάστημα που μπορείτε να προγραμματίσετε. Αν το API μπορεί να τερματίσει το TLS μέσα στο ιδιωτικό δίκτυο, βάλτε το πιστοποιητικό στο χώρο εμπιστοσύνης της συσκευής και αφήστε το cleartext απενεργοποιημένο, επειδή το τούνελ κρυπτογραφεί τη διαδρομή μέχρι την έξοδό του και τίποτα πέρα από αυτή.
Μόλις το τελικό σημείο απαντήσει σε HTTPS, αφαιρέστε την άδεια, ξαναχτίστε και δοκιμάστε στο VPN και σε συνηθισμένο Wi-Fi στην ίδια συνεδρία. Η επίλυση ονομάτων μπορεί να διαφέρει μεταξύ αυτών των δύο διαδρομών, και μόνο το ζεύγος σας λέει ποια λέει την αλήθεια.