Discussion:
Vérifier la taille d'un fichier
(trop ancien pour répondre)
Pascale
2011-10-31 09:56:28 UTC
Permalink
Bonjour,

Dans un formulaire qui permet d'uploader du texte et des images, j'utilise
(depuis fort longtemps) <input type="hidden" name="MAX_FILE_SIZE"
value="50000">.

Ensuite, du côté PHP, je fais un certain nombre de contrôles pour m'assurer
que le fichier est bien un jpg et pas autre chose. En particulier :

$contenu1=getimagesize($_FILES['photo1']['tmp_name']);
$type1=$contenu1[2];
if ($type1!=2) { echo 'Erreur...';}

Si le fichier téléchargé est trop lourd, getimagesize me renvoie une
erreur.

J'ai conscience que ce n'est pas très propre comme solution et que je
devrais spécifiquement vérifier la taille du fichier que la personne a
tenté de télécharger, d'autant que c'est l'erreur la plus courante commise
par les utilisateurs.

Le mieux est-il de vérifier tout bêtement la taille du fichier dans
$_FILES['photo1']['size'] ou vaut-il mieux vérifier le contenu de
$_FILES['photo1']['error'] ? Ou bien ?...
--
Pascale
http://www.la-grille-verte.net
DuboisP
2011-10-31 10:15:50 UTC
Permalink
Le Mon, 31 Oct 2011 10:56:28 +0100, Pascale
Post by Pascale
Bonjour,
Dans un formulaire qui permet d'uploader du texte et des images, j'utilise
(depuis fort longtemps) <input type="hidden" name="MAX_FILE_SIZE"
value="50000">.
Ensuite, du côté PHP, je fais un certain nombre de contrôles pour m'assurer
$contenu1=getimagesize($_FILES['photo1']['tmp_name']);
$type1=$contenu1[2];
if ($type1!=2) { echo 'Erreur...';}
Si le fichier téléchargé est trop lourd, getimagesize me renvoie une
erreur.
J'ai conscience que ce n'est pas très propre comme solution et que je
devrais spécifiquement vérifier la taille du fichier que la personne a
tenté de télécharger, d'autant que c'est l'erreur la plus courante commise
par les utilisateurs.
Le mieux est-il de vérifier tout bêtement la taille du fichier dans
$_FILES['photo1']['size'] ou vaut-il mieux vérifier le contenu de
$_FILES['photo1']['error'] ? Ou bien ?...
ça vaut ce que ça vaut, y'a probablement mieux, je ne suis pas spécialiste
du PHP

<?php

$phpmaxfilesize = ini_get('upload_max_filesize');
$sitemaxfilesize = 2097152;

/* non utilisé ici */
$uploaderror=array(UPLOAD_ERR_OK=>'Chargement correct',
UPLOAD_ERR_INI_SIZE=>'Fichier plus gros que le maximum autorisé sur
le serveur',
UPLOAD_ERR_FORM_SIZE=>'Le fichier téléchargé excède la taille
autorisée sur le site',
UPLOAD_ERR_PARTIAL=>'Le fichier n\'a été que partiellement
téléchargé',
UPLOAD_ERR_NO_FILE=>'Aucun fichier n\'a été téléchargé',
UPLOAD_ERR_NO_TMP_DIR=>'Un dossier temporaire est manquant',
UPLOAD_ERR_CANT_WRITE=>'Échec de l\'écriture du fichier sur le
disque',
UPLOAD_ERR_EXTENSION=>'Autre erreur de chargement'
);

/* http://www.iana.org/assignments/media-types/ */
$applicationtype=array('application/justbecause0canbefaulty',
'application/msword',
'application/ogg',
'application/pdf',
'application/rtf',
'application/vnd.ms-excel',
'application/vnd.ms-powerpoint',
'application/vnd.ms-project',
'application/vnd.oasis.opendocument.chart',
'application/vnd.oasis.opendocument.graphics',
'application/vnd.oasis.opendocument.presentation',
'application/vnd.oasis.opendocument.spreadsheet',
'application/vnd.oasis.opendocument.text',
'application/vnd.oasis.opendocument.text-master',
'application/vnd.openxmlformats-officedocument.presentationml.presentation',
'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'application/x-compress',
'application/x-compressed',
'application/x-zip',
'application/x-zip-compressed',
'application/zip',
'audio/mpeg',
'audio/ogg',
'audio/vnd.rn-realaudio',
'audio/x-ms-wma',
'audio/x-wav',
'image/gif',
'image/jpeg',
'image/png',
'image/tiff',
'multipart/x-zip',
'text/plain',
'video/mp4',
'video/ogg',
'video/quicktime',
'video/x-flv',
'video/x-ms-wmv',
'video/x-msvideo'
);

