Come è possibile avvelenare il costruttore di array di array JavaScript e in che modo ECMAScript 5 lo impedisce?

11

Dalla documentazione di Django del loro JsonResponse :

Before the 5th edition of ECMAScript it was possible to poison the JavaScript Array constructor. For this reason, Django does not allow passing non-dict objects to the JsonResponse constructor by default. However, most modern browsers implement EcmaScript 5 which removes this attack vector. Therefore it is possible to disable this security precaution.

Come può essere pericoloso inviare dati dal server al browser sotto forma di un array JavaScript? Come si chiama un attacco del genere?

I miei esperimenti hanno dimostrato che, mentre Django di default si lamenta di aver inviato a un browser qualcosa del genere: ["foo", "bar"] , non si lamenta di aver inviato qualcosa del genere: {"foo": ["bar", "baz"]} Come può essere più sicuro inviare un array avvolto in un oggetto piuttosto che inviare una matrice "raw"?

In che modo EMCAScript 5 lo impedisce?

    
posta gaazkam 16.05.2017 - 14:02
fonte

1 risposta

10

L'attacco associato all'avvelenamento del costruttore Array è chiamato dirottamento JSON . È un'istanza di un problema noto come inclusione di script tra siti (XSSI) ciò deriva dal fatto che i browser in genere consentono ai siti Web di includere file JS esterni di origine incrociata.

Diciamo che un utente autenticato sul tuo sito può accedere ad alcuni "token segreti" in questa posizione dell'API:

https://yoursite.example/api/secret_tokens

E diciamo che la risposta dell'API assomiglia a qualcosa del tipo:

tokens = ["secret123", "secrect456"]

Questo crea una vulnerabilità. Un utente malintenzionato può banalmente esfiltrare i token di un utente che ha effettuato l'accesso inviando loro un link a evil.example che avrebbe un codice come questo:

<script src="https://yoursite.example/api/secret_tokens"></script><script>alert(tokens)</script>

Inquestomodo,ilbrowserdellavittimaèindottoainterpretarelarispostadell'APIcomeunfileJSesterno.L'APIcreainavvertitamentecodiceJSvalido(assegnandol'arrayaunavariabileglobaletokens)equindiperdendoitokendiunutentechehaeffettuatol'accessoaevil.example.

Ora,consideriamoilcasopiùprobabilechelarispostaAPIsiasimileaquesta:

["secret123", "secret456"]

Questo è ancora codice JS valido, ma poiché è solo un'espressione senza assegnazioni, un utente malintenzionato non può accedere al contenuto dell'array con la stessa facilità con cui si è sopra. La soluzione qui era semplicemente sostituire il costruttore di array:

Array = function() { foo = this; }

Questo particolare trucco era segnalato e risolto in Firefox nel 2007 ma da allora, altre tecniche, ad es. utilizzando Object.__defineSetter__ o Object.defineProperty , sono stati trovati (e risolti).

How does EMCAScript 5 prevent that?

Le richieste di specifiche ES5 che [] utilizza sempre la% incorporataArray constructor (e lo stesso vale per i costruttori di oggetti):

15.4.1.1 Array ( [ item1 [ , item2 [ , … ] ] ] )

Create and return a new Array object exactly as if the standard built-in constructor Array was used in a new expression with the same arguments (15.4.2).

Infine, consideriamo il caso in cui l'API risponde con un oggetto JSON:

{"tokens": ["secret123", "secret456"]}

La semplice ragione per cui non è mai stato vulnerabile è che è JS non valido: un oggetto isolato tra parentesi graffe è analizzato come blocco invece di un oggetto . Pertanto non è possibile includere questo oggetto JSON come script esterno senza che si verifichi un errore. Storicamente, l'attivazione di un errore di sintassi è stato un modo conveniente per prevenire attacchi XSSI.

Ecco alcuni riferimenti aggiuntivi a JSON Hijacking:

risposta data 16.05.2017 - 14:58
fonte

Leggi altre domande sui tag