File di test per casi limite — Corrotti, troncati, vuoti e con etichetta sbagliata

36 file · link diretti · niente pubblicità · uso libero

Niente zip bombNiente eseguibiliNiente stringhe di malwareSHA-256 pubblicatoSicuri da estrarre

Il resto di questa raccolta risponde a "dammi un PNG valido". Questa pagina risponde alla domanda più difficile: cosa fa il tuo codice con un file troncato, vuoto, con il nome sbagliato, che mente sul proprio tipo o che contiene dati che non dovrebbe avere? Sono questi i caricamenti che arrivano in produzione, ed è così noioso costruirli a mano che la maggior parte delle suite di test non ci prova nemmeno.

Ogni file qui è sicuro. Niente zip bomb, niente voci di path traversal, niente eseguibili e niente stringhe di test antivirus; l'archivio più grande si espande a meno di un megabyte. I modi in cui falliscono sono autentici, i contenuti non sono pericolosi, e lo SHA-256 di ogni file è pubblicato, così puoi fissarlo come fixture.

Inizia da questi due. Il file HTML chiamato .jpg ti dice se il caricamento di un'immagine può trasformarsi in cross-site scripting persistente sul tuo dominio. Il CSV con payload di formule ti dice se le tue esportazioni arrivano nel foglio di calcolo di un collega come formule attive. Sono questi due a scovare più spesso bug reali.

File vuoti e quasi vuoti

Un caricamento da zero byte è in assoluto la cosa che si dimentica più spesso. I validatori che controllano una dimensione massima spesso dimenticano quella minima, e il codice che legge il primo byte prima di controllare la lunghezza va in crash qui invece di restituire un errore pulito.

FileCosa testaDimensioneScarica
zero-byte.txtCompletamente vuoto. Testa la validazione della dimensione minima, le divisioni per la lunghezza e il codice che legge un primo byte prima di verificare che esista.0 BScarica
one-byte.txtUn solo carattere. Troppo piccolo per contenere un header valido in qualsiasi formato, quindi il rilevamento del tipo deve fallire in modo controllato.1 BScarica
empty-archive.zipUno ZIP strutturalmente valido senza alcuna voce. L'estrazione deve riuscire e non produrre nulla, non generare un'eccezione.22 BScarica

File troncati e danneggiati

Hanno un header valido e dati incompleti o danneggiati, che è esattamente l'aspetto di un caricamento interrotto. Il codice che si fida dell'header e legge il resto in streaming fallirà qui, e il punto in cui fallisce ti dice se la gestione degli errori è davvero dove pensi.

FileCosa testaDimensioneScarica
truncated.pngFirma PNG e IHDR validi, troncato a metà dei dati dell'immagine. Qui i decoder generano un errore invece di restituire un'immagine parziale.4 KBScarica
corrupt-crc.pngLunghezza completa e struttura corretta, ma un byte nei dati dell'immagine è stato invertito e il CRC memorizzato non corrisponde più. I decoder rigorosi lo rifiutano; quelli permissivi restituiscono pixel sbagliati.9 KBScarica
truncated.jpgUn JPEG troncato al 60 percento, senza marcatore di fine immagine. Molti decoder restituiscono un'immagine decodificata a metà invece di fallire, ed è utile sapere come si comporta il tuo.603 BScarica
truncated.zipLa directory centrale è troncata: è l'aspetto del caricamento a metà di un archivio. È lo ZIP danneggiato più comune nella realtà.3 KBScarica
malformed.jsonUna virgola finale, una chiave senza virgolette e una parentesi graffa non chiusa. Verifica che il tuo parser indichi una posizione utile invece di un errore generico.136 BScarica

File che mentono sul proprio tipo

L'estensione dice una cosa, i byte un'altra. Se il tuo gestore di caricamenti si fida dell'estensione o del Content-Type fornito dal browser, questi file passano. Quello che conta è il file HTML chiamato .jpg: servito con un content type da immagine è innocuo, servito come HTML dal tuo dominio è cross-site scripting memorizzato.

FileCosa testaDimensioneScarica
actually-a-png.jpgUn vero PNG con estensione .jpg. Tutto ciò che sceglie il decoder in base all'estensione lo passerà a quello sbagliato.9 KBScarica
actually-html.jpgUn documento HTML con estensione .jpg. Se la tua applicazione lo memorizza e lo serve con un content type indovinato, hai un cross-site scripting memorizzato.335 BScarica

