Restituisce il codice di risposta HTTP sbagliato di proposito?

36

Sto scrivendo una semplice API REST e voglio limitare l'accesso solo al mio client mobile. In altre parole, sto cercando di impedire a un utente malintenzionato, ad es. usando arricciatura per fare una richiesta POST non autorizzata.

Ovviamente, questo è impossibile. Tuttavia, esistono alcune contromisure che rendono difficile il successo di un hacker. In questo momento, sto crittografando tutte le richieste con una chiave privata, memorizzata sul lato client (ovviamente, questo non è l'ideale, ma la difficoltà nel reverse-engineering di un'app per iOS si spera che scoraggerà tutti tranne gli hacker più determinati).

Una semplice idea che ho avuto è di restituire il codice di risposta HTTP sbagliato per una richiesta non autorizzata. Piuttosto che restituire un "401 non autorizzato", perché non tornare, ad es. "305 Use Proxy", ovvero confondendo intenzionalmente. Qualcuno ha mai pensato di farlo?

    
posta mpl 08.02.2017 - 19:25
fonte

11 risposte

83

Has anyone ever thought about doing this?

Sì, c'era effettivamente un discorso su esattamente questo a defcon 21 ( video , slides ).

La loro conclusione è stata che lavorare con i codici di risposta come protezione offensiva può a volte rallentare severamente gli scanner automatici, gli scanner non funzionanti e una quantità massiccia di falsi positivi o falsi negativi (ovviamente non farà quasi nulla per scansioni manuali).

Mentre la sicurezza per oscurità non dovrebbe mai essere la tua unica difesa, può essere utile come difesa in profondità (un altro esempio: si raccomanda di non trasmettere i numeri di versione di tutti i componenti usati).

