02 dic 2025·8 min di lettura

Scansione virus per i caricamenti di file: opzioni di architettura per le app

Scansione virus per i caricamenti di file spiegata per app con molti documenti: storage in quarantena, code di scansione, controllo accessi, retry e workflow di rilascio sicuro.

Scansione virus per i caricamenti di file: opzioni di architettura per le app

Il problema in parole semplici: file non sicuri che entrano nella tua app

Se la tua app permette agli utenti di caricare documenti, stai accettando file che non hai creato tu. In prodotti con molti documenti (portali clienti, sistemi HR, app per sinistri, onboarding fornitori) gli upload sono frequenti e gli utenti spesso condividono file presi da email, drive condivisi o terze parti. Questo rende queste app bersagli pratici: un singolo caricamento riuscito può propagarsi attraverso molti download.

I rischi non sono solo “un virus”. Un file Word o Excel può contenere macro dannose, un PDF può essere costruito per sfruttare bug del lettore e una “fattura” può essere un documento di phishing che induce qualcuno a chiamare un numero falso o inserire credenziali. Alcuni file sono avvelenati in modi più silenziosi, come nascondere un payload in uno ZIP, usare estensioni doppie (report.pdf.exe) o incorporare contenuti remoti che “telefonano a casa” quando vengono aperti.

Affidarsi a un semplice antivirus installato su un singolo server non è sufficiente. Gli upload possono raggiungere istanze multiple dell’app, muoversi tra sistemi di storage o essere serviti da object storage o CDN. Se una qualsiasi strada del codice espone accidentalmente l’upload grezzo, gli utenti possono scaricarlo prima che la scansione sia terminata. Aggiornamenti, misconfigurazioni e accessi amministrativi “temporanei” possono inoltre aggirare la scansione nel tempo.

L’obiettivo chiaro per la scansione virus sui caricamenti è semplice: nessun file non scansionato deve mai essere scaricabile o visualizzabile da chiunque non sia esplicitamente autorizzato a esaminare contenuti in quarantena.

Definisci cosa significa “sicuro” come regola di business, non come sensazione. Per esempio:

  • Deve superare la scansione malware con un set di firme aggiornato
  • Deve corrispondere ai tipi di file e ai limiti di dimensione consentiti
  • Deve essere memorizzato e servito solo da posizioni approvate
  • Deve avere una traccia di audit: chi ha caricato, quando e stato finale
  • Deve essere bloccato fino a una decisione finale: rilascio o rifiuto

Se costruisci su una piattaforma come AppMaster, tratta lo “stato di scansione” come un campo di prima classe nel modello dati e fai controllare quello stato a ogni azione di download. Questa singola barriera previene molti errori costosi.

Cosa significa davvero quarantena per i documenti caricati

“Quarantena” è meglio intenderla come uno stato nel tuo sistema, non solo come una cartella nello storage. L’idea chiave è semplice: il file esiste, ma nessuno può aprirlo o scaricarlo finché la tua app non ha un risultato di scansione chiaro e registrato. Questo è il cuore della scansione virus per i caricamenti.

La quarantena funziona generalmente come un piccolo ciclo di vita con stati chiari. Mantenere lo stato esplicito rende più difficile perdere contenuti non sicuri tramite una preview, un URL diretto o un job di esportazione.

Un set pratico di stati file è il seguente:

  • received (upload completato, non ancora scansionato)
  • scanning (preso in carico da un worker)
  • clean (sicuro per il rilascio)
  • rejected (malware trovato o violazione di policy)
  • failed (errore del scanner, timeout o file corrotto)

La quarantena ha anche bisogno dei metadati giusti per poter applicare l’accesso e verificare cosa è successo in seguito. Al minimo, conserva: il proprietario (utente o organizzazione), lo stato, il nome originale del file e il tipo, il checksum (per dedup e controlli di manomissione), la posizione di storage e i timestamp (caricato, scansione iniziata, scansione terminata). Molti team salvano anche la versione del scanner e i dettagli del verdetto della scansione.

La retention è una decisione di policy, ma deve essere intenzionale. Mantieni i file in quarantena solo per il tempo necessario per scansionarli e risolvere i guasti. Una retention breve riduce rischio e costo, ma devi comunque avere tempo sufficiente per indagare incidenti e supportare utenti che chiedono “dove è andato il mio upload?”.