$document = $_FILES['filetoupload']['name'];
$taille = $_FILES['filetoupload']['size'];
$tmp = $_FILES['filetoupload']['tmp_name'];
$type = $_FILES['filetoupload']['type'];
$ferror = $_FILES['filetoupload']['error'];

if (!empty($document) && (!array_search($type, $applicationtype) ||
($taille > $sitemaxfilesize)))
{
$taille = $taille / 1024;
echo "<p class=\"erreur\">Erreur : Votre fichier ".$document." de taille
".$taille." ko, de type ".$type." est trop gros ou de type non
autorisé.</p>\n";
$erreur="1";
}


?>
--
Utilisant le client e-mail révolutionnaire d'Opera :
http://www.opera.com/mail/
Mickaël Wolff
2011-10-31 15:01:41 UTC
Permalink
Post by DuboisP
ça vaut ce que ça vaut, y'a probablement mieux, je ne suis pas
spécialiste du PHP
Avant mieux, il y a correct :p
Post by DuboisP
<?php
$phpmaxfilesize = ini_get('upload_max_filesize');
$sitemaxfilesize = 2097152;
/* non utilisé ici */
Alors pourquoi encombrer l'exemple avec du code qui va faire couiner
PHP ? (les E_NOTICE dues aux clés mal spécifiées)
Post by DuboisP
$uploaderror=array(UPLOAD_ERR_OK=>'Chargement correct',
[snip]
Post by DuboisP
);
/* http://www.iana.org/assignments/media-types/ */
$applicationtype=array('application/justbecause0canbefaulty',
Ça correspond à quoi ça ?

[snip]
Post by DuboisP
'image/gif',
'image/jpeg',
'image/png',
[snip]
Post by DuboisP
);
$document = $_FILES['filetoupload']['name'];
$taille = $_FILES['filetoupload']['size'];
$tmp = $_FILES['filetoupload']['tmp_name'];
$type = $_FILES['filetoupload']['type'];
$ferror = $_FILES['filetoupload']['error'];
if (!empty($document) && (!array_search($type, $applicationtype) ||
($taille > $sitemaxfilesize)))
Plein de parenthèses inutiles.
Ton code ne s'assure pas que le fichier est bien du type que le
navigateur l'a affirmé (ce que PHP donne dans
$_FILES['filetoupload']['type']).
Post by DuboisP
{
$taille = $taille / 1024;
echo "<p class=\"erreur\">Erreur : Votre fichier ".$document." de taille
".$taille." ko, de type ".$type." est trop gros ou de type non
autorisé.</p>\n";
Gros trou de sécurité (XSS).
Post by DuboisP
$erreur="1";
}
Bref, au moins ça t'aura permis de corriger ton code, que de donner
de mauvais conseils ;)
DuboisP
2011-10-31 16:10:09 UTC
Permalink
Le Mon, 31 Oct 2011 16:01:41 +0100, Mickaël Wolff
Post by Mickaël Wolff
Post by DuboisP
ça vaut ce que ça vaut, y'a probablement mieux, je ne suis pas
spécialiste du PHP
Avant mieux, il y a correct :p
Post by DuboisP
<?php
$phpmaxfilesize = ini_get('upload_max_filesize');
$sitemaxfilesize = 2097152;
/* non utilisé ici */
Alors pourquoi encombrer l'exemple avec du code qui va faire couiner
PHP ? (les E_NOTICE dues aux clés mal spécifiées)
parcer que c'est du copier-coller d'un include, et donc je spécifie que ça
n'a pas d'utilité ICI, pour éviter au questionneur de chercher à quoi ça
sert
Post by Mickaël Wolff
Post by DuboisP
$uploaderror=array(UPLOAD_ERR_OK=>'Chargement correct',
[snip]
Post by DuboisP
);
/* http://www.iana.org/assignments/media-types/ */
$applicationtype=array('application/justbecause0canbefaulty',
Ça correspond à quoi ça ?
[snip]
Post by DuboisP
'image/gif',
'image/jpeg',
'image/png',
[snip]
Post by DuboisP
);
$document = $_FILES['filetoupload']['name'];
$taille = $_FILES['filetoupload']['size'];
$tmp = $_FILES['filetoupload']['tmp_name'];
$type = $_FILES['filetoupload']['type'];
$ferror = $_FILES['filetoupload']['error'];
if (!empty($document) && (!array_search($type, $applicationtype) ||
($taille > $sitemaxfilesize)))
Plein de parenthèses inutiles.
Ton code ne s'assure pas que le fichier est bien du type que le
navigateur l'a affirmé (ce que PHP donne dans
$_FILES['filetoupload']['type']).
Post by DuboisP
{
$taille = $taille / 1024;
echo "<p class=\"erreur\">Erreur : Votre fichier ".$document." de taille
".$taille." ko, de type ".$type." est trop gros ou de type non
autorisé.</p>\n";
Gros trou de sécurité (XSS).
Post by DuboisP
$erreur="1";
}
Bref, au moins ça t'aura permis de corriger ton code, que de donner
de mauvais conseils ;)
non, ça m'a permis de constater qu'il y a éventuellement des erreurs, mais
tu ne donnes aucune piste de correction, ni en quoi ce sont des erreurs.
je vois des critiques, mais aucune piste d'amélioration