Metadati e privacy

Una foto appena uscita da un telefono riporta dove è stata scattata e come è orientata. Se non rimuovi la prima informazione riveli la posizione dei tuoi utenti; se ignori la seconda ogni foto verticale appare ruotata. Questo file le contiene entrambe, così puoi verificare che la tua pipeline gestisca ciascuna.

FileCosa testaDimensioneScarica
exif-gps-orientation.jpgContiene coordinate GPS (la CN Tower di Toronto) e Orientation 6, cioè va ruotata di 90 gradi in senso orario per essere visualizzata dritta. Usala per verificare sia che rimuovi i dati di posizione sia che rispetti la rotazione.1 KBScarica

Testo, codifica e fine riga

Un byte order mark che diventa un carattere visibile nella prima colonna, campi tra virgolette con virgole e a capo letterali, tre diversi terminatori di riga nello stesso file e nessun terminatore alla fine. Sono tutte cose normali nei file che ti mandano gli utenti reali.

FileCosa testaDimensioneScarica
bom-crlf-quoted.csvUn byte order mark UTF-8, terminatori CRLF, campi tra virgolette che contengono virgole, doppie virgolette con escape, un a capo letterale dentro un campo e nomi non ASCII. Se il BOM compare nell'intestazione della prima colonna, il bug è quello.180 BScarica
unicode-torture.txtSegni diacritici combinanti, uno spazio a larghezza zero, un override da destra a sinistra, caratteri dei piani astrali e un'emoji di bandiera da sei code point. Testa il conteggio della lunghezza, il troncamento e la normalizzazione.565 BScarica
mixed-line-endings.txtLF, CRLF e un CR isolato nello stesso file, senza terminatore sull'ultima riga. Qui il codice che conta le righe spesso si contraddice.107 BScarica
no-trailing-newline.txtTermina senza a capo. Aggiungere righe a questo file senza controllare produce due record uniti in uno.48 BScarica

Nomi di file difficili

Il test è il nome, non il contenuto. I nomi lunghi superano la dimensione delle colonne del database e i limiti del file system; i nomi non ASCII mandano in crisi gli header Content-Disposition, l'escaping degli URL e la differenza tra Unicode composto e scomposto su macOS.

FileCosa testaDimensioneScarica
文件名-with spaces-🌲.txtCaratteri cinesi, spazi e un'emoji nel nome del file. Testa la codifica di Content-Disposition, l'escaping degli URL e la normalizzazione Unicode scomposta di macOS.194 BScarica

Limiti strutturali e di risorse

File validi, scomodi più che difettosi: un archivio con diecimila voci, JSON annidato più in profondità di quanto la maggior parte dei parser consenta di default e un archivio cifrato. Nessuno di questi è un attacco: sono le forme che fanno esaurire qualche risorsa a un'implementazione ingenua.

FileCosa testaDimensioneScarica
many-entries-10000.zipDiecimila piccole voci, meno di 1 MB non compresso in totale. Testa l'analisi della directory centrale e il costo per singola voce. Volutamente non è una zip bomb.1.6 MBScarica
deeply-nested.json512 livelli di annidamento. JSON valido, ma più profondo di quanto molti parser consentano di default, e abbastanza profondo da esaurire lo stack di un parser ricorsivo.3 KBScarica
encrypted-password-test.zipCifrato con ZipCrypto; la password è test. L'estrazione senza password deve fallire in modo pulito invece di produrre dati senza senso.292 BScarica

Iniezione di formule nei fogli di calcolo

Una cella CSV che inizia con =, +, - o @ viene interpretata come formula quando il file si apre in Excel, Google Sheets o LibreOffice. Se la tua applicazione esporta in CSV testo inserito dagli utenti senza fare l'escape di questi prefissi, stai distribuendo il loro input sotto forma di formule eseguibili. I payload qui eseguono calcoli aritmetici innocui.

FileCosa testaDimensioneScarica
formula-injection.csvCelle che iniziano con =, +, - e @, che i fogli di calcolo trattano come formule. I payload eseguono calcoli aritmetici innocui e uno crea un link a questo sito. Nulla esegue comandi.189 BScarica