Infine, decidi cosa fare con i file che non completano mai la scansione. Imposta un tempo massimo di scansione e un timestamp di “scadenza”. Quando la scadenza passa, muovi il file in failed, blocca l’accesso e o ritenta automaticamente per un numero limitato di volte o cancellalo e chiedi all’utente di ricaricare.

Pattern di storage temporaneo che riducono il rischio

Lo storage temporaneo è dove si verificano la maggior parte dei problemi di upload. Il file è nel tuo sistema, ma ancora non sai se è sicuro, quindi serve un posto facile da bloccare e difficile da esporre per errore.

Il disco locale può funzionare per un singolo server, ma è fragile. Se ridimensioni su più server applicativi devi condividere storage, copiare file e mantenere permessi consistenti. L’object storage (come un bucket in stile S3 o un contenitore cloud) è spesso più sicuro per app con molti documenti perché le regole di accesso sono centralizzate e i log più chiari.

Un pattern semplice per la scansione virus sui caricamenti è separare lo storage di “quarantena” da quello “pulito”. Puoi farlo con due bucket/contenitori, che riduce gli errori, o con un prefisso rigoroso all’interno di un unico bucket, che può essere più economico e semplice da gestire.

Se usi i prefissi, rendili impossibili da confondere. Preferisci una struttura come quarantine/<tenant_id>/<upload_id> e clean/<tenant_id>/<document_id>, non nomi forniti dall’utente. Non riutilizzare mai lo stesso percorso per stati diversi.

Tieni a mente queste regole:

  • Non permettere letture pubbliche sulla quarantena, neppure “temporanee”.
  • Genera nomi degli oggetti lato server, non lato client.
  • Partiziona per tenant o account per ridurre il raggio d’impatto.
  • Conserva i metadati (proprietario, stato, checksum) nel database, non nel nome del file.

Cripta i dati at-rest e sii rigoroso su chi può decriptare. L’API di upload dovrebbe poter scrivere in quarantena, lo scanner dovrebbe poter leggere dalla quarantena e scrivere in clean, e l’app pubblica dovrebbe leggere solo da clean. Se il tuo cloud supporta policy di chiavi, lega i diritti di decrittazione al set minimo possibile di ruoli.

I file grandi richiedono cura extra. Per upload multipart, non segnare l’oggetto come “ready” fino a che la parte finale non è committata e non hai registrato la dimensione attesa e il checksum. Un approccio sicuro comune è caricare le parti in quarantena, poi copiare o promuovere l’oggetto in clean solo dopo che la scansione è passata.

Esempio: in un portale clienti costruito con AppMaster, puoi trattare ogni upload come “pending”, memorizzarlo in un bucket di quarantena e mostrare il pulsante di download solo dopo che lo stato di scansione è cambiato in “clean”.

Opzioni di architettura: scansione inline vs scansione in background

Quando aggiungi la scansione virus ai caricamenti, di solito scegli tra due flussi: scansione inline (l’utente aspetta) o scansione in background (l’app accetta l’upload ma blocca l’accesso finché non è verificato). La scelta giusta dipende meno dal “livello di sicurezza” (entrambi possono essere sicuri) e più da velocità, affidabilità e frequenza degli upload.

Opzione 1: scansione inline (l’utente aspetta)

La scansione inline significa che la richiesta di upload non termina finché lo scanner non restituisce un risultato. Sembra semplice perché c’è un solo passo: caricare, scansionare, accettare o rifiutare.

La scansione inline è generalmente accettabile quando i file sono piccoli, gli upload sono rari e puoi mantenere il tempo di attesa prevedibile. Per esempio, uno strumento interno dove gli utenti caricano pochi PDF al giorno potrebbe tollerare una pausa di 3–10 secondi. Lo svantaggio è che una scansione lenta rende lenta l’app. Timeout, retry e reti mobili possono trasformare un file pulito in una cattiva esperienza utente.

Opzione 2: scansione in background (async)