pour le petit site dont je m'occupe, mon code, bien que non parfait, a
l'avantage d'être fonctionnel.
--
Utilisant le client e-mail révolutionnaire d'Opera :
http://www.opera.com/mail/
Mickaël Wolff
2011-10-31 17:28:38 UTC
Permalink
Post by DuboisP
parcer que c'est du copier-coller d'un include, et donc je spécifie que
ça n'a pas d'utilité ICI, pour éviter au questionneur de chercher à quoi
ça sert
Ben il faut virer ce qui est inutile. Et le copier-coller de ce qu'on
ne comprend pas, c'est la porte ouverte à tout les vilains qui ont
besoin de points d'attaque.
Post by DuboisP
non, ça m'a permis de constater qu'il y a éventuellement des erreurs,
Ce n'est n'est pas potentiel : il y a d'énormes trous de sécurité qui
rendent le site qui l'utilise vulnérable à toutes les attaques connues.
Post by DuboisP
mais tu ne donnes aucune piste de correction, ni en quoi ce sont des
erreurs.
Bien sûr que j'ai donné des pistes : XSS. La littérature est très
volubile à ce sujet.
Post by DuboisP
pour le petit site dont je m'occupe, mon code, bien que non parfait, a
l'avantage d'être fonctionnel.
Oui, surtout pour les pirates.
DuboisP
2011-10-31 17:46:29 UTC
Permalink
Le Mon, 31 Oct 2011 18:28:38 +0100, Mickaël Wolff
Post by Mickaël Wolff
Post by DuboisP
parcer que c'est du copier-coller d'un include, et donc je spécifie que
ça n'a pas d'utilité ICI, pour éviter au questionneur de chercher à quoi
ça sert
Ben il faut virer ce qui est inutile. Et le copier-coller de ce qu'on
ne comprend pas, c'est la porte ouverte à tout les vilains qui ont
besoin de points d'attaque.
Post by DuboisP
non, ça m'a permis de constater qu'il y a éventuellement des erreurs,
Ce n'est n'est pas potentiel : il y a d'énormes trous de sécurité qui
rendent le site qui l'utilise vulnérable à toutes les attaques connues.
Post by DuboisP
mais tu ne donnes aucune piste de correction, ni en quoi ce sont des
erreurs.
Bien sûr que j'ai donné des pistes : XSS. La littérature est très
volubile à ce sujet.
Post by DuboisP
pour le petit site dont je m'occupe, mon code, bien que non parfait, a
l'avantage d'être fonctionnel.
Oui, surtout pour les pirates.
et en te rajoutant ça dans le copier-coller, tu es plus heureux ?

