Problemi di sicurezza con gli script utente Python

1

Sto generando immagini dinamiche in un servizio web. La configurazione corrente è:

  • Richiesta image.py
  • image.py esegue una ricerca nel database per determinare quali dati utilizzare per generare l'immagine
  • image.py chiama un sub-script (dato dal database, ad esempio cats.py ) per generare la particolare immagine

Quindi image.py contiene il codice standard del wrapper e cats.py disegna i gatti ( dogs.py attirerebbe naturalmente i cani). Vorrei generalizzare questa configurazione in modo che gli utenti possano fornire il proprio codice di tracciamento, soggetto alle mie variabili pre-fornite, principalmente la tela di stampa e la libreria math .

Permettere il caricamento di script Python generici è ovviamente un problema di sicurezza sostanziale. Vorrei mantenere il mio server sotto il mio controllo ed evitare che venga utilizzato per far saltare spam su Internet; anche tenere a bada il server con loop e grandi strutture di dati è una preoccupazione, ma a mia conoscenza non c'è molto da fare (provate che mi sbaglio!).

Le seguenti misure saranno sufficienti per proteggersi dalle forme di abuso più flagranti?

  • Chiama image.py come utente con autorizzazioni limitate (per evitare che gli utenti ottengano informazioni critiche sul server)
  • Disattiva le funzioni chiave come __import__ , eval , exec , ecc. impostandole uguali a None -per limitare le funzionalità a un ambiente controllato (per evitare che gli utenti importino le librerie di rete e altre cose con brutto potenziale)

Sto distruggendo l'oggetto del database e tutte le variabili critiche prima di chiamare potenziali script utente. Una sfida è che sto restituendo errori Python quando esistono, modificando il tipo di contenuto del documento restituito. Ciò potrebbe consentire l'ispezione di alcune proprietà, ma è anche necessario per consentire il debug.

Ho trovato queste domande correlate, ma non sono sicuro che siano direttamente correlate:

Aggiornamento: vedo dal test che __import__ = None in realtà non disabilita la parola chiave import . Quindi forse questo concetto non funzionerà.

    
posta kyle 02.06.2015 - 03:01
fonte

2 risposte

4

Per affrontare questo problema da un'angolazione diversa, come creare una lingua specifica per il dominio ?

Perché dare agli utenti la possibilità di fare una miriade di cose che non vuoi che siano in grado di fare, e quindi provare a sandbox e contenere il potere che stai dando loro? Invece, crea un linguaggio semplice che può essere usato solo per il plottaggio e interpretarlo con Python.

Quindi potresti creare una semplice DSL chiamata "Plot" o qualcosa del genere. La trama sarebbe un linguaggio che consente agli utenti di descrivere le loro strategie di tracciamento. Quindi il tuo file image.py caricherà cat.plot , che potrebbe essere fornito da te o da un utente.

Come menzionato nei commenti, la whitelist delle funzionalità è molto meglio della blacklist. Non dare agli utenti più potere del necessario - meglio non dare il potere in primo luogo piuttosto che cercare di contenerlo.

    
risposta data 02.06.2015 - 07:17
fonte
0

@ La risposta di Nathan è piuttosto azzeccata: le funzioni di blacklist lasciano alcuni buchi di sicurezza considerevoli che sono facilmente sfruttabili (con un po 'di Google). Non ho avuto fortuna a seguire le varie istruzioni per far funzionare Pybox sandbox e lo stesso funziona con chroot o Jailkit.

In definitiva, ho eseguito il rollover utilizzando varie tecniche. Riconosco che questo è lungo, ma queste istruzioni mi avrebbero davvero aiutato.

  • Crea un utente di spoof con (relativamente) pochi permessi, image-user
  • Crea un chroot jail per image-user , più o meno in base a questi passaggi
  • Disabilita tutti gli accessi di rete per image-user , ad eccezione di localhost. Ciò consente il passaggio delle connessioni del database. Tieni presente che iptables sembra strozzarsi quando "localhost" è autorizzato nella whitelist, deve essere "127.0.0.1"; lo stesso vale per le connessioni MySQLdb in Python. Il comando è iptables -A OUTPUT ! -d 127.0.0.1 -m owner image-user -j DROP
  • Imposta sshd_config in modo che l'utente acceda al suo jail, Match user image-user \n ChrootDirectory /path/to/jail
  • Disattiva le connessioni non localhost per questo utente in ssh_config
  • Abilita l'autenticazione basata su chiave per ssh per questo utente
  • Invece di caricare direttamente image.py attraverso il browser, usa uno script wrapper che carica l'utente con autorizzazioni ridotte tramite ssh; poiché non c'è accesso alla rete e l'utente si trova in una prigione chroot, image-user potrebbe, nel peggiore dei casi, distruggere la sua struttura chroot. Questo sarebbe male, ma veloce da correggere da un backup di sistema. Lo script wrapper è PHP e la chiamata è shell_exec( 'ssh image-user@localhost python image.py --param1 value1 --param2 value2' )

(Spero di ampliare questa risposta, soprattutto visto che il futzing con iptables può davvero indebolire un server, sto impostando questa panoramica mentre gli eventi sono nuovi nella mia mente)

    
risposta data 04.06.2015 - 21:03
fonte

Leggi altre domande sui tag