La scansione asincrona memorizza prima il file, lo marca come “quarantena” e mette un job in una coda di scansione. L’utente riceve una risposta rapida “upload ricevuto”, ma non può scaricare o anteprima il file finché non viene approvato.

Questo approccio è migliore per volumi elevati, file grandi e ore di punta perché distribuisce il lavoro e mantiene l’app reattiva. Permette anche di scalare i worker di scansione separatamente dai server web o API principali.

Un ibrido pratico è: eseguire controlli veloci inline (allowlist dei tipi di file, limiti di dimensione, validazione di formato di base), poi fare la scansione antivirus completa in background. Questo intercetta problemi ovvi presto senza far aspettare ogni utente.

Ecco un modo semplice per scegliere:

  • File piccoli, basso volume, workflow in cui serve sapere subito: scansione inline
  • File grandi, molti upload o tempi di scansione imprevedibili: scansione in background
  • SLA rigorosi per la reattività degli upload: scansione in background con UI di stato chiara
  • Carichi misti: ibrido (controlli rapidi prima, scansione completa async)

Se costruisci con AppMaster, questa scelta spesso mappa chiaramente a un endpoint API sincrono (inline) o a un Business Process che mette in coda il lavoro di scansione e aggiorna lo stato del file quando arrivano i risultati.

Passo dopo passo: costruire una coda di scansione async

Add upload audit trails
Add audit fields for who uploaded, when scanned, and final decision.
Try It

La scansione async significa che accetti un upload, lo metti in quarantena e lo scansi in background. Gli utenti non ottengono accesso finché lo scanner non dichiara il file sicuro. Questa è generalmente l’architettura di scansione malware più pratica per app con molti documenti.

1) Definisci il messaggio della coda (tienilo piccolo)

Tratta la coda come una lista di cose da fare. Ogni upload crea un messaggio che punta al file, non il file stesso.

Un messaggio semplice di solito include:

  • File ID (o object key) e tenant o project ID
  • ID dell’utente che ha caricato
  • Timestamp dell’upload e un checksum (opzionale ma utile)
  • Numero di tentativo (o un contatore di retry separato)

Evita di mettere byte grezzi nella coda. Payload grandi possono superare i limiti, costare di più e aumentare l’esposizione.

2) Costruisci il flow del worker (fetch, scan, record)

Un worker prende un messaggio, recupera il file dallo storage di quarantena, lo scansiona e poi scrive la decisione.

Un flow chiaro è:

  • Recupera il file per ID dallo storage di quarantena (bucket privato o volume privato)
  • Esegui lo scanner (motore AV o servizio di scansione)
  • Scrivi il risultato nel database: stato (clean, infected, error), nome/versione dello scanner e timestamp
  • Se clean: sposta il file nello storage approvato o cambia un flag di accesso così diventa scaricabile
  • Se infected: mantienilo in quarantena (o cancellalo) e notifica le persone giuste

3) Rendilo idempotente (sicuro da riprocessare)

I worker crashano, i messaggi vengono consegnati due volte e i retry accadono. Progetta in modo che scansionare lo stesso file due volte non causi danni. Usa una sorgente di verità unica come files.status e consenti solo transizioni valide, per esempio: uploaded -> scanning -> clean/infected/error. Se un worker vede clean, deve fermarsi e riconoscere il messaggio.

4) Controlla la concorrenza (evita tempeste di scansione)

Imposta limiti per worker e per tenant. Limita quante scansioni possono correre contemporaneamente e considera code separate per file grandi. Questo evita che un cliente occupi tutta la capacità degli scanner.

5) Gestisci i fallimenti con retry e traccia di audit

Usa retry per errori temporanei (timeout dello scanner, problema di rete) con un numero massimo di tentativi ridotto. Dopodiché invia il messaggio in una dead-letter queue per revisione manuale.

Mantieni una traccia di audit: chi ha caricato il documento, quando è entrato in quarantena, quale scanner è stato eseguito, cosa ha deciso e chi ha approvato o cancellato il file. Quel log è importante quanto la scansione stessa, specialmente per portali clienti e conformità.

Controllo degli accessi: mantenere i file in quarantena veramente privati

