Domanda

Una domanda vuole analizzare ed "esecuzione" di un file, e vuole affermare il file è eseguibile per motivi di sicurezza.

A momenti di pensiero e ti rendi conto di questo codice iniziale è una condizione di competizione che rende il regime di sicurezza inefficaci:

import os

class ExecutionError (Exception):
    pass

def execute_file(filepath):
    """Execute serialized command inside @filepath

    The file must be executable (comparable to a shell script)
    >>> execute_file(__file__)  # doctest: +ELLIPSIS
    Traceback (most recent call last):
        ...
    ExecutionError: ... (not executable)
    """
    if not os.path.exists(filepath):
        raise IOError('"%s" does not exist' % (filepath, ))
    if not os.access(filepath, os.X_OK):
        raise ExecutionError('No permission to run "%s" (not executable)' %
                filepath)

    data = open(filepath).read()

    print '"Dummy execute"'
    print data

Esiste la condizione di competizione tra

os.access(filepath, os.X_OK)

e

data = open(filepath).read()

Poiché v'è la possibilità di file sovrascrittura di un file non eseguibile di contenuti diversi tra queste due chiamate di sistema.

La prima soluzione che ho è di cambiare l'ordine delle chiamate critiche (e ignorare il controllo esistenza ormai ridondante):

fobj = open(filepath, "rb")
if not os.access(filepath, os.X_OK):
    raise ExecutionError('No permission to run "%s" (not executable)' %
            filepath)

data = fobj.read()

Questo risolve la condizione di competizione? Come posso risolvere correttamente?

regime di sicurezza logica, per breve tempo (ho pensato)

Il file sarà in grado di eseguire comandi arbitrari all'interno della sua ambiente, quindi è paragonabile ad uno script shell.

C'è stato un buco di sicurezza sui desktop liberi con file .desktop che definiscono Applicazioni: Il file può specificare qualsiasi eseguibile con argomenti, e si può scegliere la propria icona e il nome. Quindi un file scaricato in modo casuale potrebbe nascondere dietro qualsiasi nome o icona e fare qualsiasi cosa. E 'stato male.

Questo è stato risolto richiedendo che i file .desktop hanno il bit di esecuzione insieme, altrimenti non sarà reso con nome / icona, e il desktop libero chiederà all'utente se vuole avviare il programma prima di iniziare.

Confronta questo a molto buon design di Mac OS X: "Questo programma è stato scaricato dal web, sei sicuro di volerlo aprire?".

Quindi, in allegoria con questo, e il fatto che si deve chmod +x shell script che si scarica, ho pensato alla progettazione nella domanda di cui sopra.

parole

chiusura

Forse in conclusione, forse dovremmo mantenere le cose semplici: se il file deve essere eseguibile, renderlo eseguibile e lasciare che il kernel eseguirlo quando viene richiamato dall'utente. Delegazione del compito a cui appartiene.

È stato utile?

Soluzione

L'eseguibilità è allegato al file che si apre, non c'è niente di arresto diversi file dalla punta al inode contenente i dati che si desidera leggere. In altre parole, gli stessi dati possono essere leggibile da un file non eseguibile altrove nello stesso file system. Inoltre, anche dopo l'apertura del file, non è possibile impedire l'eseguibilità di quello stesso file da cambiare, potrebbe anche essere scollegato.

Il "best effort" a disposizione di voi come lo vedo io sarebbe fare controlli utilizzando os.fstat sul file aperto, e verificare la modalità di protezione e ora di modifica prima e dopo, ma nella migliore delle ipotesi questo ridurrà solo la possibilità che cambia passare inosservato mentre si legge il file.

Il secondo pensiero, se sei il creatore originale dei dati in questo file, si potrebbe prendere in considerazione la scrittura di un inode che non è mai legata al file system, in primo luogo, questa una tecnica comune in condivisione della memoria tramite file. In alternativa, se i dati contenuti devono finalmente reso pubblico ad altri utenti, è possibile utilizzare il blocco dei file, e quindi estendere progressivamente i bit di protezione a quegli utenti che lo richiedono.

In definitiva è necessario assicurarsi utenti malintenzionati semplicemente non hanno accesso in scrittura al file.

Altri suggerimenti

Non si può del tutto risolvere questo race condition - ad esempio, nella versione in cui per la prima volta aperto, quindi controllare i permessi, è possibile che i permessi vengono cambiati solo dopo aver aperto il file e basta prima di aver cambiato i permessi.

Se si può atomicamente spostare il file in una directory in cui i potenziali cattivi non possono raggiungere, allora si può stare certi che nulla circa il file sarà cambiato da sotto il naso mentre hai a che fare con esso. Se i potenziali cattivi possono raggiungere in tutto il mondo , o non è possibile spostare il file dove non possono arrivare, non c'è difesa.

A proposito, non è chiaro per me come questo schema, anche se potrebbe essere fatto per lavorare, sarebbe in realtà aggiungere qualsiasi sicurezza - sicuramente se i cattivi possono mettere avvelenato il contenuto del file non è al di là di loro di chmod +x come bene?

Il meglio che puoi fare è:

  • salvare l'autorizzazione.
  • cambiare per il proprio utente univoco (qualcosa con il nome del programma) e vietare ad altri di farlo funzionare.
  • farvi controlli (sul permesso di salvare, se necessario).
  • eseguire il processo.
  • arretrato il permesso a quelli salvati.

Naturalmente, ci sono svantaggi, ma se il tuo caso d'uso è così semplice come si sembrano dire, si potrebbe fare il trucco.

Si dovrebbe modificare il file di proprietà in modo tale che un attaccante non può accedervi "chown root: nome_file root". Fare un "chmod 700 nome_file", in modo che nessun altro account possono lettura / scrittura / esecuzione il file. Questo evita il problema di un TOCTOU tutti insieme e questo è come le persone a prevenire i file venga modificato da un hacker che ha un account utente sul sistema.

Un altro modo per farlo è quello di cambiare il nome del file per qualcosa di inaspettato, o anche copiare l'intero file - se non è troppo grande - ad una directory temporanea (criptato se necessario), ti fanno i controlli, quindi rinominare / copiare il file indietro.

Naturalmente si tratta di un processo molto pesante.

Ma si finisce con che perché il sistema non è stato impostato per la sicurezza fin dall'inizio. Un programma di sicuro avrebbe firmato o crittografare i dati che vuole tenere al sicuro. Nel tuo caso, non è possibile.

A meno che davvero sulla crittografia pesante, non c'è modo di garantire la sicurezza 100 su una macchina che non controlli.

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