web-dev-qa-db-fra.com

Codage côté client: comment empêcher une utilisation malveillante?

Au cours des dernières années, la tendance des applications côté client (navigateur) a vraiment décollé.

Pour mon dernier projet, j'ai décidé d'essayer d'évoluer avec le temps et d'écrire une application côté client.

Une partie de cette application consiste à envoyer des e-mails de transaction aux utilisateurs (par exemple, valider l'inscription, e-mails de réinitialisation de mot de passe, etc.). J'utilise une API tierce pour envoyer les e-mails.

Normalement, mon application s'exécute sur un serveur. J'appellerais l'API tierce à partir du code sur mon serveur.

L'exécution d'une application côté client signifie que cela doit maintenant se produire sur le navigateur d'un utilisateur. L'API tierce fournit les fichiers JavaScript nécessaires pour y parvenir.

Le premier problème flagrant que je peux voir est que je dois utiliser une clé API. Cela serait normalement stocké en toute sécurité sur mon serveur, mais maintenant je suppose que je devrai fournir cette clé au navigateur client.

En supposant que je puisse contourner ce problème, le problème suivant est ce qui empêche un utilisateur averti de charger l'outil de développement JavaScript sur un navigateur et d'utiliser l'API de messagerie comme il le souhaite, plutôt que de dire qu'il respecte les règles que j'ai définies dans l'application .

Je suppose que ma question générale est - comment pouvons-nous empêcher l'utilisation malveillante d'une application côté client?

60
Gaz_Edge

Vous ne pouvez pas, et plus les gens comprennent cela, et plus ils comprennent, mieux c'est pour le monde.

Le code qui s'exécute sur un appareil sous le contrôle de l'utilisateur ne peut pas être contrôlé. Les smartphones peuvent être jailbreakés. Les décodeurs peuvent être fissurés. Les navigateurs ordinaires n'essaient même pas d'empêcher l'accès au code JavaScript. Si vous avez quelque chose qui mérite d'être volé ou abusé, un attaquant déterminé pourra le faire à moins que vous ne validiez tout ce que vous chérissez côté serveur.

L'obfuscation est très peu utile; le type d'adversaire que vous attirerez dès que quelque chose de financier à distance est impliqué lit le langage d'assemblage comme les petites annonces. Le chiffrement ne peut pas vous aider, car l'appareil qui protégerait la clé est le même appareil que vous devez supposer être fissuré. Il existe de nombreuses autres contre-mesures apparemment évidentes qui ne fonctionnent pas, pour des raisons similaires.

Malheureusement, c'est une vérité très gênante. Le monde regorge d'opérateurs de petite et de grande taille qui pensent pouvoir contourner d'une manière ou d'une autre la rupture fondamentale de la confiance à distance, simplement parce que ce serait oh si gentil si nous pouvions supposer que notre code sera exécuté comme nous le supposions. Et oui, cela rendrait tout tellement plus facile que ce n'est même pas drôle. Mais souhaiter ne le fait pas ainsi, et espérer contre tout espoir que vous êtes le seul cookie intelligent qui peut éviter le désagrément ne fera que vous brûler ainsi que vos clients. Par conséquent, sachez qu'Internet est un territoire ennemi, incluez ce coût supplémentaire dans vos estimations et tout ira bien.

Cela dit, bien sûr, la défense en profondeur existe. L'obscurcissement de votre JavaScript ne repousse pas un attaquant déterminé, mais il peut rebuter certains attaquants moins déterminés. Si vos actifs valent suffisamment pour être protégés, mais pas à n'importe quel prix, l'une de ces mesures peut ajouter une valeur commerciale à votre système; ça ne peut pas être parfait. Tant que vous êtes pleinement conscient du compromis que vous faites, cela peut être une stratégie raisonnable.

200
Kilian Foth

La règle ici est:

Faites tout ce qui concerne le client et qui n'affecte personne d'autre si l'utilisateur le manipule. En particulier, cela signifie des effets graphiques.

Faites tout ce qui doit être sécurisé côté serveur et envoyez simplement des événements d'interface utilisateur à partir du client (par exemple, le client dit simplement "l'utilisateur a appuyé sur le bouton Acheter" pendant que le serveur exécute réellement la transaction). En particulier, cela signifie des transactions financières.

69
jhocking

C'est exactement le cas où en faire une application entièrement côté client est pas approprié.

Vous pouvez effectuer la logique et la validation de base des formulaires côté client (vous devez encore revalider sur le serveur, car quelqu'un peut essayer de truquer la demande) pour améliorer la réactivité, vous pouvez effectuer des requêtes HTTP à partir de JavaScript en passant des données là-bas et en arrière dans JSON à éviter de renvoyer des décorations de page et autres, mais si la transaction elle-même doit être authentifiée et autorisée, elle doit toujours se produire sur un serveur.

28
Jan Hudec

Votre paragraphe du milieu est au cœur du problème:

L'exécution d'une application côté client signifie que cela doit maintenant se produire sur le navigateur d'un utilisateur. L'API tierce fournit les fichiers js nécessaires pour y parvenir.

Pourquoi une application côté client signifie-t-elle que vous ne pouvez pas avoir de travail côté serveur? La poussée vers la programmation côté client ne consiste pas à éliminer les serveurs, mais à tirer parti des technologies plus récentes que les navigateurs prennent enfin en charge pour améliorer les interfaces utilisateur.

En ce qui concerne la .js fichier que vous avez reçu, êtes-vous sûr qu'il est destiné à un navigateur? Serait-ce une bibliothèque node.js?

17
Brandon

Faisons un pas en arrière et jetons un regard de plus haut niveau .. devons-nous .. Eudora ou Outlook (une application côté client, sans même avoir besoin d'un navigateur) ont-ils déjà causé une perte financière à une entreprise? Non. N'importe qui pouvait écrire sur les API POP/SMTP et être le client. Mais aucune perte pour le serveur. Le serveur n'a pas limité les actions du client, les calculs, le stockage, la température, la taille du disque, la taille du ram, le moniteur DPI, le GPU, le FPU yada yada du client, mais a spécifié exactement à quoi il répondrait et pas plus. Avez-vous déjà entendu parler de quicken ou de l'utilisation de MS-Money pour pénétrer dans une banque?

Votre application de navigateur (c'est-à-dire côté client) peut utiliser la même architecture.

  1. Vous construisez votre serveur avec une API (dont BTW, se résume toujours à des dérivés de GET POST HEAD etc.).
  2. Sur le serveur, assurez-vous que l'API ne parle qu'avec un client authentifié et vérifié pour chaque appel.
  3. Ensuite, vous ne vous souciez pas de savoir qui est le client.
  4. Et puis, peu importe si c'est un navigateur, un appareil jailbreaké, Google glass, DOS 3.1 ou un tout nouveau Nexus entre les mains d'un arrière-arrière-arrière-arrière-grand-père technophobe qui a voyagé en 2014 et a tout raté la technologie qui a inondé nos vies au cours des 15 dernières décennies.
  5. Vous pouvez maintenant commencer à décharger tout le reste du côté client.

SoapBoxBegin

@KilianFoth soulève un point de sensibilisation important pour les naïfs et les imprudents, principalement ceux qui lisent les titres tout le temps mais ne pensent jamais que cela arrivera à leur application, leur code, leur employeur, leur client, leur propre compte bancaire. Encore plus téméraires sont leurs employeurs (en particulier les CTO) qui permettraient aux applications de sortir qui exposent tous les systèmes à une exposition non gérée/non contrôlée. Cependant, je suis toujours perplexe sur la façon dont il semble que "nous n'apprenons jamais".

SoapBoxEnd

Donc, pour résumer. Créez une API côté serveur solide et étanche. Déchargez tout le reste sur le client en fonction de ce que le client peut gérer.

11
LMSingh

Je dirais que vous ne pouvez vraiment pas. Si vous êtes prêt à envoyer les données au client, vous devez vous attendre à ce qu'elles soient utilisées de manière abusive, mais c'est possible. Votre exemple concernant la clé API est illustratif du point, et je n'inclurais pas cela dans votre côté client JS - il sera volé et abusé.

Vous aurez certainement encore besoin d'une certaine quantité de code serveur pour sécuriser les choses. Même quelque chose d'aussi simple que de récupérer uniquement les données relatives à l'utilisateur connecté. Cette authentification ne peut pas toutes être effectuée côté client ou encore vous serez mis à profit et vos données ne sont pas sécurisées.

Je considérerais toujours l'expérience côté client JS comme un ajout au code serveur. La validation sur le client offre une expérience utilisateur agréable, mais si vous ne vérifiez pas que les données POST sur le serveur de réception également, vous vous ouvrez à l'attaque. Tout ce que le client doit être considéré comme suspect.

6
Matt Klinker

C'est assez simple, vraiment. Supposons que l'ordinateur client et tous les logiciels qui y sont exécutés soient sous le contrôle total d'un pirate malveillant intelligent.

Cela signifie que toutes les informations que vous envoyez du serveur au client seront connues du pirate malveillant, vous devez donc vous assurer de n'envoyer aucune information au client qui pourrait être utilisée pour attaquer votre serveur ou votre entreprise.

Cela signifie également que tout ce qui est envoyé du client au serveur a été produit par le pirate malveillant, de sorte que le code de votre serveur doit s'assurer que rien que le client puisse envoyer ne serait capable d'attaquer avec succès votre serveur.

Certes, l'implémentation est un problème, mais l'important est l'attitude mentale, l'hypothèse que le "client" auquel vous pensez que votre serveur parle n'est pas un client mais un attaquant actif.

(Vous devez également supposer que l'utilisateur est un escroc intelligent qui tentera d'attaquer vos méthodes commerciales, mais cela n'a rien à voir avec la programmation côté client).

4
gnasher729

À mon avis, l'application côté client concerne principalement l'interface utilisateur. Par exemple, tout votre système d'interface utilisateur sera envoyé une fois au client, puis le client fera ce qu'il veut avec.

Normalement, mon application s'exécute sur un serveur. J'appellerais l'API tierce à partir du code sur mon serveur.

L'exécution d'une application côté client signifie que cela doit maintenant se produire sur le navigateur d'un utilisateur. L'API tierce fournit les fichiers JavaScript nécessaires pour y parvenir.

Si vous avez une clé API, elle n'est pas destinée à fonctionner côté client. Si vous donnez la clé API côté client, tout le monde y a accès et peut ensuite l'utiliser à ses propres fins. Stockez-le et utilisez-le côté serveur lorsque le client en a besoin, puis envoyez le résultat à l'aide d'Ajax/WebSockets.

C'est comme si votre banque disait: "Eh bien, je vais mettre le mot de passe du côté client de la base de données principale afin que le client puisse le demander lui-même et qu'il ne dérange plus nos serveurs."

0
Depado