La quarantena non è solo uno stato nel database. È la promessa che nessuno può aprire il file finché non è dimostrato sicuro. La regola più sicura è semplice: non servire mai file in quarantena tramite URL pubblici, neppure “temporanei”.

Un buon flow di download è noioso e rigoroso. L’app deve trattare ogni download come un’azione protetta, non come il recupero di un’immagine.

  1. Richiesta di download
  2. Controllo del permesso dell’utente su quel preciso file
  3. Controllo dello stato del file (quarantena, clean, rejected)
  4. Consegna del file solo se lo stato è clean

Se usi URL firmati, mantieni lo stesso principio: generali solo dopo i controlli di permesso e stato, e falle a breve scadenza. Una scadenza breve riduce il danno se il link viene perso nei log, in screenshot o inoltrato per email.

Il controllo basato sui ruoli aiuta a evitare logiche “casi speciali” che poi diventano falle. I ruoli tipici per app con molti documenti sono:

  • Uploader: può vedere i propri upload e lo stato di scansione
  • Reviewer: può visualizzare file clean e, talvolta, visualizzare file in quarantena solo in uno strumento di revisione sicuro
  • Admin: può investigare, riscanare e forzare override quando necessario
  • Utente esterno: può accedere solo ai documenti condivisi esplicitamente con lui

Proteggi anche contro l’indovinare gli ID. Non esporre ID incrementali come 12345. Usa ID opachi e autorizza sempre per utente e file (non solo “qualunque utente autenticato”). Anche se il tuo bucket è privato, un endpoint API distratto può comunque fare trapelare contenuti in quarantena.

Quando implementi la scansione virus per i caricamenti, il layer di accesso è dove avvengono la maggior parte dei problemi reali. Su una piattaforma come AppMaster, faresti rispettare questi controlli negli endpoint API e nella business logic prima di generare qualsiasi risposta di download, così la quarantena rimane privata di default.

Rilascio, rifiuto e ritentativi: gestire i risultati della scansione

Build safer upload workflows
Model quarantine states and enforce download gates without writing code.
Try AppMaster

Quando un file completa la scansione, la cosa più importante è muoverlo in uno stato chiaro e rendere prevedibile il passo successivo. Se implementi la scansione virus per i caricamenti, considera il risultato della scansione come un cancello: nulla diventa scaricabile finché il cancello non lo permette.

Un insieme semplice di esiti copre la maggior parte dei sistemi reali:

  • Clean: rilasciare il file dalla quarantena e permettere l’accesso normale.
  • Infected: bloccare l’accesso permanentemente e attivare il workflow per file infetti.
  • Unsupported: lo scanner non può valutare questo tipo (o è protetto da password). Mantienilo bloccato.
  • Scan error: errore temporaneo (timeout, servizio non disponibile). Mantienilo bloccato.

I messaggi agli utenti devono essere chiari e tranquilli. Evita formulazioni allarmistiche come “Il tuo account è compromesso.” Meglio: “Il file è in fase di controllo. Puoi continuare a lavorare.” Se il file è bloccato, indica cosa può fare l’utente: “Carica un altro formato” o “Riprova più tardi.” Per i file non supportati sii specifico (per esempio, “Archivi crittografati non possono essere scansionati”).

Per i file infetti, decidi presto se cancellare o conservare. Cancellare è più semplice e riduce il rischio. Conservare può aiutare per audit, ma solo se lo salvi in un’area isolata con accessi molto restritti e retention breve, e logghi chi vi ha accesso (idealmente nessuno tranne gli admin di sicurezza).

I retry sono utili, ma solo per errori temporanei. Imposta una policy di retry ridotta per non creare backlog infiniti:

  • Ritenta su timeout e indisponibilità dello scanner.
  • Non ritentare su “infected” o “unsupported”.
  • Limita i retry (per esempio 3) e poi marca come failed.
  • Aggiungi backoff tra i tentativi per evitare sovraccarichi.

Infine, tratta i fallimenti ripetuti come un problema operativo, non come un problema utente. Se molti file finiscono in “scan error” in breve tempo, allerta il team e metti in pausa i nuovi rilasci. In AppMaster puoi modellare questi stati nel database e instradare notifiche tramite i moduli integrati in modo che le persone giuste ricevano gli avvisi rapidamente.

