Come proteggere i dati dell'applicazione Web da un Javascript iniettato?

-1

Ho un'applicazione web che interagisce con due server web. La risposta del primo viene memorizzata temporaneamente nel browser (window.xyz = response.xyz) e quando l'utente effettua la richiesta per il secondo server, inviamo questi dati come uno dei parametri.

Ora questo non è sicuro come se qualcuno avesse un'estensione per browser malevola installata nel browser, può iniettare javascript ed esporre le variabili.

Quale sarebbe un buon modo per proteggersi da tali possibilità? Ho la sensazione che ci sia una soluzione piuttosto semplice a cui gli sviluppatori non hanno pensato. È possibile utilizzare variabili locali passate come parametri ad altre funzioni? Non ho familiarità con Javascript.

Ulteriore contesto: sono principalmente interessato a garantire che lo script dannoso non possa esporre le variabili e utilizzarle per richieste false

    
posta Limit 27.06.2017 - 18:34
fonte

3 risposte

3

Se ti capisco correttamente, vuoi trasferire le informazioni dal server A al server B attraverso il browser degli utenti, ma non ti devi fidare del browser poiché potrebbe esserci un'estensione malevola o simile che modifica i dati all'interno del browser prima di inviarlo a B.

Non penso che sul lato client ci sia qualcosa che rende impossibile la modifica, cioè non ci si può fidare del browser in alcun modo. Quindi, se davvero insisti nel trasferire i dati usando il browser, devi avere un altro modo per assicurarti che nessuno abbia manomesso i dati, ad esempio qualcosa di cui puoi fidarti al posto del browser.

La mia scelta sarebbe che dovresti fidarti del server A, perché hai già bisogno di fidarti di A comunque poiché questa è la fonte dei dati. Quindi devi assicurarti che i dati siano realmente originati sul server A. Il modo tipico per farlo è usare le firme digitali: il server A ha una coppia di chiavi, il server B conosce la chiave pubblica, il server A firma i dati con il suo privato la chiave e il server B possono convalidarli con la chiave pubblica. Un'altra opzione sarebbe quella di avere un segreto condiviso tra A e B e usarlo all'interno di un HMAC.

In questo modo verrà rilevata qualsiasi manipolazione dei dati, indipendentemente da dove avvengono queste manipolazioni tra A e B.

    
risposta data 27.06.2017 - 19:27
fonte
1

Quello che stai veramente chiedendo è come limitare l'impatto di un attacco XSS. Sfortunatamente, dato il tuo scenario, non c'è molto che tu possa fare, dal momento che il token deve essere accessibile in JavaScript per ottenerlo dal Server A. La soluzione migliore sarebbe implementare una politica di sicurezza dei contenuti strong (CSP). CORS non si applica a questo scenario.

Non ho molta familiarità con il modo in cui CSP si applica ai plug-in, ma non penso ci sia nulla che possa essere fatto per proteggersi da un plugin dannoso.

    
risposta data 27.06.2017 - 20:10
fonte
1

JS utilizza un modello di sicurezza basato su riferimenti, quindi se la tua estensione non può ottenere un riferimento al segreto, non può accedere al segreto. A meno che l'estensione controlli (e sovrascrive) il caricamento degli script di pagina, uno script può essere costruito per condividere segreti in un modo in cui il codice pre-run o post-run non può interferire direttamente con.

La parte difficile è l'autenticazione della parte bisognosa perché un getSecret () ingenuo è poco più sicuro di window.secret = blah. Introduci le due parti, consenti loro di autoregolarsi senza variabili pubbliche, e quindi elimina ulteriori riferimenti. Questo ti permetterà di collegare i due pezzi in modo tale da poter essere tagliato, ma non tappato o falsificato.

// this part contains a secret only specific other code should see:
var hasSecret=(function(){ 
 var mySecretRef; // an object refrence, to be populated at run-time
 var mySecretData = ["I like anchovies"]; // in array so it can be updated later
 var out={};
 out.meet=function(obj){
    mySecretRef = obj;  // bake-in a specific object
    delete out.meet; // burn this bridge
    // define a method that can only use the non-replaceable baked-ins:
    out.reveal= mySecretRef.obtain.bind(mySecretRef, mySecretData); 
    Object.freeze(out); // just for easier debugging on attempts under global "use strict"
 };

 return out;
}());


// this code needs a secret that no other code should see and only one part has (the above)
var getSecret={ 
 obtain: function(secret){
   prompt("The Secret Is", secret || "N/A"); // (instead of demo prompt(), custom app-logic goes here)
 }
};


// kick the tires a little bit:
hasSecret.meet(getSecret); // bake-in object relationship, the prime "feature" of this pattern
hasSecret.reveal = Boolean; // attack:  try to over-ride reveal()
getSecret.obtain(); // attack: obtain() can be manually called, but has no secret data
hasSecret.reveal() // legit: shows "I like anchovies" (the secret) by calling getSecret.obtain() callback
getSecret.obtain = function(secret){ return "This is a fake secret";}; // attack: try to over-ride obtain()
hasSecret.reveal() // legit: shows "I like anchovies" still, as desired
hasSecret.meet({}); // attack: remeet (throws error since meet() is gone

Naturalmente, questo potrebbe mettere una porta del caveau di una banca su una tenda se l'oggetto XMLHttpRequest viene manomesso, gli script della pagina vengono sostituiti completamente con un'estensione o se il server non è HTTPS. In breve, mentre lo schema del modulo rivelatore dovrebbe essere a prova di proiettile, l'applicazione del modello potrebbe non essere.

EDIT: assicurati di non codificare i dati segreti nel codice sorgente, ma piuttosto di recuperare i dati, impostare mySecretData e quindi chiamare immediatamente meet() .

    
risposta data 27.06.2017 - 22:23
fonte