2014-12-10 8 views
7

La capacità incorporata di Django di inviare email agli amministratori in caso di errori (vedere https://docs.djangoproject.com/en/dev/howto/error-reporting/) è molto utile.Messaggi di errore di Django che inviano email: informazioni sulle perdite di env vars

Tuttavia, queste e-mail di traceback includono un dump completo di variabili di ambiente.

E come consigliato nella documentazione Django & altrove (ad esempio https://docs.djangoproject.com/en/dev/howto/deployment/checklist/) ho spostato alcuni segreti/chiavi/password in variabili d'ambiente come un modo semplice per tenerli lontano dalla base di codice & li variano tra le implementazioni. Sfortunatamente questo significa che quando c'è un rapporto di arresto anomalo questi segreti vengono inviati in chiaro a una serie di account di posta elettronica. Non è una buona pratica.

Il django ExceptionReporter ha un filtro di base per estrarre le impostazioni "pericolose o offensive", ad es. il valore di qualsiasi oggetto in settings.py il cui nome contiene le stringhe "pass" o "chiave" sarà sostituito con **** s. Così una chiave segreta in settings.py viene modificata. Ma questo filtro non è applicato alle variabili di ambiente, che compaiono in entrambe le sezioni Traceback-> Vars locali-> richiesta e Richiesta informazioni-> Meta di questi rapporti di errore.

Ovviamente ci sono altri modi per gestire i segreti ma l'ambiente unix è una soluzione piuttosto comune per i piccoli siti in cui la creazione di un sistema di configurazione più complesso non è giustificata.

Sembra anche problematico che queste due pratiche, entrambe raccomandate nei documenti di base di django, non siano sicure se applicate insieme.

L'invio di e-mail tra le informazioni di debug del sito comporta sempre il rischio di perdita di informazioni, ma questa sembra un'omissione significativa che potrebbe essere risolta dal filtro esteso, forse controllato da alcune impostazioni.

Qualcuno ha già applicato patch (presumibilmente espandendo il filtro in django/views/debug.py) per la loro implementazione e/o ha inviato una patch al team di django? O mi manca qualche altro modo ovvio per affrontare questo?

risposta

3

OK, perso questo nel mio controllo precedente, ma a quanto pare il team di Django avuto circa questo bug registrato & chiuso come si-non-fix 6 anni fa:

https://code.djangoproject.com/ticket/7472

prenderò in su con loro, dal momento che ritengo che il Django abbia compiuto notevoli progressi nel campo della sicurezza nel tempo che intercorre e ora potrebbe desiderare, e avere alcuni semplici modi, affrontare questo problema. :)

Nel frattempo, se si utilizza questa funzione di e-admin-admins, si prega di essere consapevoli del rischio. Se invii queste e-mail, ti consiglio vivamente di lasciare o inserire tutti i segreti/password/chiavi/certs/etc nei file di configurazione di python e di assicurarti di eliminare l'ambiente (unix) passato al tuo servizio web django.

+0

Tutti i punti validi.Hai trovato una soluzione migliore? – Medorator

+0

Siamo spiacenti, ma no. Ho deciso di non utilizzare la segnalazione automatica degli errori come soluzione alternativa. Credo che il team di django abbia preso una segnalazione di errore per aggiornare i documenti per non consigliare la combinazione di queste due impostazioni, ma è andata così. Hmm, forse dovrei tornare indietro e creare e presentare una patch effettiva ... – geewiz

0

Questo tipo di problema riguarda tutte le applicazioni che trattano informazioni potenzialmente sensibili. Segnalare un errore di tale applicazione, è probabile che perdi informazioni sensibili, se il sistema di segnalazione degli errori non crea meccanismi di miglioramento della privacy (la maggior parte dei casi), che a quanto pare è il caso di Django.

Tutela della privacy nella segnalazione degli errori può essere realizzato utilizzando soluzioni dedicate, ad esempio:

http://www.gsd.inesc-id.pt/~romanop/files/papers/ESOP14.pdf

http://research.microsoft.com/en-us/projects/betterbug/castro08better.pdf

Questi sistemi possono essere integrati con i sistemi di segnalazione degli errori per consentire la sanificazione il contenuto dell'errore rapporti generati prima di chiedere all'utente l'autorizzazione a trasmetterlo.

Nei prossimi mesi saranno disponibili opere più recenti, che includeranno implementazioni open source. Aggiornerò questo post una volta visualizzati.

Spero che questo aiuti.

0

Nel caso di utilizzo mod_wsgi con Apache, variabili d'ambiente (impostate attraverso la direttiva Apache SetEnv o altro) vengono passati alla funzione application nel primo argomento environ.

Per poter accedere a queste variabili di ambiente in settings.py (o altrove), è opportuno copiarle in os.environ, utilizzando ad es.

os.environ['TOP_SECRET'] = environ['TOP_SECRET'] 

Dopo questo, environ viene passato django.core.handlers.wsgi.WSGIHandler (via django.core.wsgi.get_wsgi_application), dove alla fine rende il modo per le segnalazioni di errori.

Il tasto TOP_SECRET non ha bisogno di essere mantenuto in environ dopo che è stato copiato os.environ, in modo da cambiare la riga sopra per os.environ['TOP_SECRET'] = environ.pop('TOP_SECRET', '') rimuove dal segnalazioni di errori.

Mettere tutto insieme, il mio file wsgi.py è la seguente:

import os 

from django.core.wsgi import get_wsgi_application 

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "App.settings") 