Scenario di esempio: un portale clienti con molti documenti

Separate quarantine from clean
Design private quarantine storage and clean storage paths for every tenant.
Get Started

Un portale clienti permette ai clienti di caricare fatture e contratti per ogni progetto. È un luogo comune dove la scansione virus per i caricamenti è importante, perché gli utenti trascineranno qualunque cosa abbiano sul desktop, inclusi file inoltrati da altri.

Quando un cliente carica un PDF, il portale lo salva in una posizione temporanea e privata e crea un record nel database con stato impostato su Pending scan. Il file non è ancora mostrato come scaricabile. Un worker di scansione prende il file da una coda, esegue la scansione e poi aggiorna il record a Clean o Blocked.

Nell’interfaccia, il cliente vede il documento apparire subito, ma con un badge chiaro Pending. Il nome del file e la dimensione sono visibili così sa che l’upload è andato a buon fine, ma il pulsante Download è disabilitato finché la scansione non è pulita. Se la scansione impiega più del previsto, il portale può mostrare un messaggio semplice come “Stiamo controllando questo file per sicurezza. Riprova tra un minuto.”

Se lo scanner segnala un documento, il cliente vede Blocked con una breve nota non tecnica: “Questo file non ha superato un controllo di sicurezza.” Il supporto e gli admin ottengono una vista separata che include la ragione della scansione e le azioni successive. Possono:

  • mantenerlo bloccato e richiedere un nuovo upload
  • cancellarlo e registrare il motivo
  • segnalarlo come falso positivo solo se la policy lo consente

In caso di dispute (“L’ho caricato ieri e voi l’avete perso”), i log accurati sono fondamentali. Conserva timestamp per upload ricevuto, scansione iniziata, scansione terminata, stato cambiato e chi ha fatto cosa. Conserva anche hash del file, nome originale, account caricatnte, indirizzo IP e codice di risultato dello scanner. Se costruisci questo in AppMaster, il Data Designer più un semplice Business Process possono gestire questi stati e campi di audit senza esporre i file in quarantena agli utenti normali.

Errori comuni che causano vere falle di sicurezza

La maggior parte dei fallimenti nella sicurezza degli upload non sono hack fantasiosi. Sono piccole scelte di progettazione che permettono a un file non sicuro di comportarsi come un documento normale.

Un problema classico è una race: l’app accetta un upload, restituisce un URL di download e l’utente (o un altro servizio) può recuperare il file prima che la scansione sia terminata. Se fai la scansione virus per i caricamenti, tratta “caricato” e “disponibile” come due stati diversi.

Ecco errori che ricorrono spesso:

  • Mescolare file clean e quarantena nello stesso bucket/cartella e poi affidarsi alle regole di naming. Un permesso o un percorso sbagliato e la quarantena è inutile.
  • Fidarsi delle estensioni, del MIME type o dei controlli lato client. Gli attaccanti possono rinominare qualunque cosa in .pdf e la tua UI chiuderà un occhio.
  • Non prevedere l’indisponibilità dello scanner. Se lo scanner è lento o offline, i file rimangono in pending e i team iniziano a usare override manuali non sicuri.
  • Permettere ai worker in background di saltare le stesse regole di autorizzazione dell’API principale. Un worker che può leggere “qualunque file” è una quieta escalation di privilegi.
  • Pubblicare ID facili da indovinare (come numeri incrementali) per elementi in quarantena, anche se pensi che il contenuto sia protetto.

Anche i test rappresentano una lacuna. I team testano con pochi file piccoli e puliti e si considerano a posto. Devi anche provare upload grandi, file corrotti e documenti protetti da password, perché sono proprio quei casi dove scanner e parser falliscono o fanno timeout.

Un esempio semplice nella vita reale: un utente carica un “contract.pdf” che in realtà contiene un eseguibile rinominato dentro un archivio. Se il portale lo serve immediatamente, o il team di supporto può accedere alla quarantena senza i controlli appropriati, hai creato una via diretta per consegnare il file a altri utenti.

Checklist rapida prima del rilascio

Create a secure document portal
Build a customer portal where downloads stay blocked until scans pass.
Start App