Modelli 3D: mesh vuote, difettose e ingannevoli

Il codice che gestisce le mesh tende a presumere un modello chiuso, di dimensioni sensate, con le facce orientate correttamente e almeno un triangolo. Gli utenti caricano tutto il resto. Questi file coprono la mesh vuota, triangoli ad area nulla e rivoltati, una mesh non-manifold, coordinate troppo grandi o troppo piccole perché float32 le gestisca bene, un GLB interrotto a metà caricamento, un STL il cui header mente, un GLB che finge di essere un STL e l'STL binario che inganna il classico controllo “inizia con solid quindi è ASCII”. Si trovano nella cartella 3D; i modelli 3D validi sono nella categoria Modelli 3D.

FileCosa testaDimensioneScarica
empty-mesh-zero-triangles.stlUn STL binario strutturalmente valido: l'header da 80 byte e un numero di triangoli pari a 0, nient'altro (84 byte). Il codice per bounding box, centratura e miniature qui spesso divide per zero o accede a un array vuoto.84 BScarica
empty-scene-no-meshes.glbUn glTF 2.0 binario valido con una scena e un nodo vuoto ma senza mesh, buffer o materiali. Supera il validatore Khronos. I visualizzatori devono mostrare una scena vuota, non generare un'eccezione.276 BScarica
degenerate-triangles.stlUn cubo da 10 mm più sei triangoli ad area nulla: vertici ripetuti, punti allineati e una scheggia sotto l'epsilon. Il calcolo delle normali qui divide per una lunghezza zero, ed è da lì che nascono le normali NaN.984 BScarica
flipped-normals-inside-out.stlUn cubo da 10 mm con tutti i triangoli orientati in senso orario e le normali memorizzate rivolte verso l'interno. Con il back-face culling appare nero o invisibile, e il suo volume con segno è negativo.684 BScarica
non-manifold-open-box-and-fins.stlUna scatola senza coperchio (un bordo aperto) più due alette che condividono ciascuna uno spigolo con altre due facce. Non è stampabile così com'è; slicer e strumenti di riparazione devono segnalare entrambi i problemi.684 BScarica
huge-coordinates-1e7.stlUn cubo di 100 unità centrato a dieci milioni di unità dall'origine. A quella grandezza float32 può rappresentare solo numeri interi, quindi emergono problemi di precisione, di piano di clipping lontano della camera e di inquadratura automatica.684 BScarica
tiny-scale-1e-6.stlUn cubo largo un milionesimo di unità. Letto in millimetri è un micrometro: testa i controlli di dimensione minima, l'individuazione delle unità e qualsiasi epsilon usato per unire i vertici.684 BScarica
extreme-float-values.stlCoordinate dei vertici a ±3,0e38, vicino al massimo di float32, e un triangolo fatto di valori subnormali 1e-40. Nel file non ci sono NaN né Infinity, ma calcolare la dimensione del bounding box in float32 va in overflow e dà Infinity.234 BScarica
truncated.glbIl primo 60 percento di un GLB con texture valido. L'header dichiara ancora la lunghezza completa e il chunk BIN termina prima del previsto: è l'aspetto di un caricamento interrotto di un GLB.80 KBScarica
wrong-triangle-count-header.stlUn STL binario il cui conteggio uint32 dichiara 1.000 triangoli mentre il file ne contiene 12. Un lettore che si fida del conteggio legge oltre la fine; uno rigoroso rifiuta il file perché 84 + 50 × 1.000 non corrisponde alla sua dimensione.684 BScarica
actually-a-glb.stlUn GLB vero e valido (inizia con i byte glTF) salvato con estensione .stl. Tutto ciò che sceglie il parser in base all'estensione lo passa al parser STL.21 KBScarica
binary-stl-header-starts-with-solid.stlUn STL binario valido il cui header di testo libero inizia con la parola solid, come scrivono diversi esportatori reali. Riconoscere un STL ASCII da quel prefisso manda questo file al parser sbagliato; confronta invece la dimensione con il numero di triangoli.684 BScarica
obj-missing-mtl.objUn OBJ altrimenti valido la cui riga mtllib indica un file di materiali inesistente. La geometria deve comunque caricarsi con un materiale predefinito e un avviso, non fallire.914 BScarica
obj-negative-indices.objUn OBJ valido le cui facce usano indici negativi e relativi (f -3 -2 -1), consentiti dal formato. Molti parser scritti a mano supportano solo indici positivi.675 BScarica
立方体 cube-modèle-🧊.stlUn cubo valido da 10 mm il cui nome di file mescola caratteri cinesi, una lettera accentata, uno spazio e un'emoji. Testa Content-Disposition, la codifica degli URL e le chiavi di archiviazione per i caricamenti di modelli.684 BScarica

