Dupliquer possible:
Écrire des applications Web «sans serveur»
Donc, disons que je vais construire un clone Stack Exchange et que je décide d'utiliser quelque chose comme CouchDB comme magasin backend. Si j'utilise leur authentification intégrée et leur autorisation au niveau de la base de données, y a-t-il une raison de ne pas autoriser le code Javascript côté client à écrire directement sur le serveur CouchDB disponible au public? Puisqu'il s'agit en gros d'une application CRUD et que la logique métier est constituée de "Seul l'auteur peut éditer son message", je ne vois pas vraiment la nécessité de disposer d'une couche entre le contenu côté client et la base de données. J'utiliserais simplement la validation du côté de CouchDB pour m'assurer que quelqu'un ne met pas de données erronées et que les autorisations sont définies correctement pour que les utilisateurs ne puissent lire que leurs propres données _user. Le rendu se ferait côté client avec quelque chose comme AngularJS. En substance, vous pouvez simplement avoir un serveur CouchDB et un tas de pages "statiques" et vous êtes prêt à partir. Vous n'avez besoin d'aucun type de traitement côté serveur, mais simplement de quelque chose qui pourrait servir les pages HTML.
Ouvrir ma base de données sur le monde semble faux, mais dans ce scénario, je ne vois pas pourquoi tant que les autorisations sont correctement définies. Cela va à l’encontre de mon instinct de développeur Web, mais je ne vois pas de bonne raison. Alors, pourquoi est-ce une mauvaise idée?
EDIT: On dirait qu'il y a une discussion similaire ici: Écrire des applications Web "sans serveur"
EDIT: Super discussion jusqu'à présent, et j'apprécie les commentaires de chacun! Je pense que je devrais ajouter quelques hypothèses génériques au lieu d'appeler spécifiquement CouchDB et AngularJS. Supposons donc que:
- La base de données peut authentifier les utilisateurs directement à partir de son magasin caché
- Toutes les communications de base de données auraient lieu via SSL
- La validation des données peut (mais ne devrait peut-être pas?) Être gérée par la base de données
- La seule autorisation qui nous importe, à part les fonctions d'administration, est que quelqu'un soit autorisé à modifier son propre message.
- Tout le monde peut lire toutes les données (SAUF les enregistrements d’utilisateur pouvant contenir des mots de passe hachés).
- Les fonctions administratives seraient restreintes par une autorisation de base de données
- Personne ne peut s'ajouter à un rôle d'administrateur
- La base de données est relativement facile à mettre à l'échelle
- Il y a peu ou pas de vraie logique métier; Ceci est une application de base CRUD
la source
DELETE FROM ImportantData;
Réponses:
Faire ce que vous suggérez crée un couplage plus étroit entre votre langage côté client et votre base de données.
Cela peut aller - il y a moins de code à écrire et à maintenir, et en théorie le débogage pourrait / devrait aller un peu plus vite.
D'autre part, cela rend d'autres aspects plus difficiles. Si / quand vous devez changer l'une ou l'autre de ces technologies, vous aurez plus de difficulté à cause du couplage étroit qui les unit.
Se protéger contre les attaques sera (bien) un peu plus difficile. Vous supposez que le client présentera toujours des requêtes bien formatées à la base de données. Cela suppose que personne ne piratera jamais le code côté client pour insérer des déclarations malveillantes. En d'autres termes, ils "emprunteront" vos mécanismes d'authentification et remplaceront le code client normal par le leur.
Je ne le recommanderais pas et beaucoup vous diraient avec véhémence de ne pas le faire. Mais cela peut être fait.
la source
Ce n'est probablement pas une bonne idée. Et la première et la plus forte raison que je puisse donner est qu’un serveur de base de données n’est pas conçu pour être un serveur Web public. Au contraire, la sagesse conventionnelle dit que vous devriez cacher votre base de données derrière un pare-feu.
Si vous avez besoin d'éléments de preuve à l'appui, vos préoccupations sont nombreuses - non pas toutes insurmontables, mais aussi une matière à réflexion. Sans ordre particulier, en voici quelques uns:
... Et je suis sûr qu'il y a d'autres préoccupations. Et je suis sûr qu'il existe une solution à la plupart - sinon à toutes ces préoccupations. Mais, il y a une liste pour vous aider à démarrer!
la source
La meilleure raison que je puisse imaginer est la suivante: cette méthode n’est ni directement supportée ni recommandée par aucune des parties impliquées.
Les éditeurs de navigateurs, les normes EcmaScript, les développeurs de systèmes de base de données, les sociétés d’équipement réseau, les architectes d’hébergement / infrastructures et les spécialistes de la sécurité ne prennent pas en charge (ou ne considèrent peut-être même pas) votre cas d'utilisation proposé. Cela pose un problème, car la méthode que vous proposez nécessite que toutes ces entités, et plus encore, fonctionnent correctement pour votre application, même si aucun des systèmes concernés n'a été conçu pour prendre en charge cette opération.
Je ne dis pas que ce n'est pas possible. Je dis simplement que cela revient moins à "réinventer la roue" qu’à réinventer l’interaction client-serveur basée sur un navigateur.
Au mieux, vous travaillerez énormément pour que les systèmes fonctionnent au niveau le plus fondamental possible. Les bases de données populaires modernes ne sont ni RESTful, ni conçues pour fonctionner sur HTTP. Vous allez donc créer vos propres pilotes client basés sur WebSocket (je présume).
Même si tout fonctionne techniquement, vous abandonnerez bon nombre des fonctionnalités les plus puissantes des architectures modernes. Vous n'aurez aucune défense en profondeur - tout le monde peut facilement se connecter directement à la cible principale de la plupart des tentatives de piratage de sites Web. Mais le scénario que vous proposez est bien pire.
Le modèle proposé ne fait pas qu'exposer le serveur, il expose des chaînes de connexion valides. Les attaquants ne peuvent pas simplement envoyer une requête ping au serveur - ils peuvent se connecter activement et lui donner des commandes. Même si vous pouvez limiter l'accès aux données, je ne connais pas suffisamment d'outils dans les systèmes de SGBD pour se protéger contre les scénarios de déni de service et leurs semblables. Lorsque vous travaillez dans des versions améliorées de SQL, telles que TSQL, il est souvent très facile de produire des bombes qui fonctionnent efficacement à l'infini (quelques jointures illimitées pour produire un produit cartésien et vous obtiendrez un SELECT qui fonctionnera indéfiniment, ce qui nécessitera beaucoup de travail). . J'imagine que vous auriez besoin de désactiver la plupart des fonctionnalités de SQL, en éliminant même les requêtes SELECT de base avec JOIN et en autorisant peut-être uniquement l'appel de procédures stockées? Je ne sais même pas si tu peux faire ça, on ne m'a jamais demandé d'essayer. C'est pas ca'
L’évolutivité des bases de données a également tendance à être l’un des problèmes les plus difficiles à travailler à grande échelle, tandis que la mise à l’échelle de plusieurs serveurs HTTP - en particulier avec des pages statiques ou mises en cache - est l’une des parties les plus simples. Votre proposition permet à la base de données de fonctionner plus efficacement en étant responsable de pratiquement 100% des activités côté serveur. C'est un défaut de tueur tout seul. Ce que vous gagnez en transférant du travail sur le client que vous perdez en transférant davantage de travail dans la base de données.
Enfin, je voudrais juste souligner que le cœur de ce que vous proposez n’est pas nouveau, mais remonte en réalité à des décennies. Ce modèle est appelé modèle "base de données fat", qui a essentiellement déplacé la logique côté serveur dans la base de données, comme vous le proposez. Ce modèle a échappé à de nombreuses raisons sur l'Internet de masse et il serait probablement instructif de se pencher davantage sur cette histoire. Notez également que, même à ce moment-là, il était peu envisagé de permettre à des utilisateurs totalement non fiables de se connecter au système et d'exécuter des commandes, car l'accès serait toujours contrôlé pour sélectionner des utilisateurs internes (connus) qui n'étaient pas censés attaquer le système en permanence.
Le fait est que vous aurez toujours besoin d'un serveur HTTP pour traiter les fichiers, car les systèmes de base de données ne le font tout simplement pas. Dans le même temps, tout ce que vous proposez peut être obtenu en utilisant un modèle de serveur léger (tel que Nodejs) pour exposer une interface RESTful à votre base de données. Ceci est populaire pour une raison - cela fonctionne, maintient la base de données cachée derrière des couches de protection, est extrêmement extensible, et vous permet néanmoins de construire votre base de données aussi épaisse ou aussi fine que vous le souhaitez.
la source
En plaçant votre autorisation (les problèmes de sécurité) et votre validation logique en dehors de Database, vous séparez les problèmes de votre système logiciel. Ainsi, vous pouvez tester, gérer, mettre à l'échelle et réutiliser vos blocs de code logiques avec moins de risque de ralentir les fonctionnalités du système.
Fournir la possibilité pour le client de communiquer directement avec la base de données a un très grand potentiel de bousiller les données .
Cela signifie également que le fait d'éviter / de supprimer un couplage étroit rend votre système logiciel plus facile à gérer et plus solide.
la source
Permettre à l'utilisateur d'interagir directement avec la base de données me semble vraiment dangereux.
Le mécanisme d'authentification de CouchDB est-il vraiment si sophistiqué que vous pouvez isoler l'accès en lecture et en écriture d'un utilisateur uniquement aux données qu'il est censé lire et écrire (nous parlons d'accès par document, voire même par champ privilèges ici)? Qu'en est-il des données "communes" qui sont partagées par plusieurs utilisateurs? Cela n’existe-t-il pas du tout dans la conception de votre application?
Voulez-vous vraiment que l'utilisateur puisse modifier ses données de n'importe quelle manière? Qu'en est-il des injections de XSS, par exemple? Ne serait-il pas préférable d'avoir une couche serveur pour filtrer ceux-ci avant qu'ils entrent dans la base de données?
la source
Vous avez un certain nombre de raisons, mais voici une dernière: la pérennité. Tôt ou tard, à mesure que votre application évolue, certaines exigences ne peuvent pas être satisfaites facilement ou de manière sécurisée dans JS côté client ou sous forme de procédure stockée dans votre base de données.
Par exemple, on vous dit que toutes les nouvelles inscriptions doivent avoir une vérification CAPTCHA pour être valides. Ce serait vraiment assez facile avec à peu près n'importe quel framework d'application web moderne. Glissez simplement un reCAPTCHA sur le formulaire d'inscription, transmettez le jeton de réponse de reCAPTCHA au backend et ajoutez quelques lignes de code à votre backend pour vérifier la validité du jeton avec l'API de Google (ou mieux, utilisez une bibliothèque qu'un autre utilisateur a écrite pour le faire.) pour vous).
Si vous utilisez un système à deux niveaux et que vous utilisez la base de données pour toute la logique côté serveur, comment allez-vous vérifier le jeton? Oui, je suppose qu'il serait théoriquement possible, en fonction du SGBD, d'écrire une procédure stockée qui appelle en quelque sorte un shell et appelle curl avec les arguments appropriés. C’est aussi presque certainement une idée horrible: filtrer les entrées et les protéger contre les failles de sécurité serait terrible; vous auriez du mal à gérer le traitement des erreurs et les délais d'attente; et vous auriez à analyser la réponse vous-même. Sans oublier qu'un SGBD n'est pas conçu pour cela, il n'y a donc aucune raison de penser que performances, stabilité, sécurité du thread, etc. ne seront pas un problème. Voir, par exemple, ce fil qui aborde certaines de ces questions pour Postgres.
Et ce n’est que l’enjeu de l’ajout d’un simple CAPTCHA à un formulaire. Qu'allez-vous faire si vous souhaitez ajouter une vérification par SMS ou un travail en arrière-plan qui envoie aux utilisateurs inactifs un e-mail leur rappelant votre application ou une fonctionnalité de téléchargement de fichier afin que les utilisateurs puissent définir une photo de profil? Peut-être que vous décidez que votre application devrait avoir des tests automatisés un jour? Ou souhaitez-vous suivre les modifications apportées à vos procédures dans un système de contrôle de version? Il existe de nombreuses bibliothèques et outils pour la plupart des langages utiles permettant de gérer la plupart de ces tâches pour vous, mais peu de ressources seront disponibles pour votre SGBD, car elles ne sont pas conçues pour cela.
Finalement, vous voudrez faire quelque chose que vous ne pouvez pas raisonnablement faire directement dans votre SGBD, puis vous serez bloqué. Étant donné que vous avez construit l’ensemble de votre application dans votre SGBD, vous n’avez d’autre choix que de vous procurer un serveur Web et de commencer à reconstruire des éléments dans une autre langue, il suffit d’ajouter une fonctionnalité simple.
Et ce serait vraiment dommage, car nous avons déjà un nom pour l'endroit où vous mettez votre logique d'application, et cela s'appelle "le code source de votre application" plutôt que "procédures stockées de base de données" pour une raison.
la source
Si vos contrôles de sécurité et votre logique métier sont contenus dans le code JavaScript côté client, ils peuvent être remplacés par un utilisateur malveillant. Vous pouvez également utiliser une technologie côté serveur basée sur JavaScript (telle que Node.JS ) pour gérer la validation, l'autorisation, etc.
la source
Toute contrainte métier à vérifier doit être validée côté serveur. Même si vous contrôlez l'accès des utilisateurs, il est possible que quelqu'un envoie des données non valides.
Après votre exemple de clonage stackoverflow:
N'importe qui peut manipuler le code côté client et violer complètement l'intégrité des données (même s'il est limité à certains objets, comme leurs propres publications).
la source
Modifiez la page dans Firebug et, à un moment donné, insérez une ligne semblable à celle-ci:
ExecDbCommand("DROP TABLE Users")
Exécuter.
Modifier:
La question portait en fait sur CounchDB, donc pas de SQL à exécuter ici. Pourtant l'idée est la même. Je suppose que toute application non triviale dépend des données pour respecter certaines règles de cohérence vérifiées / appliquées par le code de l'application. Un utilisateur malveillant peut modifier le code client pour enregistrer les données dans un formulaire qui ne respecte pas les règles de votre entreprise et qui pourrait causer des dégâts dans votre application.
Si votre site considère que tous les états de données possibles sont valables du point de vue commercial, optez pour cette voie, mais si ce n'est pas le cas (probablement), vous voudriez avoir la garantie que toutes les données qui sont stockées sont générées par votre code et selon vos règles .
la source
Vieille question, je le sais, mais je voulais en parler car mon expérience est assez différente des autres réponses.
J'ai passé de nombreuses années à écrire des applications collaboratives en temps réel. L'approche générale pour ces applications consiste à répliquer les données localement et à synchroniser les modifications avec des homologues aussi rapidement que possible. Toutes les opérations sur les données sont locales. Par conséquent, toutes les couches de stockage, d'accès aux données, de logique métier et d'interface utilisateur sont locales. Le mouvement " Hors ligne d'abord" ( http://offlinefirst.org/ ) a adopté cette approche pour créer des applications Web hors ligne et peut disposer de ressources pertinentes. Ces types de cas d'utilisation exigent non seulement que vous ouvriez votre couche d'accès aux données aux clients, mais également au stockage de données! Je sais je sais. Semble fou, non?
Les préoccupations relatives à de telles applications, qui sont les premières en mode hors connexion, sont similaires à ce que vous avez demandé, à un seul niveau supprimé. Cela me semble pertinent. Étant donné que vous ouvrez l'accès direct aux données des clients, la question est de savoir comment limiter les effets d'un utilisateur malveillant. Eh bien, il y a beaucoup de stratégies, mais elles ne sont pas évidentes si vous venez d'un contexte de développement plus traditionnel.
La première idée fausse est qu'exposer la base de données signifie exposer toutes les données. Prenez CouchDB par exemple; Les bases de données dans CouchDB sont légères, vous ne perdez donc pas de temps à créer des centaines de milliers de bases de données distinctes sur un serveur. Les utilisateurs peuvent uniquement accéder aux bases de données auxquelles ils sont autorisés à accéder en tant que lecteur ou rédacteur (sans parler des fonctionnalités de validation et de ce qui ne se trouve pas dans CouchDB), afin de ne pouvoir accéder qu'à un sous-ensemble des données.
La deuxième idée fausse est qu'un utilisateur craquant sur des données est un problème! Si les utilisateurs reçoivent une réplique d'une base de données, ils peuvent alors tout mettre en valeur sans affecter les autres utilisateurs. Toutefois, vous devez valider leurs modifications avant de répliquer leurs données dans le magasin "central". Pensez à Git - les utilisateurs peuvent faire ce qu’ils veulent dans les branches, les fourchettes et les référentiels locaux sans affecter la branche principale. La fusion avec le maître implique beaucoup de cérémonie et ne se fait pas à l'aveuglette.
Je construis actuellement un système utilisant CouchDB où les utilisateurs doivent collaborer sur des données pour créer un jeu de données qui est ensuite "publié" via un flux de travail AQ / CQ. La collaboration est réalisée sur une réplique des données (nous appelons cela une base de données intermédiaire ou opérationnelle), puis une fois la tâche terminée, une personne responsable effectue un contrôle de qualité / contrôle de la qualité des données, qui est ensuite répliqué dans le référentiel principal.
De nombreux avantages découlent de ce qui est difficile à obtenir dans d'autres systèmes - tels que le contrôle de version, la réplication et la collaboration (laissez le travail hors connexion!) Pour les applications CRUD à trois niveaux traditionnelles est extrêmement difficile.
Mon conseil - si votre application est "traditionnelle", faites-la de manière traditionnelle. Si l'une des choses que j'ai mentionnées ci-dessus (bien qu'il y en ait beaucoup plus…) s'applique à vous, envisagez d'autres architectures et soyez prêt à penser latéralement.
la source
Je pense que, compte tenu de toutes vos hypothèses, il est possible de passer directement du client à la base de données. Cependant, il est raisonnable de vérifier si vos hypothèses sont valides et le resteront probablement à l'avenir.
Je crains qu’à l’avenir il ne soit pas convenable que tout le monde lise toutes les données, et surtout qu’il puisse développer davantage de logique métier à l’avenir. Les deux sont plus susceptibles si le projet réussit.
Tant que vous vous laisserez le moyen de régler ces problèmes à l’avenir quand et si vous avez réellement besoin de les résoudre, je pense que votre conception fonctionnera. Je pense que vous devrez redoubler de prudence pour séparer les problèmes dans le code JavaScript. Une partie de ce code pourrait être réécrite ultérieurement sur le serveur.
Mais je pourrais certainement voir où cela pourrait valoir le risque de le faire plus tard par rapport au bénéfice de moins de pièces mobiles aujourd'hui.
la source
Tout d’abord merci pour la question OUT OF THE BOX .... :)
Mais ce que je suggérerais est; Essayez toujours de maintenir une séparation entre vos 3 couches. qui sont Presentation / Business et Database ou DAO car ce sera la meilleure pratique pour ce type d’exigences et de configurations où de nombreux changements seront apportés chaque jour.
Dans les mondes simples, votre couche présentation ne doit pas connaître la couche base de données, c’est-à-dire que le format de certains champs de type date peut différer de la couche présentation et de la couche base de données, ce qui permet à l’utilisateur de choisir librement le format de date approprié.
Et Business Logic doit agir comme un couplage entre la couche de présentation et la couche base de données / Dao, comme la transposition des champs, certaines validations commerciales, etc., devrait être traité dans la couche de gestion plutôt que dans la section Javascript, conformément à votre question.
Cette séparation vous apportera une grande facilité et une grande compacité lors de scénarios complexes, de fonctionnalités et même de validations complexes. Le meilleur avantage est que vous pouvez avoir différentes technologies pour mettre en œuvre ces couches et que vous pouvez les modifier en fonction des besoins ou de la portée de l'entreprise.
Merci
la source
Si vous souhaitez créer du code SQL en JavaScript et l'envoyer à la base de données, qui vérifie les droits, etc., pour des raisons de sécurité, il s'agirait d'un sinistre. Tout simplement parce que lorsque vous créez une API et créez vous-même des requêtes, vous devez analyser du point de vue de la sécurité uniquement le nombre limité de requêtes. Si les requêtes sont construites en dehors de votre système, vous avez potentiellement un nombre illimité d'astuces que quelqu'un pourrait faire.
Mais ce n'est pas le cas puisque vous utilisez une base de données clé-valeur (si je comprends bien, CouchDB entre généralement dans cette catégorie). L’interface de base de données elle-même est une sorte de couche intermédiaire et elle est testée pour des raisons de sécurité par l’équipe Apache. En raison de la simplicité de l’API JavaScript, il est encore plus facile d’analyser les failles potentielles que des interfaces aussi complexes que les applications JSF.
Cela peut constituer une solution sécurisée si vous effectuez des tests de sécurité complexes. Cela peut être encore plus facile lorsque vous utilisez des infrastructures telles que JSF, qui utilisent souvent des API difficilement lisibles. La sécurité par obscurité n'est considérée comme une solution.
En ce qui concerne votre question, il ne s'agira de toute façon pas d'un accès direct à la base de données. L'accès direct serait la construction de requêtes SQL en JavaScript (malheureusement, j'ai vu de telles solutions). Dans votre cas, CouchDB fournit lui-même la couche d’isolation. Vous pouvez bien sûr l'envelopper dans votre API pour la renforcer, mais tant que vous pourrez facilement tester ce que peut faire un utilisateur particulier et si les contraintes de sécurité fonctionnent pour vous, vous aurez une solution sécurisée et robuste sans couches supplémentaires.
la source
Je vois deux problèmes:
1. Couplage serré: Changer votre option de base de données? Eh bien, maintenant, vous devez aussi changer tout votre code côté client. Croyez-moi. Nous n'avons pas besoin de plus de problèmes du côté client.
2. Problème de sécurité TMI: révèle beaucoup trop de choses sur le fonctionnement des choses. L'authentification peut toujours être un obstacle, mais trouver un exploit est un enfer beaucoup plus facile lorsque vous savez exactement ce qui se passe sur le serveur.
Un niveau intermédiaire très très mince pourrait être une meilleure solution.
la source
Votre client ne peut pas utiliser votre application Web si javascript est désactivé (ou non pris en charge par le navigateur de son appareil) si javascript est la seule couche d'accès à la base de données.
la source