Suis-je en train de faire une ingénierie excessive si je considère un acte répréhensible intentionnel de l'utilisateur?


12

Est-ce une ingénierie excessive si j'ajoute une protection contre les actes répréhensibles intentionnels d'un utilisateur (pour le dire légèrement), si le préjudice que l'utilisateur peut subir n'est pas lié à mon code?

Pour clarifier, j'expose un service JSON RESTful simple comme celui-ci:

GET /items - to retrieve list of user's items
PUT /items/id - to modify an item
POST /items - to add a new item

Le service lui-même n'est pas destiné à être utilisé via un navigateur, mais uniquement à partir d'applications tierces, contrôlées par l'utilisateur (comme les applications téléphoniques, les applications de bureau, etc.). De plus, le service lui-même doit être sans état (c'est-à-dire sans session).

L'authentification se fait avec l'authentification de base sur SSL.

Je parle d'un comportement "nuisible" possible comme celui-ci:

L'utilisateur saisit l'URL GET dans un navigateur (pas de raison mais ...). Le navigateur demande l'authentification de base, la traite et stocke l'authentification pour la session de navigation en cours. Sans fermer le navigateur, l'utilisateur visite un site Web malveillant, qui possède un javascript CSRF / XSRF malveillant qui effectue un POST à ​​notre service.

Le scénario ci-dessus est hautement improbable et je sais que d'un point de vue commercial, je ne devrais pas trop m'inquiéter. Mais pour améliorer la situation, pensez-vous que si le nom d'utilisateur / mot de passe est également requis dans les données JSON POST, cela vous aidera-t-il?

Ou dois-je supprimer complètement l'authentification de base, me débarrasser de GET et utiliser uniquement POST / PUT avec des informations d'autorisation? Comme les informations récupérées à travers GET peuvent également être sensibles.

D'un autre côté, l'utilisation d'en-têtes personnalisés est-elle considérée comme une implémentation REST pure? Je peux supprimer l'authentification de base et utiliser des en-têtes personnalisés. De cette façon, au moins une attaque CSRF à partir d'un navigateur peut être évitée, et les applications qui utilisent le service définiront le nom d'utilisateur / mot de passe dans la bruyère personnalisée. Mauvais pour cette approche, c'est que le service ne peut plus être consommé depuis un navigateur.


3
En plus de ma réponse, je voudrais également laisser cette déclaration, je pense qu'il serait probablement mieux répondu sur SO ou Security
Jeff Langemeier

1
Je pense que vous avez changé PUT et POST comme défini par RFC 2616 ( tools.ietf.org/html/rfc2616#section-9.5 ).
Svante

Réponses:


6

Sur-ingénierie? Pas du tout. Les mesures anti-XSRF sont une partie nécessaire de toute application ou service Web sécurisé. Il peut ou non être «hautement improbable» que quelqu'un choisisse de vous attaquer, mais cela ne rend pas votre logiciel moins dangereux.

Les systèmes ont généralement été attaqués à l'aide de XSRF, et bien que les résultats soient moins immédiatement - évidemment mauvais que l'injection SQL ou XSS, ils sont assez mauvais pour compromettre toutes les fonctionnalités interactives de l'utilisateur.

Cela signifie que vous ne pouvez pas avoir une interface RESTful «pure» où les seuls paramètres sont les propriétés de l'appel lui-même. Vous devez inclure quelque chose dans la demande qu'un attaquant ne pourrait pas deviner. Cela pourrait être la paire nom d'utilisateur-mot de passe, mais c'est loin d'être le seul choix possible. Vous pouvez avoir un nom d'utilisateur avec un jeton généré à partir d'un hachage salé du mot de passe. Vous pourriez avoir des jetons émis par le service lui-même au moment de l'authentification (qui pourraient être mémorisés dans la session ou vérifiés cryptographiquement).

dois-je me débarrasser du GET

Non, les requêtes GET sont utilisées pour les requêtes de lecture qui n'ont aucune opération d'écriture active (elles sont «idempotentes»). Ce ne sont que des opérations d'écriture qui nécessitent une protection XSRF.


Que faire si la demande GET peut révéler des informations sensibles?
Sunny

@Sunny: Que considérez-vous comme des données sensibles?
Chris

2
Chris, si je deviens paranoïaque, toutes les données sont sensibles, si elles sont reçues par le "mauvais" utilisateur :). C'est théorique.
Sunny

pls, passez en revue les changements dans la question que j'ai ajoutée.
Sunny

