Codifica lato client: come prevenire l'uso dannoso?

59

Negli ultimi anni, la tendenza per le applicazioni lato client (browser) è davvero decollata.

Per il mio ultimo progetto, ho deciso di provare a spostarmi con i tempi e scrivere un'applicazione client-side.

Parte di questa applicazione comporta l'invio di e-mail di transazione agli utenti (ad esempio, convalida della registrazione, e-mail di reimpostazione della password, ecc.). Sto utilizzando un'API di terze parti per inviare le email.

Normalmente avrei la mia applicazione in esecuzione su un server. Chiamerei l'API di terze parti dal codice sul mio server.

L'esecuzione di un'applicazione sul lato client significa che ora deve avvenire sul browser di un utente. L'API di terze parti fornisce i file JavaScript necessari per raggiungere questo obiettivo.

Il primo problema lampante che riesco a vedere è che devo usare una chiave API. Questo normalmente verrebbe salvato in modo sicuro sul mio server, ma ora presumibilmente dovrò fornire questa chiave al browser client.

Supponendo di poter aggirare questo problema, il problema successivo è quello di impedire a un utente esperto di tecnologia di caricare lo strumento per sviluppatori JavaScript su un browser e utilizzare l'API di posta elettronica a loro piacimento, piuttosto che aderire a qualsiasi regola che ho impostato nell'applicazione.

Suppongo che la mia domanda generale sia: come possiamo impedire l'uso dannoso di un'applicazione client-side?

    
posta Gaz_Edge 30.07.2014 - 15:09
fonte

8 risposte

196

Non puoi, e più persone capiscono questo, e più a fondo capiscono, meglio è per il mondo.

Il codice che gira su un dispositivo sotto il controllo dell'utente non può essere controllato. Gli smartphone possono essere jailbroken. I set-top box possono essere incrinati. I browser ordinari non tentano nemmeno di impedire l'accesso al codice JavaScript. Se hai qualcosa che valga la pena di rubare o abusare, un determinato attaccante sarà in grado di farlo a meno che tu non convalidi tutto ciò che ami sul lato server.

L'offuscamento è di pochissimo aiuto; il tipo di avversario che attirerai non appena tutto ciò che è remoto è coinvolto legge il linguaggio assembly come annunci pubblicitari. La crittografia non può aiutarti, perché il dispositivo che protegge la chiave è lo stesso dispositivo che devi assumere è rotto. Ci sono molte altre contromisure apparentemente ovvie che non funzionano, per ragioni simili.

Sfortunatamente, questa è una verità molto scomoda. Il mondo è pieno di operatori di piccole e grandi dimensioni che pensano di poter in qualche modo aggirare la fondamentale rottura della fiducia a distanza, semplicemente perché sarebbe oh così bello se potessimo assumere che il nostro codice essere eseguito nel modo in cui abbiamo assunto. E sì, renderebbe tutto molto più semplice che non fosse nemmeno divertente. Ma il desiderio non è così, e sperare contro la speranza che tu sia l'unico biscotto intelligente che può evitare la spiacevolezza, brucerà solo te e i tuoi clienti. Pertanto, prendi in considerazione che Internet è territorio nemico, includi quel costo aggiuntivo nelle tue stime e starai bene.

Detto questo, ovviamente c'è una cosa come la difesa in profondità. L'offuscamento del tuo JavaScript non rimanda un determinato attaccante, ma può rimandare alcuni aggressori meno determinati. Se le tue risorse valgono abbastanza per proteggere, ma non ad ogni costo, una di queste misure potrebbe aggiungere valore aziendale al tuo sistema; semplicemente non può essere perfetto. Finché sei pienamente consapevole del compromesso che stai facendo, potrebbe essere una strategia ragionevole.

    
risposta data 30.07.2014 - 15:20
fonte
68

La regola qui è:

Fai tutto il lato client che non influisce su nessun altro se l'utente lo manomette. In particolare, ciò significa effetti grafici.

Fai tutto il lato server che deve essere sicuro e invia semplicemente gli eventi dell'interfaccia utente dal client (ad esempio, il client dice semplicemente "l'utente ha toccato il pulsante Acquista" mentre il server esegue effettivamente la transazione). In particolare, ciò significa transazioni finanziarie.

    
risposta data 30.07.2014 - 19:53
fonte
28

Questo è esattamente il caso in cui renderlo completamente client-side è non appropriato.

Puoi fare la logica e la convalida di base dei moduli lato client (devi ancora convalidare il server, perché qualcuno potrebbe provare a fingere la richiesta) per migliorare la reattività, puoi fare richieste HTTP da JavaScript che passa i dati là e ritorno in JSON per evitare di inviare nuovamente le decorazioni delle pagine e simili, ma se la transazione stessa deve essere autenticata e autorizzata, dovrebbe comunque succedere su un server.

    
risposta data 30.07.2014 - 15:22
fonte
18

Il tuo secondo paragrafo è il cuore del problema:

Running a client side app means this now needs to happen on a users browser. The third party API provides the necessary js files to achieve this.

Perché un'app lato client significa che non puoi avere un lavoro lato server? La spinta verso la programmazione lato client non riguarda l'eliminazione dei server, ma l'utilizzo di nuove tecnologie che i browser finalmente supportano per creare interfacce utente migliori.

Come per il file .js che hai ricevuto, sei sicuro che sia pensato per un browser? Potrebbe essere una libreria node.js?

    
risposta data 30.07.2014 - 23:43
fonte
11