D'altro canto, un'API REST dovrebbe essere il più pulita possibile e rispondere con codici HTTP volutamente sbagliati potrebbe confondere gli sviluppatori e i client legittimi (questo è un po 'meno un problema per i browser, dove gli utenti non lo fanno effettivamente vedere i codici). Per questo motivo non lo consiglierei nel tuo caso, ma è comunque un'idea interessante.

    
risposta data 08.02.2017 - 19:47
fonte
58

In realtà non rallenterà in modo significativo un attaccante, ma farà sì che i futuri sviluppatori che lavorano sulla tua piattaforma siano davvero infastiditi da te. Potrebbe anche far sì che alcune caratteristiche interessanti delle tue librerie di richieste HTTP non siano così belle, dato che stanno funzionando a partire da informazioni errate.

Questa è una forma molto debole di sicurezza attraverso l'oscurità . Quando progetti un sistema come questo, dovresti pensare a rallentare un attaccante di centinaia di anni, non di decine di minuti - altrimenti perderai ancora.

    
risposta data 08.02.2017 - 19:34
fonte
8

Rather than return a "401 Unauthorized," why not return e.g. "305 Use Proxy," i.e. purposely being confusing.

Sì, confonderà un attaccante. Ma per uno addestrato, potrebbe non essere più di due secondi piatti. E i codici di stato non sono poi così utili, soprattutto quando i nomi dei file forzanti sono brute.

Supponiamo di avere una chiave valida e posso osservare che stai restituendo codici a 200 gamme per la mia autenticazione. Se cambio un po 'nella mia chiave, e per ogni richiesta torni 305, immediatamente penserò "Hmm. Sembra che lo sviluppatore potrebbe aver incasinato". Se restituisci codici casuali, saprò che è stato fatto apposta e li ignoro.

the difficulty in reverse-engineering an iOS app will hopefully deter all but the most determined hackers

Sì, ma dal momento che ne impiega solo uno per pubblicarlo, lo rallenta di nuovo ..

    
risposta data 08.02.2017 - 19:45
fonte
6

Questa è sicurezza attraverso l'oscurità, il che vuol dire che non fornisce molta sicurezza. La soluzione che stai suggerendo rallenterà solo un aggressore, non gli impedirà di utilizzare il proprio client. In effetti, il metodo di crittografia delle richieste, a seconda dell'implementazione, potrebbe rendere la tua applicazione meno sicura aprendo attacchi ad altre parti del sistema crittografico. Sarebbe meglio spendere il tuo sforzo cercando di proteggere le stesse funzioni API (ad esempio testandole e proteggendole da attacchi come Sql injection), piuttosto che tentare di impedire ai client non autorizzati di accedervi.

    
risposta data 08.02.2017 - 19:33
fonte
4

Ma l'utente sta già utilizzando il tuo protocollo.

Il tuo problema è che l'interfaccia del tuo server su ciò che l'utente può fare non è sicura!
Tu decidi quali dati invia il tuo server a chi!
(Ciao, cari giornali online. Sì, ti sto guardando!)

Disegnala, assumendo che l'utente sia il cliente. Non il tuo codice Perché lo è. Non dovrebbe importare quale sia il client utilizzato.
La tua app funziona su una CPU che è sotto il controllo hardware dell'utente. Il tuo codice è solo un elenco di commmands / dati e l'utente e la sua CPU possono elaborarlo come preferiscono. Compreso non che lo elabora.
Decide cosa fa la sua CPU. Non confondere la sua grazia di accettare il tuo codice app come-è per il diritto all'esecuzione cieca. Sei quello che si è fidato qui, e quella fiducia è molto fugace.
Soprattutto con tattiche squallide come questa.

In ogni caso: consegni all'utente la chiave di crittografia e tutto il resto, e aspettati che non lo usi da solo, perché lo metti da qualche parte nel tuo paniere di codice. ... Proprio come il DRM, quello è olio di serpente e non può mai funzionare.
Ci vuole solo una persona one per trovare dove hai messo la chiave. (Sarei io, ad esempio.) Tutti gli altri devono solo cercarlo su Google.

Ma sono sorpreso che tu pensi solo a crittografare il protocollo contro l'utente, invece che per proteggerlo dagli attacchi man-in-the-middle.
Assumendo il motivo per cui questo è fatto di solito (Sì, sto parlando di nuovo con "l'industria dei contenuti"). Se il tuo utente è il tuo nemico, forse dovresti cercare un modello di business basato sull'equità e un win-win, invece di strappare l'utente e avere a che fare con il backlash.

P.S .: Ignora tutte le risposte di "sicurezza attraverso l'oscurità". Questo è un errore che si traduce in un comportamento corretto, ma è ancora basato su ipotesi non valide. Usarlo come argomento è, nel migliore dei casi, amatoriale e non molto competente.
In realtà, la sicurezza di tutto è attraverso l'oscurità. Alcuni sono solo più oscuri (= meglio mascherati). Il vero motivo per cui ciò è negativo, è perché ciò che chiamiamo sicurezza reale è un bazillion volte più oscuro, dandogli una effettiva (statistica) attendibilmente alta oscurità, al contrario di molto semplice oscurità che è semplicemente un'allerta troppo probabile che qualcuno possa inventare dal nulla.

    
risposta data 09.02.2017 - 10:58
fonte
3

Come altri già hanno spiegato, la sicurezza per oscurità rallenta al meglio un aggressore.

Nel tuo caso specifico, direi che non avrà alcun effetto apprezzabile. Per arrivare a questo punto, il tuo aggressore doveva già decodificare la tua app ed estrarre la chiave privata. Ciò significa che il tuo aggressore non è un idiota e sa cosa sta facendo. Un po 'di oscurità gli costerà meno tempo di quello che ti serve per implementarlo.

    
risposta data 09.02.2017 - 10:46
fonte
1

Come altri hanno già menzionato, stai proponendo di usare Security by Obscurity. Sebbene questa tecnica abbia il suo scopo, considera quanto segue prima di scegliere di adottare questo approccio:

  • Fornire supporto tecnico per la tua API. L'uso di codici di risposta HTTP ingannevoli rende difficile a chiunque altro che fornire supporto. Devono considerare se la particolare situazione sta effettivamente inviando il codice di risposta appropriato o se ne sta inviando uno oscuro. Se decidi di rimanere l'unico contatto per eventuali richieste di supporto, questo non dovrebbe essere un problema.
  • Che cos'è un "Utente malintenzionato"? Prestare attenzione quando la classificazione di una richiesta come dannosa può avere effetti negativi. Supponiamo che un IP sia determinato a inviare traffico dannoso e che vengano utilizzate contromisure. Supponiamo ora che lo stesso IP sia in realtà un proxy con centinaia o migliaia di utenti dietro di esso. Ora hai applicato la tua contromisura a tutti loro. Questo stesso principio può essere applicato per identificare attività dannose nelle intestazioni e / o nel corpo.
  • Il codice dell'applicazione è il più lento. La richiesta deve attraversare l'intero stack per arrivare finalmente alla logica di "sicurezza". Questa architettura non scala bene ed è lenta. Le richieste errate dovrebbero essere interrotte il prima possibile, che è la premessa per l'utilizzo di Web Application Firewall (WAF).
  • Estensione dell'accesso. Se la tua API diventasse accessibile a più clienti per la quale era stata originariamente progettata, i nuovi clienti dovranno essere consapevoli del possibile utilizzo di codici di risposta HTTP ingannevoli.
  • Persistenti utenti malintenzionati. Come altri hanno già accennato, questa tecnica è solo una speed-bump.

Approccio migliore

Concentrati sul tempo in bianco, elencando tutte le buone richieste conosciute. Questo è molto più facile quindi cercare di identificare tutte le potenziali richieste errate. Tutto ciò che non appare nella white-list dovrebbe immediatamente ottenere un codice di risposta appropriato come HTTP 400 o HTTP 405 se si sta filtrando su verbi HTTP (come esempi). Preferibilmente ciò accade prima che la richiesta colpisca il codice dell'applicazione.

Insieme alle richieste consentite in white list, assicurati che l'applicazione sia protetta in base alle Linee guida OWASP . Otterrai risultati molto migliori spendendo il tuo tempo con OWASP, quindi proverai a determinare cosa sia un utente malintenzionato e a restituire un codice di risposta HTTP oscuro.

    
risposta data 09.02.2017 - 19:56
fonte
1

Fondamentalmente, NON è possibile impedire ai client non autorizzati di inviare richieste. La cosa più vicina possibile sarebbe avere una sorta di controllo crittografico fatto nel client, ma come Sherlock Holmes ha detto, "cosa si può inventare, un altro può scoprire". (Lo so per certo, perché ho infranto la sicurezza della clientela sul lato client in diverse occasioni.)

Costruisci la tua API in modo tale che chiunque possa autorizzarlo a utilizzare i client personalizzati. Rendilo amichevole. Cosa ti perdi da questo? Gli attaccanti attaccheranno a prescindere da ciò che fai, e se rendi la tua API facile da usare, qualcuno troverà qualcosa che non hai mai pensato e renderà il tuo server ancora più grande di quanto tu abbia mai immaginato potesse essere. Cosa potrebbe fare un cliente che parla sia con la tua API che con un'altra? Quali miriade di possibilità ci sono e ti farà davvero male permetterglielo?

    
risposta data 10.02.2017 - 09:28
fonte
1

Non lo farei. Generalmente significa che stai creando il tuo standard, che causa:

  1. la tua API è predittiva dopo aver creato una mappa delle tue risposte http al loro vero significato. Cambiare le risposte HTTP potrebbe funzionare su alcuni "hacker" che si arrenderanno dopo alcuni tentativi, ma non su altri, più determinati. Vuoi proteggere la tua API solo dal primo tipo, ad esempio 11 anni? Io non la penso così

  2. un po 'di confusione per gli sviluppatori e probabilmente per i tester, specialmente per quelli che sono abituati a operare secondo gli standard globali.

  3. Scegli un altro modo. Ce ne sono sicuramente alcuni. Ho lottato con lo stesso headscratcher da qualche settimana ultimamente e ho trovato almeno 2 modi più o meno affidabili per ottenere le restrizioni desiderate [non posso postarle qui però].

Sicuramente ci sono modi migliori e MOLTO più efficaci per ottenere quello che vuoi. Prova a guardare la tua API da una prospettiva diversa ... Se tu fossi un hacker e la tua vita dipendesse dall'hacking dell'API, cosa faresti per avere successo? Cosa dovrebbe accadere perché tu sia frustrato nei tuoi tentativi di romperlo?

    
risposta data 13.02.2017 - 08:28
fonte
0

Un buon motivo per non farlo, in particolare per un'app mobile, è che è molto probabile che la tua app stia parlando al tuo server tramite più proxy, ad esempio già nella compagnia telefonica. La maggior parte delle grandi aziende utilizza i proxy sulla propria rete per cercare di proteggere i propri sistemi da contenuti dannosi e molte compagnie telefoniche riducono la qualità dei video o delle immagini in transito. Inoltre, renderà inutili le varie librerie di sistema per HTTP sulla tua piattaforma. Un approccio comunemente utilizzato è quello di ricavare alcune chiavi o token da informazioni che è improbabile che l'utente desideri condividere, ad esempio l'hashing dell'indirizzo del nome e i dettagli della carta di credito. In questo modo, anche se la tua app viene hackerata, le persone saranno caute nel fornire le informazioni richieste a un programma casuale che hanno scaricato limitando la capacità di condivisione di qualsiasi attacco provato.

    
risposta data 13.02.2017 - 00:07
fonte
0

Generalmente non è una buona idea.

Ho fatto un uso molto mirato di questo una volta con buoni risultati quando il sito web di un cliente veniva utilizzato da un anello di riciclaggio di carte di credito rubato. C'erano alcune caratteristiche identificative condivise solo dalle transazioni fraudolente quindi piuttosto che rifiutarle educatamente avrei il sito ritardare la risposta di un paio di minuti (a nessuno piace un sito web che impiega minuti per fare qualcosa) e quindi restituire un 500 con il sito standard "mi dispiace, non sei tu, sono io" messaggio per gli errori del server (ha anche registrato i dettagli per passare alle forze dell'ordine). Abbiamo avuto tre tentativi di transazioni che hanno ottenuto questa risposta all'opossum e poi non li abbiamo mai più sentiti.

