i pericoli dell'uso di eval () per la creazione di oggetti dinamici - questo è un argomento valido in una cultura di adulti consenzienti?

2

Ho letto sugli avvertimenti espliciti di stackoverflow contro l'utilizzo di eval () per creare oggetti. La ragione che sembra essere data è che il codice maligno potrebbe essere iniettato e oggetti creati ciecamente potrebbero compromettere un sistema. Tuttavia, questo argomento di intento malevolo non è invalidato dall'argomento consenziente-adulto?

Alcuni esempi di codice:

class Test(object):
    def __init__(self, vala, valb, valc):
        self._vala = vala
        self._valb = valb
        self._valc = valc

    def __repr__(self):
        return "<Test(vala={0}, valb={1}, valc={2})>".format(self._vala, self._valb, self._valc)


testlist = [dict(cls="Test", vala="this is vala", valb="this is valb", valc="this is valc"), dict(cls="Test", vala="this is vala II", valb="this is valb II", valc="this is valc II")]

mytestobjects = []

for test in testlist:
    newobj = eval(test['cls'])(**{key: value for key, value in test.items() if key != "cls"})
    mytestobjects.append(newobj)

print(mytestobjects)
    
posta Dowwie 27.07.2014 - 12:53
fonte

3 risposte

7

Dovresti avere qualche idea su chi utilizzerà il tuo software e come.

Se sei sicuro che il tuo codice verrà sempre utilizzato da "brave persone" - ad es. se il tuo codice è uno sviluppo interno interno che non interagirà mai con persone esterne (o fonti), allora l'argomento degli adulti consenzienti è valido. Ma allora dovresti documentare -almeno in alcuni commenti- la tua scelta progettuale (es. Affermare che input errati farebbero scattare il temuto comportamento non definito , e tale input dovrebbe essere valido e valido).

Se al contrario potresti credere che il tuo codice alla fine funzionerà con alcuni dati ottenuti da Internet (o da un server connesso su Internet), dovresti essere consapevole che a causa di molti diversi (sociali, culturali e umani) fattori, persone cattive disposte a spendere tempo e sforzi per irrompere esistono.

Guarda come sono presenti alcune tecnologie Internet attuali, ad es. e-mail. All'inizio di SMTP, Internet era per lo più una cosa accademica (e anche militare), con una strong cultura del "buon comportamento in rete". Oggi riceviamo miliardi di SPAM perché non è più il caso

Vedi tavoli da poker ! Fai attenzione all'iniezione di codice ...

    
risposta data 27.07.2014 - 13:20
fonte
5

L'argomento per adulti consenzienti è che i programmatori che usano il tuo codice sono adulti consenzienti. Gli utenti potrebbero non esserlo. (Potrebbero, ad esempio, non capire come verranno utilizzati i loro dati nel programma.)

Inoltre, la persona che fornisce i dati dannosi potrebbe non essere la persona che ha "acconsentito" all'utilizzo del programma. Se il programma acquisisce dati da Internet, ad esempio, anche un utente "adulto consenziente" può inavvertitamente scaricare dati dannosi e danneggiare il proprio sistema. Il rovescio della medaglia, se il programma gira su un server, l '"utente" potrebbe essere l'amministratore del server, che non vuole che i visitatori del sito siano in grado di rendere flessibile il suo server inserendo dati dannosi in un modulo web o simili. In entrambi i casi, il punto è che la persona che fa il consenso non è necessariamente la persona che subisce l'effetto.

    
risposta data 27.07.2014 - 21:39
fonte
1

Questo è fatto da stdlib di Python, in collections.namedtuple() , anche se usano exec() piuttosto che eval() . Quando ho ha segnalato una possibile vulnerabilità di codifica (inizialmente a python-security ), è stato corretto, ma non è stato trattato come un problema di sicurezza . In particolare, hanno mantenuto il exec() nonostante l'esistenza di una patch che l'ha evitata.

A quanto ho capito, gli sviluppatori di Python stanno permettendo alla praticità di battere la purezza in questo caso. La patch è piuttosto complessa e coinvolge metaclassi e altre intelligenze, mentre exec() è più facile da capire. Inoltre, è raro chiamare collections.namedtuple() con input utente non fidato, e ancora più raro passare il tipo di oggetto strano che ho dovuto costruire per aggirare i controlli di sicurezza già in atto.

Probabilmente non userò questa tecnica da solo a meno che non avessi altre opzioni valide, ma non sono abbastanza sicuro di poter ragionevolmente ritenere questa implementazione sbagliata.

    
risposta data 13.01.2015 - 04:20
fonte

Leggi altre domande sui tag