Avec toutes les violations de données récentes, la confidentialité est devenue un sujet important. Presque toutes les applications communiquent sur le réseau, il est donc important de prendre en compte la sécurité des informations des utilisateurs. Dans cet article, vous apprendrez les meilleures pratiques actuelles pour sécuriser les communications de votre application Android..
Lorsque vous développez votre application, il est recommandé de limiter vos demandes réseau à celles qui sont essentielles. Pour les éléments essentiels, assurez-vous qu’ils sont générés sur HTTPS au lieu de HTTP. HTTPS est un protocole qui chiffre le trafic de sorte qu'il ne puisse pas être facilement intercepté par des oreilles indiscrètes. La bonne chose à propos de Android est que la migration est aussi simple que de changer l’URL de http à https.
URL url = nouvelle URL ("https://example.com"); HttpsURLConnection httpsURLConnection = (HttpsURLConnection) url.openConnection (); httpsURLConnection.connect ();
En fait, Android N et les versions supérieures peuvent appliquer le protocole HTTPS à l'aide de la configuration de la sécurité réseau d'Android..
Dans Android Studio, sélectionnez le app / res / xml répertoire pour votre projet. Créer le xml répertoire s'il n'existe pas déjà. Sélectionnez-le et cliquez Fichier> Nouveau fichier. Appeler network_security_config.xml. Le format du fichier est le suivant:
exemple.com
Pour dire à Android d’utiliser ce fichier, ajoutez son nom à la balise d’application dans le AndroidManifest.xml fichier:
Mettre à jour les fournisseurs de crypto
Le protocole HTTPS a été exploité à plusieurs reprises au fil des ans. Lorsque les chercheurs en sécurité signalent des vulnérabilités, les défauts sont souvent corrigés. L'application des correctifs garantit que les connexions réseau de votre application utilisent les protocoles standard les plus récents. Les versions les plus récentes des protocoles contiennent moins de faiblesses que les précédentes.
Pour mettre à jour les fournisseurs de cryptage, vous devez inclure les services Google Play. Dans votre fichier de module de build.gradle, ajoutez la ligne suivante à la section dependencies:
implémentation 'com.google.android.gms: play-services-safetynet: 15.0.1'L'API des services SafetyNet comporte de nombreuses autres fonctionnalités, notamment l'API de navigation sécurisée qui vérifie si les URL ont été marquées comme une menace connue et une API reCAPTCHA pour protéger votre application contre les spammeurs et tout autre trafic malveillant..
Après avoir synchronisé Gradle, vous pouvez appeler le
ProviderInstaller
deinstallIfNeededAsync
méthode:Classe publique MainActivity (extension) Activity implémente ProviderInstaller.ProviderInstallListener @Override protected void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); ProviderInstaller.installIfNeededAsync (ceci, cela);le
onProviderInstalled ()
La méthode est appelée lorsque le fournisseur est correctement mis à jour ou déjà à jour. Autrement,onProviderInstallFailed (int errorCode, Intent recoveryIntent)
est appelé.Attribution de certificat et de clé publique
Lorsque vous établissez une connexion HTTPS à un serveur, un certificat numérique est présenté par le serveur et validé par Android pour vous assurer que la connexion est sécurisée. Le certificat peut être signé avec un certificat d'une autorité de certification intermédiaire. Ce certificat utilisé par l'autorité intermédiaire peut à son tour être signé par une autre autorité intermédiaire, etc., qui est digne de confiance tant que le dernier certificat est signé par une autorité de certification racine déjà approuvée par Android OS..
Si l'un des certificats de la chaîne de confiance n'est pas valide, la connexion n'est pas sécurisée. Bien que ce soit un bon système, il n'est pas infaillible. Il est possible pour un attaquant de dire à Android OS d'accepter des certificats personnalisés. Les mandataires d'interception peuvent posséder un certificat approuvé. Si le périphérique est contrôlé par une société, celle-ci peut l'avoir configurée pour accepter son propre certificat. Ces scénarios permettent une attaque «homme au milieu», permettant de déchiffrer et de lire le trafic HTTPS..
L'identification de certificat vient à la rescousse en vérifiant le certificat du serveur présenté par rapport à une copie du certificat attendu. Cela empêche les connexions d'être établies lorsque le certificat est différent de celui attendu.
Afin de mettre en œuvre l'épinglage sur Android N et supérieur, vous devez ajouter un hachage (appelé "pins") du certificat dans la network_security_config.xml fichier. Voici un exemple d'implémentation:
duckduckgo.com lFL47 + i9MZkLqDTjnbPTx2GZbGmRfvF3GkEh + J + 1F3g = w9MWhhnFZDSPWTFBjaoeGuClsrCs7Z70lG7YNlo8t + s = Pour trouver les pins pour un site spécifique, vous pouvez aller à SSL Labs, entrer sur le site et cliquer sur Soumettre. Ou, si vous développez une application pour une entreprise, vous pouvez la demander à l'entreprise..
Remarque: Si vous devez prendre en charge des appareils exécutant une version de système d'exploitation antérieure à Android N, vous pouvez utiliser la bibliothèque TrustKit. Il utilise le fichier de configuration de la sécurité réseau de la même manière.
Désinfection et validation
Avec toutes les protections apportées jusqu'à présent, vos connexions devraient être assez sûres. Même dans ce cas, n'oubliez pas la validation de la programmation régulière. Faire confiance aveuglément aux données reçues du réseau n’est pas sûr. Une bonne pratique de programmation est la «conception par contrat», où les entrées et les sorties de vos méthodes satisfont à un contrat qui définit les attentes spécifiques de l’interface..
Par exemple, si votre serveur attend une chaîne de 48 caractères ou moins, assurez-vous que l'interface ne renverra que 48 caractères au maximum..
if (editText.getText (). toString (). length () <= 48) ; //return something… else ; //return default or errorSi vous n'attendez que des numéros du serveur, vos entrées doivent vérifier cela. Bien que cela aide à prévenir les erreurs innocentes, cela réduit également le risque d’attaques par injection et par corruption de mémoire. Cela est particulièrement vrai lorsque ces données sont transmises au code C et C ++ natif de NDK ou JNI..
Il en va de même pour l'envoi de données au serveur. Ne pas envoyer aveuglément des données, surtout si elles sont générées par l'utilisateur. Par exemple, il est recommandé de limiter la longueur des entrées de l'utilisateur, en particulier si elles seront exécutées par un serveur SQL ou par toute technologie exécutant du code..
Bien que la sécurisation d'un serveur contre les attaques dépasse le cadre de cet article, en tant que développeur mobile, vous pouvez faire votre part en supprimant les caractères de la langue utilisée par le serveur. De cette façon, l'entrée n'est pas susceptible d'attaques d'injection. Quelques exemples sont les guillemets, les points-virgules et les barres obliques, s'ils ne sont pas essentiels à la saisie de l'utilisateur:
string = string.replace ("\\", "") .replace (";", "") .replace ("\" "," ") .replace (" \ '"," ");Si vous connaissez exactement le format attendu, vérifiez-le. Un bon exemple est la validation de courrier électronique:
final final String emailRegexString = "^ [A-Za-z0-9 ._% + \\ -] + @ [A-Za-z0-9. \\ -] + \\. [A-Za-z] 2,4 $ "; private boolean isValidEmailString (Chaîne emailString) return emailString! = null && Pattern.compile (emailRegexString) .matcher (emailString) .matches ();Les fichiers peuvent également être vérifiés. Si vous envoyez une photo sur votre serveur, vous pouvez vérifier qu’elle est valide. Les deux premiers octets et les deux derniers octets sont toujours
FF D8
etFF D9
pour le format JPEG.private boolean isValidJPEGAtPath (String pathString) lève l'IOException RandomAccessFile randomAccessFile = null; try randomAccessFile = new RandomAccessFile (pathString, "r"); long length = randomAccessFile.length (); si (longueur < 10L) return false; byte[] start = new byte[2]; randomAccessFile.readFully(start); randomAccessFile.seek(length - 2); byte[] end = new byte[2]; randomAccessFile.readFully(end); return start[0] == -1 && start[1] == -40 && end[0] == -1 && end[1] == -39; finally if (randomAccessFile != null) randomAccessFile.close();Soyez prudent lorsque vous affichez une alerte d'erreur qui affiche directement un message du serveur. Les messages d'erreur peuvent révéler des informations de débogage privées ou liées à la sécurité. La solution consiste à faire en sorte que le serveur envoie un code d'erreur que le client recherche pour afficher un message prédéfini..
Communication avec d'autres applications
Pendant que vous protégez la communication vers et depuis le périphérique, il est également important de protéger IPC. Il est arrivé que des développeurs aient laissé des fichiers partagés ou implémenté des sockets pour échanger des informations sensibles. Ce n'est pas sécurisé. Il vaut mieux utiliser Intentions. Vous pouvez envoyer des données en utilisant un Intention en fournissant le nom du paquet comme ceci:
Intention d'intention = nouvelle intention (); intent.setComponent (new ComponentName ("com.example.app", "com.example.app.TheActivity")); intent.putExtra ("UserInfo", "Exemple de chaîne"); startActivity (intention);Pour diffuser des données vers plusieurs applications, vous devez vous assurer que seules les applications signées avec votre clé de signature obtiendront les données. Sinon, les informations que vous envoyez peuvent être lues par toutes les applications qui s'inscrivent pour recevoir la diffusion. De même, une application malveillante peut envoyer une diffusion à votre application si vous vous êtes enregistré pour la recevoir. Vous pouvez utiliser une autorisation pour envoyer et recevoir des émissions où Signature est utilisé comme Niveau de protection. Vous pouvez définir une autorisation personnalisée dans le fichier manifeste comme suit:
Ensuite, vous pouvez accorder la permission comme ceci:
Les deux applications doivent avoir les autorisations dans le fichier manifeste pour que cela fonctionne. Pour envoyer la diffusion:
Intention d'intention = nouvelle intention (); intent.putExtra ("UserInfo", "Exemple de chaîne"); intent.setAction ("com.example.SOME_NOTIFICATION"); sendBroadcast (intent, "com.example.mypermission");Alternativement, vous pouvez utiliser
setPackage (String)
lors de l'envoi d'une diffusion, restreignez-la à un ensemble d'applications correspondant au package spécifié. Réglageandroid: exporté
àfaux
dans le fichier manifeste exclura les émissions reçues de l'extérieur de votre application.Cryptage de bout en bout
Il est important de comprendre les limites du protocole HTTPS pour la protection des communications réseau. Dans la plupart des implémentations HTTPS, le cryptage est terminé sur le serveur. Par exemple, votre connexion au serveur d'une entreprise peut être via HTTPS, mais une fois que le trafic atteint le serveur, il est non crypté. Il peut ensuite être transféré vers d'autres serveurs, soit en établissant une autre session HTTPS, soit en l'envoyant non chiffré. La société est en mesure de voir les informations qui ont été envoyées et, dans la plupart des cas, cela est une nécessité pour les opérations commerciales. Cependant, cela signifie également que la société pourrait transmettre les informations à des tiers non chiffrées..
Il existe une tendance récente appelée "cryptage de bout en bout", selon laquelle seuls les périphériques communicants de bout en bout peuvent lire le trafic. Un bon exemple est une application de discussion cryptée dans laquelle deux appareils mobiles communiquent entre eux via un serveur; seuls l'expéditeur et le destinataire peuvent lire les messages l'un de l'autre.
Une analogie pour vous aider à comprendre le cryptage de bout en bout est d’imaginer que vous voulez que l’on vous envoie un message que vous seul pouvez lire. Pour ce faire, vous leur fournissez une boîte avec un cadenas ouvert (la clé publique) tout en conservant la clé du cadenas (clé privée). L'utilisateur écrit un message, le met dans la boîte, verrouille le cadenas et vous le renvoie. Seulement vous pouvez lire le message parce que vous êtes le seul à avoir la clé pour déverrouiller le cadenas.
Avec un cryptage de bout en bout, les deux utilisateurs s'envoient mutuellement leurs clés. Le serveur fournit uniquement un service de communication, mais il ne peut pas lire le contenu de la communication. Bien que les détails de la mise en œuvre dépassent le cadre de cet article, il s'agit d'une technologie puissante. Si vous souhaitez en savoir plus sur cette approche, un excellent point de départ est le dépôt GitHub pour le projet Signal à source ouverte..
Conclusion
Avec toutes les nouvelles lois sur la confidentialité telles que le GDPR, la sécurité est de plus en plus importante. C'est souvent un aspect négligé du développement d'applications mobiles.
Dans ce didacticiel, vous avez abordé les meilleures pratiques en matière de sécurité, notamment l'utilisation de HTTPS, l'identification des certificats, la désinfection des données et le cryptage de bout en bout. Ces meilleures pratiques devraient servir de base à la sécurité lors du développement de votre application mobile. Si vous avez des questions, n'hésitez pas à les laisser ci-dessous, et pendant que vous êtes ici, consultez certains de mes autres tutoriels sur la sécurité des applications Android.!