2017-07-30 1 views
1

Je veux savoir comment la fonction suivante définit l'élément 'this' et extrait la cellule du tableau? S'il vous plaît.Problème de sécurité JavaScript

//my secure code 
 
var priv = ['item-0','item-1']; 
 
var api = {push: function(x){priv.push(x)}} 
 

 
api.store = function(i,x){priv[i] = x} 
 

 
//the attaker script 
 
var result; 
 
api.store('push',function(){result = this[0]}); 
 
api.push(); 
 

 
//the result is cell 0 of private array 
 
//how? 
 
//if i change the 'push' parameter then the result is empty! 
 
document.write(result)

+0

Le mot-clé 'this' peut avoir différentes significations selon le contexte. Vous n'avez déclaré nulle part la variable 'result', donc par défaut il a la portée globale, c'est pourquoi il devient disponible en dehors de la fonction. Pourriez-vous fournir plus de détails sur votre problème? – CROSP

+0

@CROSP J'ai un contenu critique, et je veux les garder en sécurité. un de mes amis m'envoie ce code et je réalise qu'il peut accéder à des variables privées, en utilisant mes objets API. – easa

+0

@easa Si un attaquant peut exécuter du code arbitraire dans le même environnement, vous avez généralement déjà perdu. Qu'est-ce que vous essayez de protéger exactement? – Bergi

Répondre

4

Ce qui se passe est que api.store('push',function(){result = this[0]}); remplace la méthode push du tableau priv. Cela signifie qu'après cette ligne push n'est plus la méthode push que javascript fournit nativement mais la fonction personnalisée des attaquants, qui est function(){result = this[0]}. Maintenant, lorsque vous appelez api.push(), il appelle priv.push(x) qui a été remplacé. Puisque push est appelé sur un objet, this est lié à l'objet, qui est priv (plus sur cela in the MDN article on this). Par conséquent, result = this[0] est égal à result = priv[0] et le résultat contiendra la première entrée du tableau.

+0

Je n'arrive pas à comprendre comment elle a été surchargée? Dans quelle ligne? Comment? – easa

+0

'api.store ('push', function() {result = this [0]});' appelle 'api.store = fonction (i, x) {priv [i] = x}'. Ici, 'i' est push et x est la fonction que votre attaquant a réussi. Cela signifie que vous exécutez effectivement 'priv [" push "] = function() {result = this [0]}' qui est égal à 'priv.push = function() {résultat = ce [0]}' (d'où, remplacer la méthode "push"). –

+0

merci Daniel :-) – easa