Uso i buffer del protocollo google C++ in un'applicazione web-facing molto attenta alla sicurezza.
Osservando il codice generato, tutto il lavoro di deserializzazione è delegato al codice generato automaticamente nel metodo <Message-Type>::MergePartialFromCodedStream
di ogni messaggio. Questi metodi sono generati con controlli completi su tipi di dati e lunghezze e finora non abbiamo avuto alcun problema.
Un'area di attacco che potresti voler chiudere tu stesso è nell'inquadratura dei dati di protobuf - i buffer di protocollo stessi non serializzano la dimensione complessiva del messaggio serializzato nello stream in alcun tipo di intestazione standardizzata, quindi potresti volere a (come faccio io) avvolgere tutti i messaggi del protocollo buffer in un frame. Per i miei scopi l'intestazione del frame contiene semplicemente una dimensione del messaggio, il che significa che sono in grado di determinare i requisiti di memoria del messaggio prima di tentare di leggerlo dal cavo, per non parlare di decodificarlo.
A questo punto è possibile effettuare un semplice controllo per rifiutare i messaggi (o rilasciare la connessione) se la dimensione è eccessivamente grande.
È possibile eseguire ulteriori operazioni per avvolgere questo frame in uno schema di inserimento di chiavi pubbliche al fine di prevenire il dirottamento man-in-the-middle della sessione, se questo è un problema.
sovraccarichi di buffer all'interno di un messaggio (ad esempio una stringa diventando troppo lungo) non può succedere perché bytes
e string
campi sono rappresentati internamente da std::string
, che cresce automaticamente la sua impronta memoria, come dati vengono aggiunti ad esso.
Tuttavia:
Non c'è alcuna garanzia che i clienti maligni non cercherà di codificare i messaggi validi che contengono dati non validi. Ad esempio, se l'applicazione server prende un nome di metodo dalla stringa di dati, cerca il suo indirizzo e lo chiama, quindi questo è un vettore ovvio per l'attacco.
Non si dovrebbe mai consentire ai dati client di trovare il codice del server senza un controllo completo che l'operazione sia specificamente consentita.
Alcuni esempi di questo che non si deve mai fare:
- consentire al cliente di inviare SQL in un campo di testo
- consentire al cliente di inviare righe di comando, che in seguito si passano a
system()
, exec()
, spawn()
ecc ...
- consentire al cliente di inviare il nome di una libreria condivisa e un nome di funzione all'interno di esso ...
e così via.
fonte
2015-01-12 17:25:10
utilizzare [HMAC] (http://en.wikipedia.org/wiki/Hash-based_message_authentication_code) o almeno una qualche forma di checksum. – tumdum
I checksum non sono una difesa contro la malizia. L'autenticazione è, almeno con adeguate implementazioni crittografiche. – MSalters
@MSalters L'autenticazione non è davvero una difesa contro la malvagità ... Permette solo di identificare (supponendo che le tue chiavi/certs non siano state compromesse) chi è malizioso ... – twalberg