mirror of
https://github.com/sigmasternchen/php-doc-en
synced 2025-03-16 00:48:54 +00:00
Promote track vars instead of globals.
Added more pitfalls. git-svn-id: https://svn.php.net/repository/phpdoc/en/trunk@68908 c90b9560-bf6c-de11-be94-00142212c4b1
This commit is contained in:
parent
6dd2d6e638
commit
3f13a76bf0
1 changed files with 97 additions and 66 deletions
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!-- $Revision: 1.28 $ -->
|
||||
<!-- $Revision: 1.29 $ -->
|
||||
<chapter id="features.file-upload">
|
||||
<title>Handling file uploads</title>
|
||||
|
||||
|
@ -50,62 +50,35 @@ Send this file: <input name="userfile" type="file">
|
|||
</para>
|
||||
|
||||
<para>
|
||||
In PHP, the following variables will be defined within the
|
||||
destination script upon a successful upload, assuming that <link
|
||||
linkend="ini.register-globals">register_globals</link> is turned
|
||||
on in <filename>php.ini</filename>. If <link
|
||||
linkend="ini.track-vars">track_vars</link> is turned on, they will
|
||||
also be available in PHP within the global array
|
||||
<varname>$HTTP_POST_VARS</varname>. Note that the following
|
||||
variable names assume the use of the file upload name 'userfile',
|
||||
as used in the example above:
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<simpara>
|
||||
<varname>$userfile</varname> - The temporary filename in which
|
||||
the uploaded file was stored on the server machine.
|
||||
</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara>
|
||||
<varname>$userfile_name</varname> - The original name or path
|
||||
of the file on the sender's system.
|
||||
</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara>
|
||||
<varname>$userfile_size</varname> - The size of the uploaded
|
||||
file in bytes.
|
||||
</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara>
|
||||
<varname>$userfile_type</varname> - The mime type of the file
|
||||
if the browser provided this information. An example would be
|
||||
"image/gif".
|
||||
</simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
Note that the "$userfile" part of the above variables is
|
||||
whatever the name of the INPUT field of TYPE=file is in the upload
|
||||
form. In the above upload form example, we chose to call it
|
||||
"userfile"
|
||||
Variables defined for uploaded files differs depends on PHP
|
||||
version and configuration. Following variables will be defined
|
||||
within the destination script upon a successful upload. When <link
|
||||
linkend="ini.track-vars">track_vars</link> is enabled,
|
||||
$HTTP_POST_FILES/ $_FILES array is initialized. <link
|
||||
linkend="ini.track-vars">track_vars</link> is always on from PHP
|
||||
4.0.3. Finally, related variables may be initialized as globals
|
||||
when <link linkend="ini.register-globals">register_globals</link>
|
||||
is turned on . However, use of globals is not recommended anymore.
|
||||
</para>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
<link linkend="ini.track-vars">track_vars</link> is always on
|
||||
from PHP 4.0.3. From PHP 4.1.0 or later, $_FILES may be used
|
||||
instead of
|
||||
<varname>$HTTP_POST_FILES</varname>. <varname>$_FILES</varname> is
|
||||
always global, so <literal>global</literal> is should not be used
|
||||
for $_FILES in function scope.
|
||||
</para>
|
||||
</note>
|
||||
<para>
|
||||
In PHP 4, the behaviour is slightly different, in that the new
|
||||
global array <varname>$HTTP_POST_FILES</varname> is provided to
|
||||
contain the uploaded file information. This is still only
|
||||
available if <link linkend="ini.track-vars">track_vars</link> is
|
||||
turned on, but <link linkend="ini.track-vars">track_vars</link> is
|
||||
always turned on in versions of PHP after PHP 4.0.2.
|
||||
<varname>$HTTP_POST_FILES</varname>/<varname>$_FILES</varname> is
|
||||
provided to contain the uploaded file information.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The contents of <varname>$HTTP_POST_FILES</varname> are as
|
||||
follows. Note that this assumes the use of the file upload name
|
||||
'userfile', as used in the example above:
|
||||
'userfile', as used in the example script above:
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><varname>$HTTP_POST_FILES['userfile']['name']</varname></term>
|
||||
|
@ -144,6 +117,50 @@ Send this file: <input name="userfile" type="file">
|
|||
</varlistentry>
|
||||
</variablelist>
|
||||
</para>
|
||||
<note>
|
||||
<para>
|
||||
PHP3 does not support $HTTP_POST_FILES.
|
||||
</para>
|
||||
</note>
|
||||
|
||||
<para>
|
||||
When <link linkend="ini.register-globals">register_globals</link>
|
||||
is turned on in <filename>php.ini</filename>. Note that the
|
||||
following variable names assume the use of the file upload name
|
||||
'userfile', as used in the example script above:
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<simpara>
|
||||
<varname>$userfile</varname> - The temporary filename in which
|
||||
the uploaded file was stored on the server machine.
|
||||
</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara>
|
||||
<varname>$userfile_name</varname> - The original name or path
|
||||
of the file on the sender's system.
|
||||
</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara>
|
||||
<varname>$userfile_size</varname> - The size of the uploaded
|
||||
file in bytes.
|
||||
</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara>
|
||||
<varname>$userfile_type</varname> - The mime type of the file
|
||||
if the browser provided this information. An example would be
|
||||
"image/gif".
|
||||
</simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
Note that the "$userfile" part of the above variables is
|
||||
whatever the name of the INPUT field of TYPE=file is in the upload
|
||||
form. In the above upload form example, we chose to call it
|
||||
"userfile"
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Files will by default be stored in the server's default temporary
|
||||
|
@ -167,13 +184,14 @@ Send this file: <input name="userfile" type="file">
|
|||
<programlisting role="php">
|
||||
<![CDATA[
|
||||
<?php
|
||||
if (is_uploaded_file($userfile)) {
|
||||
copy($userfile, "/place/to/put/uploaded/file");
|
||||
// PHP 4.1.0 or later, $_FILES may be usedd instead of $HTTP_POST_FILES
|
||||
if (is_uploaded_file($HTTP_POST_FILES['userfile'])) {
|
||||
copy($HTTP_POST_FILES['userfile'], "/place/to/put/uploaded/file");
|
||||
} else {
|
||||
echo "Possible file upload attack: filename '$userfile'.";
|
||||
echo "Possible file upload attack: filename '".$HTTP_POST_FILES['userfile'".".";
|
||||
}
|
||||
/* ...or... */
|
||||
move_uploaded_file($userfile, "/place/to/put/uploaded/file");
|
||||
move_uploaded_file($HTTP_POST_FILES['userfile'], "/place/to/put/uploaded/file");
|
||||
?>
|
||||
]]>
|
||||
</programlisting>
|
||||
|
@ -191,20 +209,21 @@ move_uploaded_file($userfile, "/place/to/put/uploaded/file");
|
|||
<programlisting role="php">
|
||||
<![CDATA[
|
||||
<?php
|
||||
// PHP 4.1.0 or later, $_FILES may be usedd instead of $HTTP_POST_FILES
|
||||
/* Userland test for uploaded file. */
|
||||
function is_uploaded_file($filename) {
|
||||
function is_uploaded_file($HTTP_POST_FILES['filename']) {
|
||||
if (!$tmp_file = get_cfg_var('upload_tmp_dir')) {
|
||||
$tmp_file = dirname(tempnam('', ''));
|
||||
}
|
||||
$tmp_file .= '/' . basename($filename);
|
||||
$tmp_file .= '/' . basename($HTTP_POST_FILES['filename']);
|
||||
/* User might have trailing slash in php.ini... */
|
||||
return (ereg_replace('/+', '/', $tmp_file) == $filename);
|
||||
return (ereg_replace('/+', '/', $tmp_file) == $HTTP_POST_FILES['filename']);
|
||||
}
|
||||
|
||||
if (is_uploaded_file($userfile)) {
|
||||
copy($userfile, "/place/to/put/uploaded/file");
|
||||
if (is_uploaded_file($HTTP_POST_FILES['userfile'])) {
|
||||
copy($HTTP_POST_FILES['userfile'], "/place/to/put/uploaded/file");
|
||||
} else {
|
||||
echo "Possible file upload attack: filename '$userfile'.";
|
||||
echo "Possible file upload attack: filename '".$HTTP_POST_FILES['userfile']".".";
|
||||
}
|
||||
?>
|
||||
]]>
|
||||
|
@ -215,12 +234,12 @@ if (is_uploaded_file($userfile)) {
|
|||
The PHP script which receives the uploaded file should implement
|
||||
whatever logic is necessary for determining what should be done
|
||||
with the uploaded file. You can for example use the
|
||||
<varname>$file_size</varname> variable to throw away any files
|
||||
that are either too small or too big. You could use the
|
||||
<varname>$file_type</varname> variable to throw away any files
|
||||
that didn't match a certain type criteria. Whatever the logic,
|
||||
you should either delete the file from the temporary directory or
|
||||
move it elsewhere.
|
||||
<varname>$HTTP_POST_FILES['file_size']</varname> variable to throw
|
||||
away any files that are either too small or too big. You could
|
||||
use the <varname>$HTTP_POST_FILES['file_type']</varname> variable
|
||||
to throw away any files that didn't match a certain type criteria.
|
||||
Whatever the logic, you should either delete the file from the
|
||||
temporary directory or move it elsewhere.
|
||||
</simpara>
|
||||
<simpara>
|
||||
The file will be deleted from the temporary directory at the end
|
||||
|
@ -236,6 +255,18 @@ if (is_uploaded_file($userfile)) {
|
|||
linkend="ini.upload-max-filesize">upload_max_filesize</link> ini-setting.
|
||||
The default is 2 Megabytes.
|
||||
</simpara>
|
||||
<simpara>
|
||||
If memory limit is enabled, larger <link
|
||||
linkend="ini.memory-limit">memory_limit</link> may be needed. Make
|
||||
sure to set <link linkend="ini.memory-limit">memory_limit</link>
|
||||
large enough.
|
||||
</simpara>
|
||||
<!-- FIXME: max_execution_time INI -->
|
||||
<simpara>
|
||||
If <literal>max_execution_time</literal> is set too small, script
|
||||
execution may be exceeded the value. Make sure to set
|
||||
<literal>max_execution_time</literal> large enough.
|
||||
</simpara>
|
||||
<simpara>
|
||||
Not validating which file you operate on may mean that users can access
|
||||
sensitive information in other directories.
|
||||
|
|
Loading…
Reference in a new issue