Comment envoyer sécuriser les requêtes AJAX avec PHP et jQuery
Le problème
Donc, pour un certain temps maintenant, j'ai fait des expériences avec différents AJAX approches dans l'envoi de données à un serveur qui seront traitées et stockées dans une base de données MySQL.
La page de la requête AJAX hits api.php
, utilise PHP PDO préparées pour enregistrer les données, MySQL injections ne sont pas vraiment un problème et que les mots de passe ou des données qui doivent être chiffrées sont également traitées par api.php
ce qui n'est pas ce que je demande ici. Ma question porte davantage sur la façon d'assurer la sécurité des données lors du transfert à partir du client vers le serveur.
Les approches
J'ai actuellement (pour la connexion exemple, j'ai inclus ci-dessous):
- Certificat SSL/HTTPS en cours d'exécution sur le domaine.
- Certains requête AJAX (évidemment pas à cette demande de connexion exemple qu'il n'y a pas de session pour commencer) ne fonctionnera que si la Session PHP est valable sur tout le site (utilisé sur les deux
login.php
etapi.php
dans cet exemple). - La limitation du débit sur
api.php
lors de l'accès aux fonctions. - PHP PDO préparées lors de l'interaction avec la base de données à l'intérieur de
api.php
. - Le cryptage des données sensibles à l'intérieur de
api.php
(pas pertinente pour la question).
Les questions
Enfin, mes questions sont les suivantes:
- Est cette approche à l'aide de HTTP asynchrones (Ajax) les demandes suffisamment en sécurité pour l'utilisation, plutôt que de simplement transmettre des données à une page PHP et la redirection de partir? (Ce qui améliore l'expérience de l'utilisateur).
- Comment puis-je vérifier pour savoir que les données de mon utilisateur l'envoi n'a pas été altéré?
- Suis-je raisonnablement faire assez pour protéger mes données de l'utilisateur, sinon, que puis-je faire?
L'exemple
Je comprends que tout le monde a différentes approches de la gestion de leurs données du site et le transport de données. Je comprends aussi que peu importe ce que vous faites, vous ne pouvez jamais être protégé à 100%, il y a peut-être des vulnérabilités et des moyens autour de votre système que vous ne pouvez pas le prendre en compte. Je suis à la recherche de commentaires, améliorations sur mon approche générale dans l'envoi de données en toute sécurité plutôt que critique de la spécifique de code ci-dessous n'est qu'un exemple. Mais toutes les réponses constructives sont les bienvenus. Merci de prendre le temps de lire/réponse.
function loginUser() {
var process = "loginUser";
var data = $("form").serializeArray();
data[1].value = SHA512(data[1].value); //sha then encrypt on api.php page
data = JSON.stringify(data);
$("#loginButton").html('<i class="fa fa-spinner fa-pulse fa-lg fa-fw"></i> Login');
$.ajax({
type: "POST",
url: "api.php",
data: {"process": process, "data": data},
success: function(data) {
if (data.response.state == "success") {
//if api.php returns success, redirect to homepage
} else {
//if api.php returns failure, display error
}
},
error: function(jqXHR, textStatus, errorThrown, data) {
//error handling
},
dataType: "json"
});
}
- 1. oui 2. le SHA512 est mignon, mais si quelqu'un peut modifier les données en transit, ils peuvent mettre à jour la table de hachage aussi, donc ne vous embêtez pas avec elle. 3. utiliser https pour assurer l'intégrité
Vous devez vous connecter pour publier un commentaire.
1. Vérifier l'en-tête d'ORIGINE
Comme spécifié par l'OWASP, ce n'est pas assez, mais recommandé :
Et par Mozilla :
La vérification de la
HTTP_ORIGIN
en-tête peut être écrite comme :1. (bis) Vérifier l'en-tête REFERER
Nouveau à partir de l'OWASP :
La vérification de la
HTTP_REFERER
est également très simple en PHP avec$_SERVER['HTTP_REFERER']
, vous pouvez simplement mettre à jour le code ci-dessus avec elle.ÊTRE PRUDENT avec la vérification qui a toujours besoin d'être très précis : ne pas cocher juste example.com ou api.example.com mais l'ensemble de la https://example.com. Pourquoi ? Parce que vous pourrait usurper cette case à l'origine comme api.example.com.hacker.com.
2. Générer des jetons CSRF
Bien expliquées réponse spécifique à PHP a été donné il y, en bref :
Générer le jeton :
L'ajouter dans votre "vues" par l'intermédiaire d'un méta (comme Github) :
Installation de jQuery ajax appels d'inclure ce jeton :
Côté serveur, vérifiez vos requêtes AJAX :
La plupart des frameworks PHP ont leur propre CSRF de la mise en œuvre, ce qui est plus ou moins sur le même principe.
3.
Désinfectervalider la saisie de l'utilisateur.Vous devez
filtreespace des entrées et valider.4. Protéger votre serveur
5. Ne faites jamais confiance à la saisie de l'utilisateur
Comme @blue112 dit, il est l'un des plus élémentaires les principes de la sécurité.
X-Requested-With
est un non-d'en-tête standard qui n'a jamais dit à vous que l'URL qui a initié la demande. C'estOrigin
, qui est facilement falsifiés si l'attaquant n'est pas une attaque CSRF.openssl_random_pseudo_bytes()
pour la génération aléatoire d'octets?random_bytes
.Réponse courte: vous ne pouvez pas protéger votre côté client.
Réponse longue:
Vous ne pouvez pas faire quelque chose pour rendre le navigateur de prouver qu'il est en fait votre code javascript qui s'exécute côté client.
Ensuite, la première action à entreprendre est la plus simple: ne faites JAMAIS CONFIANCE à la SAISIE de l'UTILISATEUR.
- Ce à dire, comme vous avez commencé à faire, la sécurisation de votre côté serveur à l'aide de session, limite de vitesse, la validation des données, fail2ban (interdiction ip d'un client après un certain nombre d'échec), la surveillance des journaux...
integrity
attrib et un hachage sur la balise script. ça ne pourra pas prouver qu'il est le seul de JS en cours d'exécution, mais il faudra prouver votre JS devriez avoir exécuté.le meilleur moyen est encore de le faire côté serveur sécurisation et si j'étais un utilisateur connecté sur le site, je voudrais être capable de vérifier le jeton csrf sur ma balise meta et de forger un script sur le serveur. Ainsi, le pari sûr est côté serveur de validation