Domanda

Se sto valutando una stringa Python usando eval (), e ho una classe come:

class Foo(object):
    a = 3
    def bar(self, x): return x + a

Quali sono i rischi per la sicurezza se non mi fido della stringa? In particolare:

  1. eval(string, {"f": Foo()}, {}) non è sicuro? Cioè, puoi raggiungere os o sys o qualcosa di non sicuro da un'istanza di Foo?
  2. eval(string, {}, {}) non è sicuro? Cioè, posso raggiungere os o sys interamente da builtin come len e list?
  3. C'è un modo per rendere i builtin non presenti affatto nel contesto eval?

Esistono stringhe non sicure come " [0] * 100000000 " Non mi interessa, perché nel peggiore dei casi rallentano / fermano il programma. Sono principalmente preoccupato per la protezione dei dati degli utenti esterni al programma.

Ovviamente, eval(string) senza dizionari personalizzati non è sicuro nella maggior parte dei casi.

È stato utile?

Soluzione

Non puoi proteggere eval con un approccio in blacklist come questo. Vedi Eval è davvero pericoloso per esempi di input che segfaultano l'interprete CPython, danno accesso a qualsiasi classe ti piaccia, e così via.

Altri suggerimenti

eval() consentirà ai dati dannosi di compromettere l'intero sistema, uccidere il tuo gatto, mangiare il tuo cane e fare l'amore con tua moglie.

Di recente c'è stato un thread su come fare questo genere di cose in modo sicuro nell'elenco di Python-Dev, e le conclusioni sono state:

  • È davvero difficile farlo correttamente.
  • Richiede patch all'interprete Python per bloccare molte classi di attacchi.
  • Non farlo a meno che tu non voglia davvero.

Inizia qui per leggere la sfida: http: // tav.espians.com/a-challenge-to-break-python-security.html

In quale situazione vuoi usare eval ()? Vuoi che un utente sia in grado di eseguire espressioni arbitrarie? O vuoi trasferire i dati in qualche modo? Forse è possibile bloccare l'input in qualche modo.

Puoi accedere a os usando le funzioni integrate: __import__('os').

Per python 2.6+, il ast module può aiutare; in particolare ast.literal_eval, anche se dipende esattamente da cosa vuoi valutare.

Si noti che anche se si passano dizionari vuoti a eval (), è ancora possibile segfault (C) Python con alcuni trucchi di sintassi. Ad esempio, prova questo sul tuo interprete: eval("()"*8**5)

Probabilmente starai meglio girando la domanda:

  1. Che tipo di espressioni vuoi valutare?
  2. Puoi assicurarti che solo le stringhe che corrispondono ad una sintassi definita in modo stretto siano eval () d?
  3. Quindi considera se quello è sicuro.

Ad esempio, se si desidera consentire all'utente di immettere un'espressione algebrica per la valutazione, prendere in considerazione la possibilità di limitarli a nomi di variabili di una lettera, numeri e un set specifico di operatori e funzioni. Non eval () stringhe contenenti altro.

Esiste un ottimo articolo sulla non sicurezza di eval() nel Dive into Python di Mark Pilgrim.

Citato da questo articolo:

  

Alla fine, è possibile in sicurezza   valutare espressioni Python non attendibili,   per qualche definizione di & # 8220; sicuro & # 8221; quello   risulta non essere terribilmente utile in   vita reale. & # 8217; va bene se & # 8217; sei giusto   giocando, ed è & # 8217; va bene se tu   trasmetti sempre solo input affidabili. Ma   qualsiasi altra cosa sta solo chiedendo   guai.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top