Una breve checklist per la gestione dei caricamenti

  1. Controlla una dimensione minima oltre a quella massima. I caricamenti da zero byte sono il caso dimenticato più spesso.
  2. Determina il tipo dai byte, mai dall'estensione o dal content type fornito dal browser. Entrambi sono controllati da un eventuale attaccante.
  3. Servi i file caricati dagli utenti da un dominio separato, oppure con Content-Disposition: attachment e X-Content-Type-Options: nosniff, così un file che si rivela HTML non può essere eseguito nella tua origine.
  4. Rimuovi i dati EXIF prima di pubblicare un'immagine, e applica il tag di orientamento prima di rimuoverli.
  5. Fai l'escape dei caratteri iniziali =, +, - e @ quando scrivi testo degli utenti in un CSV.
  6. Imposta limiti espliciti al numero di voci di un archivio, alla dimensione totale decompressa e alla profondità di ricorsione del parser, e restituisci un errore chiaro quando uno viene superato.
  7. Decidi cosa deve succedere con un file caricato solo in parte, poi verificalo con i file troncati di questa pagina invece di dare per scontato il risultato.

Domande frequenti

Questi file sono pericolosi?

No. Non ci sono zip bomb, voci di path traversal, eseguibili, macro né stringhe di test antivirus. Il file più grande si espande a meno di un megabyte. I modi in cui falliscono sono reali (un'immagine troncata è davvero troncata), ma niente qui attacca il computer che lo apre. I payload di formule nel foglio di calcolo eseguono calcoli innocui anziché lanciare un comando.

A cosa serve il file HTML con estensione .jpg?

È in assoluto il file più utile del pacchetto. Se la tua applicazione lo accetta come immagine, lo salva e poi lo restituisce con un content type dedotto dal contenuto, il browser lo mostra come una pagina del tuo dominio. È cross-site scripting persistente veicolato tramite il caricamento di un'immagine. Accettare il file va bene; restituirlo come HTML no.

Perché il CSV ha celle che iniziano con un segno di uguale?

Perché Excel, Google Sheets e LibreOffice interpretano come formula una cella che inizia con =, +, - o @. Se la tua applicazione esporta in CSV testo inserito dagli utenti senza fare l'escape di questi prefissi, qualunque cosa un utente abbia scritto in un modulo arriva nel foglio di calcolo di un collega come formula attiva. La soluzione è anteporre un apostrofo a queste celle o racchiuderle tra virgolette in fase di esportazione.

La foto contiene davvero coordinate GPS?

Sì: la CN Tower di Toronto, a 43,6426 nord e 79,3871 ovest, più l'altitudine. Contiene anche Orientation 6, cioè un visualizzatore deve ruotarla di 90 gradi in senso orario per mostrarla dritta. Insieme coprono le due cose che ogni pipeline di immagini deve fare bene: rimuovere i dati di posizione prima della pubblicazione e rispettare la rotazione, così le foto verticali non appaiono di lato.

Posso usarli in una suite di test automatizzati?

Sì, servono proprio a questo. Ogni file è deterministico, il suo SHA-256 è pubblicato qui e i link diretti hanno una lunga durata della cache e header CORS aperti. Fissa l'hash nel tuo test e saprai subito se una fixture cambia.

Hai trovato un problema o qualcosa che potrebbe andare meglio? Leggiamo ogni messaggio e sistemiamo le cose in fretta.

Ti servono file validi?

Per la maggior parte dei test serve un file che funziona. Pubblichiamo anche quelli: immagini, video, audio, documenti, archivi, dati, font e modelli 3D reali, in dimensioni esatte e con hash pubblicati.