Con questo articolo concludo l’articolo precedente EPrints Tips & tricks: limite upload e controllo antivirus in modo tale da bloccare il caricamento del file nel momento in cui viene selezionato per quanto riguarda la dimensione massima e bloccare il virus non appena il file è disponibile nel server senza che l’autore debba proseguire avanti o indietro nel wokflow di caricamento.
In tal caso il file non rimane nel server.
Introduzione
Questo che verrà descritto sarà valido se risulta attivo nel browser javascript altrimenti continua ad esser valido quello descritto nella parte 1 di 2 del precedente articolo.
Inoltre non vale neppure per i secondi o successivi file appartenenti allo stesso documento.
Consideriamo valide tutta l’introduzione dell’articolo parte 1 di 2 e che sia presente l’antivirus ClamAV come descritto sempre nel predente articolo.
Implementazione
Per gestire la variabile “upload_limit” anche in javascript aggiungiamo al file di configurazione $EPCONF/conf.d/upload.pl precedentemente commentato con il seguente codice:
$c->add_trigger( EP_TRIGGER_DYNAMIC_TEMPLATE, sub {
my %params = @_;
my $repo = $params{repository};
my $pins = $params{pins};
my $upload_limit=$repo->get_conf('upload');
$upload_limit=$upload_limit->{'upload_limit'};
my $pagetop = $repo->make_doc_fragment;
$pagetop->appendChild( $repo->make_javascript(qq|var upload_limit=|.$upload_limit.";"));
if( defined $pins->{pagetop} ) {
$pagetop->appendChild( $pins->{pagetop} );
$pins->{pagetop} = $pagetop;
}
else {
$pins->{pagetop} = $pagetop;
}
return EP_TRIGGER_OK;
});
Questo codice aggiunge un trigger relativo alla creazione dinamica della pagina html che definisce la variabile javascript “upload_limit” uguale al valore definito in perl.
Fatto ciò possiamo modificare il codice javascript che gestisce l’upload dei file nel workflow e cioè il file $EPRINTS/lib/static/javascript/auto/88_uploadmethod_file.js. Per non toccare il sorgente di eprints, di cui perderemmo traccia nel tempo o dopo un aggiornamento di versione è sempre meglio farne una copia con lo stesso nome in $EPCONF/static/javascript/auto/88_uploadmethod_file.js dove iniziamo a fare le modifiche.
Innanzitutto eprints differenzia se si fa
- un trascinamento di uno o più file (con il gestore dei file) dentro l’area di upload
- oppure se si clicca sul tasto “Sfoglia …” per aprire la classica finestra del browser per selezionare il file da caricare.
Infatti tramite trascinamento è possibile caricare più file alla volta mentre con il classico tasto “Sfoglia …” si carica al massimo un file alla volta.
Con le modifiche che propongo, innanzitutto, adeguo i 2 metodi di caricamento permettendo anche tramite la classica finestra del browser di poter selezionare più file alla volta.
Inoltre utilizzando l’oggetto “FileReader” di javascript posso immediatamente, durante la selezione, escludere i file più grandi di “upload_limit“.
Per il controllo antivirus uso poi una chiamata Ajax nel momento in cui il file è stato caricato completamente che mi restituisce se lo stato è “ok” oppure se è presente un virus richiamando la funzione “upload_file” definita nel solito file $EPCONF/cfg.d/upload.pl.
Il file richiamato in Ajax si trova sotto cgi/users/ajax/upload_validation.
Codice online
Per scaricare tutto il codice completo potete andare sul mio progetto “eprints_validate_upload_file_js” sotto github.
Osservazioni di sicurezza
Come nell’articolo precedente EPrints Tips & tricks: limite upload e controllo antivirus – parte 1 di 2 riporto le osservazioni di sicurezza.
Per non farvi riempire il disco e per evitare attacchi del tipo denial-of-service è sempre utile definire la massima dimensione del messaggio in POST (e quindi anche degli allegati) che il server accetterà.
Naturalmente la dimensione del POST in genere non corrisponde con la dimensione dell’allegato e quindi per sicurezza io metterei tale dimensione almeno al 20% in più rispetto a quella massima dell’allegato.
Per evitare un POST molto grande si possono utilizzare uno dei seguenti metodi:
- metodo a livello eprints: basta impostare la variabile $CGI::POST_MAX = 1024 * 1024 * 20; (20MB posts) in un file di configurazione (ad esempio proprio upload.pl)
- metodo a livello di apache: basta impostare “LimitRequestBody 20971520” (20MB posts). Come predefinito Apache 2.4 usa “LimitRequestBody 0” che corrisponde ad un massimo di 2GB.