Facciamo un passo indietro e guardiamo a un livello più alto .. dobbiamo ... Eudora o outlook (un'app client, che non ha nemmeno bisogno di un browser) causano mai una perdita finanziaria per qualsiasi azienda? No. Chiunque può scrivere alle API POP / SMTP e essere il cliente. Ma nessuna perdita per il server. Il server non ha limitato le azioni, i calcoli, la conservazione, la temperatura, le dimensioni del disco, le dimensioni del ram, il monitor DPI, GPU, FPU yada yada del client ma ha specificato esattamente a cosa avrebbe risposto e non più. Hai mai sentito parlare di quicken o di MS-Money che vengono usati per rompere in banca?

La tua app browser (ad esempio lato client) può utilizzare la stessa architettura.

  1. Costruisci il tuo server con un'API (che a proposito, si riduce sempre alle derivate di GET POST HEAD ecc.).
  2. Sul server, assicurati che l'API parli solo con un client autenticato e verificato con identità per ogni chiamata.
  3. Quindi non ti interessa chi è il cliente.
  4. E poi non ti importa se è un browser, un dispositivo jailbroken, un Google glass, un DOS 3.1 o un nuovissimo Nexus nelle mani di un tecnofobo tris grandino che ha viaggiato nel tempo fino al 2014 e ha mancato tutta la tecnologia che ha inondato le nostre vite negli ultimi 15 decenni.
  5. Ora puoi iniziare a caricare tutto il resto sul lato client.

SoapBoxBegin

@KilianFoth solleva un importante punto di consapevolezza per gli ingenui e gli spericolati, soprattutto quelli che leggono sempre i titoli, ma non pensano mai che accadrà alla loro app, al loro codice, al loro datore di lavoro, al loro cliente, al proprio conto bancario. Ancora più spericolati sono i loro datori di lavoro (in particolare i CTO) che consentirebbero l'uscita di app che espongono i sistemi all'esposizione non gestita / non controllata. Tuttavia sono sempre perplesso su come sembra "non impariamo mai".

SoapBoxEnd

Quindi per riassumere. Crea un'API lato server solida e stretta. Scarica tutto il resto sul client in base a ciò che il client può gestire.

    
risposta data 31.07.2014 - 06:57
fonte
6

Direi che non puoi davvero. Se sei disposto a inviare i dati al cliente, devi aspettarti che venga abusato, comunque possibile. Il tuo esempio riguardante la chiave API è illustrativo del punto, e non lo includerei nel tuo client JS - sarà rubato e abusato.

Avrai sicuramente ancora bisogno di una certa quantità di codice server per mantenere le cose al sicuro. Anche qualcosa di semplice come recuperare solo i dati relativi all'utente connesso. Questa autenticazione non può essere eseguita dal lato client o ancora ne trarrai vantaggio e i tuoi dati non saranno al sicuro.

Vorrei sempre vedere l'esperienza lato client JS come un'aggiunta al codice del server. La convalida sul client fornisce una buona esperienza utente, ma se non si verificano i dati POST sul server ricevente, si apre la porta all'attacco. Qualsiasi cosa proveniente dal cliente dovrebbe essere considerata sospetta.

    
risposta data 30.07.2014 - 15:20
fonte
4

È abbastanza semplice, davvero. Supponiamo che il computer client e tutto il software in esecuzione su di esso è sotto il controllo completo di un hacker malintenzionato intelligente.

Ciò significa che qualsiasi informazione che invii dal server al client sarà nota all'hacker malintenzionato, quindi devi assicurarti di non inviare alcuna informazione al client che potrebbe essere utilizzata per attaccare il tuo server o la tua azienda.

Significa anche che qualsiasi cosa inviata dal client al server è stata prodotta dall'hacker malintenzionato, quindi il codice del server deve assicurarsi che nulla che il client possa inviare sia in grado di attaccare con successo il tuo server.

Certo, l'implementazione è un problema, ma la cosa importante è l'atteggiamento mentale, il presupposto che il "client" con cui si pensa che il server stia parlando non è un client ma un aggressore attivo.

(Devi anche assumere che l'utente sia un intelligente truffatore che proverà ad attaccare i tuoi metodi di business, ma questo non ha nulla a che fare con la programmazione lato client).

    
risposta data 03.08.2014 - 01:49
fonte
0

L'applicazione lato client, a mio parere, riguarda principalmente l'interfaccia utente. Ad esempio, tutto il tuo sistema di interfaccia utente verrà inviato una sola volta al client, e quindi il client farà tutto ciò che vuole con esso.

Normally I would have my application running on a server. I would call the third-party API from code on my server.

Running a client-side application means this now needs to happen on a user's browser. The third-party API provides the necessary JavaScript files to achieve this.

Se si dispone di una chiave API, quindi non è destinato a lavorare sul lato client. Se si fornisce la chiave API sul lato client, chiunque può accedervi e quindi utilizzarla per il proprio scopo. Archivialo e usalo lato server quando il cliente ne ha bisogno, quindi invia il risultato usando Ajax / WebSockets.

È come se la tua banca stesse dicendo: "Bene, inserirò la password del lato client del database principale in modo che il client possa richiederlo da sé e non disturberà più i nostri server."

    
risposta data 01.08.2014 - 16:40
fonte

Leggi altre domande sui tag