Prima di rilasciare la scansione virus per i caricamenti, fai un ultimo controllo sui punti dove i team tendono a pensare “va bene” e poi scoprono che non lo era. L’obiettivo è semplice: un file non sicuro non deve mai diventare leggibile solo perché qualcuno ha indovinato un URL, ritentato una richiesta o usato un link in cache.

Parti dal flusso utente. Ogni azione di download, preview o “apri file” dovrebbe ricontrollare lo stato corrente di scansione al momento della richiesta, non solo al momento del caricamento. Questo ti protegge da race condition (qualcuno clicca immediatamente), risultati di scansione ritardati e casi limite in cui un file viene riscansionato.

Usa questa checklist pre-lancio come baseline minima:

  • Lo storage di quarantena è privato di default: niente bucket pubblico, niente “chiunque con il link” e niente serving diretto dallo object storage.
  • Ogni record file ha un proprietario (utente, team o tenant) più uno stato di ciclo di vita come pending, clean, infected o failed.
  • La coda di scansione e i worker hanno retry limitati, regole di backoff chiare e alert quando gli elementi restano bloccati o falliscono ripetutamente.
  • Esistono log di audit per upload, risultati di scansione e tentativi di download (inclusi quelli bloccati), con chi, quando e perché.
  • Esiste un override manuale per casi rari, ma è solo per admin, registrato e limitato nel tempo (niente “mark clean” silenzioso).

Infine, assicurati di poter osservare il sistema end-to-end. Devi poter rispondere a: “Quanti file sono in attesa di scansione adesso?” e “Quali tenant stanno avendo problemi?” Se costruisci su AppMaster, modella il ciclo di vita del file nel Data Designer e fai rispettare i controlli di stato nel Business Process Editor così le regole restano coerenti su web e mobile.

Passi successivi: trasformare il progetto in un’app funzionante

Inizia scrivendo gli stati esatti in cui i tuoi file possono trovarsi e cosa permette ciascuno stato. Mantienilo semplice ed esplicito: “uploaded”, “queued”, “scanning”, “clean”, “infected”, “scan_failed”. Poi aggiungi le regole di accesso accanto a ciascuno stato. Chi può vedere il file, scaricarlo o cancellarlo mentre è ancora non affidabile?

Poi scegli l’approccio che corrisponde a volume e obiettivi di UX. La scansione inline è più semplice da spiegare, ma può rendere gli upload lenti. La scansione async scala meglio per app con molti documenti, ma aggiunge stato, code e UI “pending”.

Un modo pratico per passare da design a build è prototipare il flusso end-to-end usando documenti realistici (PDF, Office, immagini, archivi) e comportamenti utente realistici (upload multipli, cancellazioni, retry). Non fermarti a “lo scanner funziona”. Verifica che l’app non serva mai un file in quarantena, nemmeno per errore.

Ecco un piano di lavoro semplice che puoi eseguire in una settimana:

  • Definisci stati dei file, transizioni e regole di accesso in una pagina
  • Scegli scansione inline, async o ibrida e documenta i compromessi
  • Implementa upload -> quarantena storage -> scan job -> callback di risultato, con log di audit
  • Costruisci gli stati UI che gli utenti vedranno (pending, blocked, failed, approved)
  • Aggiungi monitoring fin dal primo giorno: dimensione backlog, tasso di errori e tempo per arrivare a clean

Se usi uno strumento no-code, AppMaster può aiutarti a modellare i metadati dei file (stato, proprietario, checksum, timestamp), costruire schermate di upload e revisione e orchestrare il workflow di scansione con logica di business e processi in stile coda. Questo ti permette di testare il flusso reale del prodotto presto, poi rinforzare le parti che contano: permessi, separazione dello storage e retry affidabili.

Infine, decidi numericamente cosa significa “bene”. Imposta soglie di alert prima del lancio così noterai scansioni bloccate e fallimenti in aumento prima che lo facciano gli utenti.

Facile da avviare
Creare qualcosa di straordinario

Sperimenta con AppMaster con un piano gratuito.
Quando sarai pronto potrai scegliere l'abbonamento appropriato.

Iniziare
Scansione virus per i caricamenti di file: opzioni di architettura per le app | AppMaster