$document=strip_tags(document);
$document=stripslashes($document);
$document=mysql_real_escape_string($document);
--
Utilisant le client e-mail révolutionnaire d'Opera :
http://www.opera.com/mail/
Mickaël Wolff
2011-10-31 19:09:36 UTC
Permalink
Post by DuboisP
et en te rajoutant ça dans le copier-coller, tu es plus heureux ?
$document=strip_tags(document);
$document=stripslashes($document);
$document=mysql_real_escape_string($document);
Non, c'est encore pire.
Le filtrage des données en amont est, à mon avis, une mauvaise
politique. Il faut adapter les données lors de leur usage (pas testé,
fait de tête) :

<?php

function mysql_query_format(mysqli $dbcon, $format/*, $args*/)
{
$args = func_get_args() ;
unset($args['dbcon']) ;
unset($args['format']) ;

$escaped = array() ;
foreach($args as $arg)
{
$escaped[] = $dbcon->real_escape_string($arg) ;
}

return call_user_func_array('sprintf', array_merge(array($format),
$escaped));
}

function html_escape_text($content, $encoding = 'utf-8')
{
return htmlentities($content, ENT_NOQUOTES, $encoding) ;
}

function html_escape_attribute($content, $delim = '\'', $encoding = 'utf-8')
{
if($delim === '\'')
$opt = ENT_QUOTES ;
elseif($delim === '"')
$opt = ENT_COMPAT ;
else
throw new Exception('Attribute delimiter is not recognized') ;

return htmlentities($content, ENT_NOQUOTES, $encoding) ;
}

C'est le genre de fonctions qu'il faut écrire et utiliser quand on
créé des requêtes SQL, et qu'on intègre du texte à l'HTML.
Pascale
2011-10-31 16:10:51 UTC
Permalink
Post by DuboisP
ça vaut ce que ça vaut, y'a probablement mieux, je ne suis pas
spécialiste du PHP [...]
Merci pour ta réponse... tout ça est bien compliqué pour ma petite
cervelle, je vais voir ce que je peux en tirer.

Mais je n'ai pas fini de m'arracher les cheveux : le même programme avec
les mêmes tests derrière ne fonctionne pas pareil chez mon hébergeur actuel
et chez mon futur hébergeur canadien. Je m'explique :

J'ai pour l'instant une limite de taille d'image à 50 Ko, telle que définie
dans mon MAX_FILE_SIZE mentionné précédemment. Et bien, sur chez le nouvel
hébergeur (que je commence à regretter d'avoir choisi, le support est
catastrophiquement absent), pour qu'une photo passe, il faut qu'elle soit
nettement plus petite que 50 Ko : je ne sais pas exactement où se trouve la
limite, mais par exemple, une photo de 49,5 Ko passera sur le site actuel,
par contre, elle ne passera pas chez le nouvel hébergeur ! Je n'ai fait
aucune modification dans les programmes.
Au s'cours, si quelqu'un pouvait me sortir de cette histoire de fous...
--
Pascale
http://www.la-grille-verte.net
DuboisP
2011-10-31 16:14:37 UTC
Permalink
Le Mon, 31 Oct 2011 17:10:51 +0100, Pascale
Post by Pascale
Post by DuboisP
ça vaut ce que ça vaut, y'a probablement mieux, je ne suis pas
spécialiste du PHP [...]
Merci pour ta réponse... tout ça est bien compliqué pour ma petite
cervelle, je vais voir ce que je peux en tirer.
Mais je n'ai pas fini de m'arracher les cheveux : le même programme avec
les mêmes tests derrière ne fonctionne pas pareil chez mon hébergeur actuel
J'ai pour l'instant une limite de taille d'image à 50 Ko, telle que définie
dans mon MAX_FILE_SIZE mentionné précédemment. Et bien, sur chez le nouvel
hébergeur (que je commence à regretter d'avoir choisi, le support est
catastrophiquement absent), pour qu'une photo passe, il faut qu'elle soit
nettement plus petite que 50 Ko : je ne sais pas exactement où se trouve
la
limite, mais par exemple, une photo de 49,5 Ko passera sur le site actuel,
par contre, elle ne passera pas chez le nouvel hébergeur ! Je n'ai fait
aucune modification dans les programmes.
Au s'cours, si quelqu'un pouvait me sortir de cette histoire de fous...
parce qu'il y a 2 limites
celles de ton hébergeur, et les tiennes

