2013-04-07 6 views
5

Immagina che ci sia un processo mission-critical che verrà utilizzato in un'azienda che gestisce le informazioni sensibili (pensa a carta di credito, sicurezza sociale, record dei pazienti ... ecc.). Penserei che questa unità dovrebbe idealmente fare tutto ciò che deve fare al volo, nel senso che non scriverà intenzionalmente file su disco contenenti informazioni sensibili. L'idea qui è che se il computer che esegue questo processo è compromesso, nessuna informazione sensibile può essere trapelata, almeno non tramite i file.Come verificare se una determinata unità di codice funzionale (C#) NON crea/scrive alcun file sul disco?

Quali approcci potrebbero essere adottate, per esempio, venire con una prova di unità che si fallire se l'unità in prova tenta di scrivere qualsiasi file su disco?

+0

Se fossi in te eseguirò il controllo di processo tramite http://blogs.msdn.com/b/carloc/archive/2008/ 10/31/how-to-automate-process-monitor.aspx e analizza l'output per le scritture di file dall'applicazione di esecuzione del test dell'unità (nunit o altro). Solo un'idea – devshorts

risposta

6

C'è il FileSystemWatcher (http://www.c-sharpcorner.com/uploadfile/puranindia/filesystemwatcher-in-C-Sharp/) tuttavia ciò richiede che tu conosca una directory specifica. Nel tuo caso questo probabilmente non è molto utile in quanto il programma potrebbe scrivere qualsiasi cosa sul disco dove. Questo introduce un problema unico. Tuttavia, ho anche trovato qualcosa chiamato Detours di Microsoft. Questo sembra intercettare tutte le chiamate native a Win32 API. http://research.microsoft.com/en-us/projects/detours/ Il problema con questo è che è difficile da testare e integrarlo nei test di unità sarà una sfida.

Quando si tratta il software come "non attendibile" nel senso che è necessario dimostrare che non fa qualcosa, il test diventa un'attività complessa che richiede di eseguirli in ambienti molto controllati. Quando ti colleghi all'API Win32, verrai inondato con chiamate API che devono essere elaborate rapidamente. Ciò può provocare effetti collaterali involontari poiché l'applicazione non è in esecuzione in un ambiente veramente nativo.

Il mio suggerimento per voi (avendo lavorato diversi anni facendo test di software per l'automazione Pharma agli standard rigorosi della FDA) è quello di creare un ambiente controllato, ad esempio una macchina virtuale, che ha uno stato di partenza noto. Questo può essere ottenuto non salvando mai realmente le modifiche di vmdk sul disco. Devi fare un'istantanea del file system. Puoi farlo scrivendo un'app C# per enumerare tutti i file sul disco virtuale, ottenendo le loro dimensioni, alcuni timestamp e forse persino un hash del file. Questo può richiedere molto tempo, quindi potresti volere (o essere in grado) di saltare l'hashing. Creare una sorta di rapporto, il più semplice sarebbe lasciarli in un'esportazione CSV o XML. Quindi esegui il software in circostanze normali per un determinato periodo di tempo. Una volta completato, si esegue nuovamente un'analisi del file system e si confrontano i risultati. Ci sono alcune buone app là fuori per confrontare i contenuti dei file (come WinMerge). Quando si scattano queste istantanee, il modo migliore per farlo sarebbe montare il vmdk come unità nel sistema operativo host. Questo eviterà qualsiasi blocco di file che il sistema operativo guest potrebbe avere.

Questo metodo richiede molto tempo ma è completo. Se non hai bisogno di qualcosa di questo approfondimento, puoi usare qualcosa come Process Monitor e scrivere l'output in un file ed eseguire un rapporto in questo senso. Tuttavia nel mio lavoro dovrei dimostrare che Process Monitor mostra tutto IO prima che potessi usarlo, il che può essere altrettanto difficile del metodo di cui ho parlato sopra.

Solo i miei 2 centesimi.

UPDATE:

Ci ho pensato su di esso, e si potrebbe essere in grado di raggiungere risultati abbastanza affidabili se si rimuove tutti i riferimenti a System.IO dal codice. Scrivere una libreria per avvolgere System.IO che non implementa un metodo di scrittura o implementa solo uno che scrive anche in un file di registro. In questo caso, devi semplicemente convalidare che ogni volta che si verifica una scrittura utilizzando la tua libreria, viene registrato. Quindi convalidare utilizzando la reflection che non si fa riferimento a System.IO al di fuori di questa nuova libreria wrapper. I test possono quindi semplicemente guardare questo file di registro per assicurarsi che si stiano verificando solo scritture approvate.È possibile utilizzare un database SQL anziché un file di registro flat per evitare casi di manomissione o risultati contaminati. Questo dovrebbe essere molto più facile da validare rispetto al tentativo di creare script su una configurazione di macchina virtuale come ho descritto sopra. Questo, ovviamente, richiede che tu abbia accesso al codice sorgente dell'applicazione "non affidabile", sebbene dal momento che tu collaudi l'unità, presumo che tu lo faccia.

+0

La mia preoccupazione principale è di assicurarmi che il codice non faccia nulla che non dovrebbe fare. Automatizzare un ciclo di generazione/snapshot/confronto VM mi darebbe la sicurezza che sia così. –

+0

@ArcaArtem Ho pensato ad un altro metodo di test, fatemi sapere cosa ne pensate –

+0

Come suggerito da @Fabske, astrazione di System.IO (ad esempio [System.IO.Abstractions] (http://systemioabstractions.codeplex.com)), e usando FxCop/StyleCop per limitare gli sviluppatori non utilizzare System.IO potrebbe garantire che il nostro codice non scriva sul disco. Il feedback ricevuto con questo metodo sarà ricevuto molto più velocemente rispetto all'approccio VM. Tuttavia, se il codice ha dipendenze che non sono sotto il nostro controllo, questo non funzionerebbe. Penso che entrambi gli approcci dovrebbero essere usati in questo caso, ovvero limitare l'utilizzo di System.IO per uso interno, utilizzare il confronto di istantanee VM per garantire che nessun'altra scrittura di dipendenze sul disco. –

2

prima opzione:
Forse si potrebbe utilizzare il codice di accesso di sicurezza, ma la "Nega" è obsoleta in .NET 4 (ma dovrebbe opere nella versione precedente):

[FileIOPermission(SecurityAction.Deny)] 
public class MyClass 
{ 
    ... 
} 

Si può riattivare questo comportamento in NET 4 utilizzando NetFx40_LegacySecurityPolicy

seconda opzione:
ridurre il livello di privilegio può funziona anche, come so che ha scaricato app non può scrivere sul disco e deve utilizzare una speciale area di stoccaggio.

3a opzione:
Rimuovere qualsiasi riferimento a System.IO e sostituirlo con un'interfaccia che il codice deve utilizzare per scrivere dati su disco.
Quindi scrivere un'implementazione che utilizza System.IO (in un progetto separato)
Nel test di nunit, prendi in giro questa interfaccia e genera un'eccezione quando viene chiamato un id di metodo.

Il problema è garantire che gli sviluppatori non chiamino più System.IO. Puoi provare a farlo applicando le regole di codifica usando FxCop (o altri strumenti simili)

+0

Non ho mai considerato l'utilizzo di StyleCop o FxCop per questo scopo. Buona chiamata –

+0

La preoccupazione principale è assicurarsi che il codice non faccia ciò che non dovrebbe fare. Usare CAS o astrarre System.IO mi aiuterebbe a farlo sul codice di cui ho il controllo, ma non sulle dipendenze esterne. Usare FXCop o equivalente è una buona idea per ottenere un feedback immediato sul codice interno. –

Problemi correlati