env_variables_to_pass = ['TOP_SECRET'] 

def application(environ, start_response): 
    # pass the WSGI environment variables on through to os.environ 
    for var in env_variables_to_pass: 
     os.environ[var] = environ.pop(var, '') 
    return get_wsgi_application()(environ, start_response) 

Ciò significa che le variabili di ambiente richieste sono disponibili in os.environ ove necessario, ma non appaiono nei rapporti di errore.

È possibile che mi sia sfuggito qualcosa qui, ma sembra che funzioni per me. Se c'è un motivo per non farlo, per favore pubblica un commento. Potrebbe essere più sicuro creare prima una copia del dizionario environ, ad esempio my_environ = copy.deepcopy(environ), quindi utilizzare quello anziché environ direttamente.

Si noti inoltre che altre variabili sensibili (ad esempio le password in POST richieste) dovrebbe essere filtered invece.

+0

Copia per richiesta I valori dell'ambiente WSGI per elaborare ampie variabili d'ambiente sono generalmente considerati una cattiva pratica. Se il valore delle variabili può cambiare per richiesta, è possibile avere problemi in una configurazione con multithreading. –

+0

@GrahamDumpleton, grazie per il tuo commento - Sto usando questo solo per cose come le password del database, che non cambiano spesso. Prendo il punto però. C'è un altro modo per rendere i valori di 'environ' disponibili per l'app? – zelanix

+0

Leggendoli in qualche modo da un file di configurazione separato o dall'origine dei segreti, quando viene caricato il file di script WSGI. –

1

Ho riscontrato lo stesso problema e l'ho risolto creando un middleware personalizzato, come descritto nello Django docs. Questo approccio presuppone che tu conosca i nomi delle variabili di env che vuoi nascondere dalle pagine di errore/email e che in realtà non hai bisogno di queste variabili presenti in ogni richiesta. È quindi possibile filtrarli dalla richiesta.META dizionario prima che venga generata la risposta all'errore:

class RequestSafetyMiddleware(object): 
    def __init__(self, get_response): 
     self.get_response = get_response 
    def __call__(self, request): 
     request.META.pop('TOP_SECRET', None) 
     response = self.get_response(request) 
     return response 

Spero che questo aiuti! Vorrei che Django applicasse le stesse regole di offuscamento di sicurezza alle variabili env in quanto si applica alle impostazioni, quindi questo non sarebbe nemmeno un problema.