Questo però era:

  1. In risposta a qualcosa che sapevamo era un attacco piuttosto che essere odioso per gli utenti che hanno un problema.
  2. Non una difesa contro un attacco alla sicurezza del protocollo stesso, ma a livello umano sopra quello.
  3. Spiegabile attraverso altre spiegazioni, ovvero fingevamo di avere un sito Web davvero fighissimo in una situazione in cui ciò era plausibile (ci sono molti siti Web di successo là fuori) e non eravamo un target specifico (i perp si sarebbero spostati a qualcun altro)

Gli utenti che hanno un problema dovrebbero essere aiutati, non abusati. "Non posso farlo perché non sei autorizzato correttamente" si rifiuta di fare qualcosa in modo utile. "Non posso farlo perché è necessario utilizzare un proxy" quando qualcuno non ha bisogno di utilizzare un proxy è abusivo. Essere deliberatamente inutili è appropriato solo quando sai di essere attaccato e quindi non dovrebbe sembrare un messaggio fittizio o non hai nascosto nulla (potenzialmente hai effettivamente rivelato qualcosa se non si utilizza lo stesso falso stato per ogni errore del client).

Detto questo, è appropriato adottare misure per fare in modo che gli stati non perdano informazioni. Per esempio. è accettabile (descritto come tale negli standard) per /admin/ su 404 anche se in un caso sarebbe 200 (utente autorizzato, indirizzi IP client consentiti, ecc.) In alternativa se /members/my-profile sarà 200 per un utente autorizzato e 403 o In caso contrario, se /members/fdsasafdasfwefaxc sarebbe 404 per un utente autorizzato, è una buona idea farlo 403 o 401 per l'utente non autorizzato. Questa non è tanta sicurezza per oscurità quanto considerare quali URI si riferiscono alle risorse per essere uno dei bit di informazione che viene protetto.

    
risposta data 13.02.2017 - 02:57
fonte

Leggi altre domande sui tag