$phpmaxfilesize = ini_get('upload_max_filesize');

normalement, ça donne celles de ton hébergeur
sinon, phpmyadmin() doit te donner les valeurs
--
Utilisant le client e-mail révolutionnaire d'Opera :
http://www.opera.com/mail/
Mickaël Wolff
2011-10-31 14:54:21 UTC
Permalink
Post by Pascale
Dans un formulaire qui permet d'uploader du texte et des images, j'utilise
(depuis fort longtemps)<input type="hidden" name="MAX_FILE_SIZE"
value="50000">.
À quoi te sert ce champ ?
Post by Pascale
Ensuite, du côté PHP, je fais un certain nombre de contrôles pour m'assurer
$contenu1=getimagesize($_FILES['photo1']['tmp_name']);
$type1=$contenu1[2];
if ($type1!=2) { echo 'Erreur...';}
Si le fichier téléchargé est trop lourd, getimagesize me renvoie une
erreur.
J'ai conscience que ce n'est pas très propre comme solution et que je
devrais spécifiquement vérifier la taille du fichier que la personne a
tenté de télécharger, d'autant que c'est l'erreur la plus courante commise
par les utilisateurs.
Dans l'absolu, tu vas quand même utiliser getimagesize pour t'assurer
que le fichier est une image, donc ce n'est pas choquant comme usage.
Post by Pascale
Le mieux est-il de vérifier tout bêtement la taille du fichier dans
$_FILES['photo1']['size'] ou vaut-il mieux vérifier le contenu de
$_FILES['photo1']['error'] ? Ou bien ?...
La taille spécifiée dans $_FILES est celle donnée par le navigateur,
ce n'est donc pas une information fiable.
Pascale
2011-10-31 16:42:45 UTC
Permalink
Post by Mickaël Wolff
Dans l'absolu, tu vas quand même utiliser getimagesize pour t'assurer
que le fichier est une image, donc ce n'est pas choquant comme usage.
Oui, mais mon idée était de différencier le cas où le fichier est trop gros
et le cas où le fichier n'est pas un vrai jpg, histoire d'avoir un message
d'erreur plus « parlant ».
Post by Mickaël Wolff
La taille spécifiée dans $_FILES est celle donnée par le navigateur,
ce n'est donc pas une information fiable.
Je comprends. Par contre aurais-tu une idée pour cette histoire de taille
de fichier qui commence à me faire tourner en bourrique ? Mêmes programmes,
mêmes tests, même limite de taille de fichier chez Planet-Work (mon
hébergeur actuel) et PlanetHoster (le futur hébergeur de la-grille-verte),
et une photo qui passe chez Planet-Work ne passe pas chez PlanetHoster, il
faut que je la réduise un peu plus... grmbl.
--
Pascale
http://www.la-grille-verte.net
Mickaël Wolff
2011-10-31 17:22:48 UTC
Permalink
Post by Pascale
Oui, mais mon idée était de différencier le cas où le fichier est trop gros
et le cas où le fichier n'est pas un vrai jpg, histoire d'avoir un message
d'erreur plus « parlant ».
Ok. Dans ce cas, il suffit de demander à l'OS la taille du fichier ;)