1
C'est bien que la réponse (qu'elle soit GET ou autre méthode) contienne des données que seul l'utilisateur devrait voir. Une attaque XSRF permet uniquement à l'attaquant de demander à l'utilisateur de faire une demande particulière, il ne lui permet pas de lire la réponse qui revient de cette demande. À moins que le script cible ne soit construit de manière spéciale pour permettre aux pages tierces de le lire à partir d'une <script>balise, délibérément («JSONP») ou accidentellement ( JSON non protégé ).
bobince

32

Ne faites jamais confiance à rien. Chaque demande est une attaque. Chaque utilisateur est un hacker. Si vous développez avec cet état d'esprit, votre application sera beaucoup plus sécurisée, stable et moins susceptible d'être détournée par un utilisateur malveillant. Tout ce qu'il faut, c'est une personne intelligente pour trouver un moyen de contourner votre sécurité pour que vous ayez de sérieux problèmes avec vos données (l'une de vos ressources les plus précieuses ).

Si vous avez identifié une faille de sécurité dans votre application, faites tout ce que vous pensez que vous devez faire pour combler l'écart. Votre API, en particulier, devrait être le logiciel le moins fiable qui existe. Je voudrais les informations d'identification et aller avec les demandes de poste.


4
YAY pour la paranoïa! Vous avez des ennemis! (Et +1 pour chaque demande est une attaque )
Treb

0

Si le code est établi et maintenu, les cas marginaux devraient être examinés et traités au cas par cas.

FIXANT EN RAISON DE CERTAINES ERREURS DE MA PART:

GET doit toujours être utilisé dans le cadre d'un service RESTful approprié, l'authentification doit toujours être là dans tous les cas. Ce que j'essayais de supposer, c'est que pour des raisons de sécurité, GET est à peu près la même chose que POST, mais la publication fait son travail sans mettre les informations dans une barre d'adresse, ce qui tend à être la grande différence de sécurité (et pourquoi je n'aime pas GET), mais comme publié par @Lee,

GET requests are used to retrieve resources, and PUT/POST are used to add/update 
resources so it would be completely against expectations for a RESTful API to use
PUT/POST to get data. 

Étant donné que cela sera utilisé par des applications tierces, il convient de suivre les bonnes pratiques pour un service RESTful afin que l'implémenteur final ne soit pas confus sur cette partie.


3
En quoi GET diffère-t-il de POST en termes de sécurité? Les deux sont envoyés en clair sur le transport (HTTP ou HTTPS), la seule différence est que les chaînes de requête GET sont visibles dans la barre d'adresse.
tdammers

1
@Sunny: POST est tout aussi exposé que GET à cet égard. Lancez telnet et parlez à un serveur Web si vous ne me croyez pas.
tdammers

1
@Jeff: La raison pour laquelle j'utilise telnet (ou curl, wget ou un bon renifleur à l'ancienne) est qu'il vous permet de voir le flux de données complet. Oui, HTTPS cache ces informations aux écoutes indiscrètes, mais n'importe qui à chaque extrémité de la connexion SSL peut voir exactement ce que telnet voit.
tdammers

1
@Jeremy: POST n'affiche pas les paramètres dans la barre d'adresse, mais comme les données sont tout aussi visibles dans le flux HTTP réel, vous avez raison dans l'ensemble.
tdammers

7
Les requêtes GET sont utilisées pour récupérer des ressources, et PUT / POST sont utilisées pour ajouter / mettre à jour des ressources, il serait donc totalement contraire aux attentes d'une API RESTful d'utiliser PUT / POST pour obtenir des données.
Lee

0

Vous devez considérer toutes les éventualités plausibles, y compris l'utilisateur étant activement malveillant et inversant (avec succès) toute barrière de «sécurité par obscurité».

Mais en même temps, vous devriez évaluer l'impact d'un piratage réussi et la probabilité d'une tentative. Par exemple:

  • Un service interne protégé par un pare-feu solide est moins susceptible d'être attaqué qu'un service sur Internet public.

  • L'impact de la suppression d'un forum de discussion client est inférieur à l'impact du vol de cartes de crédit client.


Mon point est que la "sécurité totale" est "infiniment chère" ... et pratiquement irréalisable. Idéalement, vous devriez prendre vos décisions sur le point de tracer la ligne sur la base d'une analyse coûts-avantages approfondie.


Merci. La question n'était pas de protéger "contre" l'utilisateur, mais de protéger l'utilisateur lui-même s'il agit de manière irresponsable. Mais votre réponse fait peu de bons points.
Sunny
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.