Quelque chose dans ce goût là :
filesize($_FILES['xxx']['tmp_namehéhé']);
Post by Pascale
Je comprends. Par contre aurais-tu une idée pour cette histoire de taille
de fichier qui commence à me faire tourner en bourrique ? Mêmes programmes,
mêmes tests, même limite de taille de fichier chez Planet-Work (mon
hébergeur actuel) et PlanetHoster (le futur hébergeur de la-grille-verte),
et une photo qui passe chez Planet-Work ne passe pas chez PlanetHoster, il
faut que je la réduise un peu plus... grmbl.
Comme l'a proposé DuboisP, tu devrais regarder le paramétrage de ton
hébergeur. Ceci dit, je serais plus violent : mauvais hébergeur, changer
hébergeur ;)
Pascale
2011-10-31 19:17:05 UTC
Permalink
Post by Mickaël Wolff
Ok. Dans ce cas, il suffit de demander à l'OS la taille du fichier ;)
filesize($_FILES['xxx']['tmp_namehéhé']);
Ah ah, je ne connaissais même pas cette fonction ! Ça donne un résultat
différent de $_FILES['photo1']['size'] ?
Post by Mickaël Wolff
Comme l'a proposé DuboisP, tu devrais regarder le paramétrage de
ton hébergeur.
Je viens de regarder : la limite est à 64 M (octets ? bytes ?...) et moi je
me limite à 50 Ko (l'objectif du changement d'hébergeur étant justement
d'augmenter la taille autorisée des photos, vu que 50 Ko, ça fait vraiment
pas lourd).
Post by Mickaël Wolff
Ceci dit, je serais plus violent : mauvais hébergeur,
changer hébergeur ;)
Le problème, c'est que je viens juste de payer pour un an...
--
Pascale
http://www.la-grille-verte.net
Pascale
2011-10-31 19:39:48 UTC
Permalink
La commande filesize m'a permis d'y voir plus clair : en fait, si j'en
crois ce qu'elle me dit, c'est mon hébergeur actuel qui est trop
« laxiste » : une photo qui apparaît comme faisant 50 Ko fait en réalité
50664 octets (c'est un exemple).
Donc je ne peux pas franchement râler auprès de mon nouvel hébergeur... (:
Par contre, ce qui m'étonne, c'est qu'en cas de dépassement de la taille
maxi (quel que soit l'hébergeur), filesize($_FILES['photo1']['tmp_name'])
renvoie un beau rien tout neuf, ce qui ne m'aide donc pas pour indiquer à
mes utilisateurs que passé les bornes y a p'us d'limites...
--
Pascale
http://www.la-grille-verte.net
DuboisP
2011-10-31 19:41:54 UTC
Permalink
Le Mon, 31 Oct 2011 20:39:48 +0100, Pascale
La commande filesize m'a permis d'y voir plus clair : en fait, si j'en
crois ce qu'elle me dit, c'est mon hébergeur actuel qui est trop
« laxiste » : une photo qui apparaît comme faisant 50 Ko fait en réalité
50664 octets (c'est un exemple).
Par contre, ce qui m'étonne, c'est qu'en cas de dépassement de la taille
maxi (quel que soit l'hébergeur), filesize($_FILES['photo1']['tmp_name'])
renvoie un beau rien tout neuf, ce qui ne m'aide donc pas pour indiquer à
mes utilisateurs que passé les bornes y a p'us d'limites...
c'est normal
le ko informatique, c'est 1024
donc, 50 ko, ce sont 51200 octets
--
Utilisant le client e-mail révolutionnaire d'Opera :
http://www.opera.com/mail/
Pascale
2011-10-31 19:56:00 UTC
Permalink
Post by DuboisP
c'est normal
le ko informatique, c'est 1024
donc, 50 ko, ce sont 51200 octets
Rhâââ... j'aurais dû y penser. Il n'empêche que ça reste un mystère, cette
différence de fonctionnement entre 2 hébergeurs, vu que le Ko sont censés
peser pareil partout...

Chez mon hébergeur actuel (celui qui est laxiste, si on peut dire), c'est :
PHP Version 5.2.6-1+lenny13
System Linux celia 3.0.4-grsec-em64t #0 SMP Tue Sep 6 23:04:09 CEST
2011 x86_64

Chez le nouvel hébergeur, c'est :

PHP Version 5.2.17
System Linux edain.planethoster.net 2.6.18-338.12.1.el5.lve0.8.34 #1
SMP Tue Jun 7 16:46:50 EEST 2011 x86_64

Y a-t-il un paramètre bien planqué quelque part qui justifierait cette
différence de traitement ?
--
Pascale
http://www.la-grille-verte.net
Continuer la lecture sur narkive:
Loading...