mirror of
https://github.com/macintoshplus/doc-en.git
synced 2026-03-24 00:42:18 +01:00
filesystem.xml: amend file style, add the tags (#3569)
* filesystem.xml: amend file style, add the tags * filesystem.xml: fix tag mismatching * Update security/filesystem.xml Remove redundant dots after 'etc' Co-authored-by: Gina Peter Banyard <girgias@php.net> * Update security/filesystem.xml nits Co-authored-by: Gina Peter Banyard <girgias@php.net> --------- Co-authored-by: Gina Peter Banyard <girgias@php.net>
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
<simpara>
|
||||
Since <acronym>PHP</acronym> was designed to allow user level access to the filesystem,
|
||||
it's entirely possible to write a <acronym>PHP</acronym> script that will allow you
|
||||
to read system files such as /etc/passwd, modify your ethernet
|
||||
to read system files such as <filename>/etc/passwd</filename>, modify your ethernet
|
||||
connections, send massive printer jobs out, etc. This has some
|
||||
obvious implications, in that you need to ensure that the files
|
||||
that you read from and write to are the appropriate ones.
|
||||
@@ -32,7 +32,8 @@
|
||||
<programlisting role="php">
|
||||
<![CDATA[
|
||||
<?php
|
||||
// remove a file from the user's home directory
|
||||
|
||||
// Remove a file from the user's home directory
|
||||
$username = $_POST['user_submitted_name'];
|
||||
$userfile = $_POST['user_submitted_filename'];
|
||||
$homedir = "/home/$username";
|
||||
@@ -40,6 +41,7 @@ $homedir = "/home/$username";
|
||||
unlink("$homedir/$userfile");
|
||||
|
||||
echo "The file has been deleted!";
|
||||
|
||||
?>
|
||||
]]>
|
||||
</programlisting>
|
||||
@@ -49,13 +51,15 @@ echo "The file has been deleted!";
|
||||
and delete it even if they're not supposed to be allowed to do so.
|
||||
In this case, you'd want to use some other form of authentication.
|
||||
Consider what could happen if the variables submitted were
|
||||
"../etc/" and "passwd". The code would then effectively read:
|
||||
<literal>"../etc/"</literal> and <literal>"passwd"</literal>.
|
||||
The code would then effectively read:
|
||||
<example>
|
||||
<title>... A filesystem attack</title>
|
||||
<programlisting role="php">
|
||||
<![CDATA[
|
||||
<?php
|
||||
// removes a file from anywhere on the hard drive that
|
||||
|
||||
// Removes a file from anywhere on the hard drive that
|
||||
// the PHP user has access to. If PHP has root access:
|
||||
$username = $_POST['user_submitted_name']; // "../etc"
|
||||
$userfile = $_POST['user_submitted_filename']; // "passwd"
|
||||
@@ -64,6 +68,7 @@ $homedir = "/home/$username"; // "/home/../etc"
|
||||
unlink("$homedir/$userfile"); // "/home/../etc/passwd"
|
||||
|
||||
echo "The file has been deleted!";
|
||||
|
||||
?>
|
||||
]]>
|
||||
</programlisting>
|
||||
@@ -88,7 +93,8 @@ echo "The file has been deleted!";
|
||||
<programlisting role="php">
|
||||
<![CDATA[
|
||||
<?php
|
||||
// removes a file from the hard drive that
|
||||
|
||||
// Removes a file from the hard drive that
|
||||
// the PHP user has access to.
|
||||
$username = $_SERVER['REMOTE_USER']; // using an authentication mechanism
|
||||
$userfile = basename($_POST['user_submitted_filename']);
|
||||
@@ -101,6 +107,7 @@ if (file_exists($filepath) && unlink($filepath)) {
|
||||
} else {
|
||||
$logstring = "Failed to delete $filepath\n";
|
||||
}
|
||||
|
||||
$fp = fopen("/home/logging/filedelete.log", "a");
|
||||
fwrite($fp, $logstring);
|
||||
fclose($fp);
|
||||
@@ -113,13 +120,14 @@ echo htmlentities($logstring, ENT_QUOTES);
|
||||
</example>
|
||||
However, even this is not without its flaws. If your authentication
|
||||
system allowed users to create their own user logins, and a user
|
||||
chose the login "../etc/", the system is once again exposed. For
|
||||
chose the login <literal>"../etc/"</literal>, the system is once again exposed. For
|
||||
this reason, you may prefer to write a more customized check:
|
||||
<example>
|
||||
<title>More secure file name checking</title>
|
||||
<programlisting role="php">
|
||||
<![CDATA[
|
||||
<?php
|
||||
|
||||
$username = $_SERVER['REMOTE_USER']; // using an authentication mechanisim
|
||||
$userfile = $_POST['user_submitted_filename'];
|
||||
$homedir = "/home/$username";
|
||||
@@ -130,7 +138,8 @@ if (!ctype_alnum($username) || !preg_match('/^(?:[a-z0-9_-]|\.(?!\.))+$/iD', $us
|
||||
die("Bad username/filename");
|
||||
}
|
||||
|
||||
//etc...
|
||||
// etc.
|
||||
|
||||
?>
|
||||
]]>
|
||||
</programlisting>
|
||||
@@ -138,9 +147,10 @@ if (!ctype_alnum($username) || !preg_match('/^(?:[a-z0-9_-]|\.(?!\.))+$/iD', $us
|
||||
</para>
|
||||
<para>
|
||||
Depending on your operating system, there are a wide variety of files
|
||||
which you should be concerned about, including device entries (/dev/
|
||||
or COM1), configuration files (/etc/ files and the .ini files),
|
||||
well known file storage areas (/home/, My Documents), etc. For this
|
||||
which you should be concerned about, including device entries (<filename>/dev/</filename>
|
||||
or <filename>COM1</filename>), configuration files (<filename>/etc/</filename> files and
|
||||
the <literal>.ini</literal> files), well known file storage areas (<filename>/home/</filename>,
|
||||
<filename>My Documents</filename>), etc. For this
|
||||
reason, it's usually easier to create a policy where you forbid
|
||||
everything except for what you explicitly allow.
|
||||
</para>
|
||||
@@ -159,12 +169,16 @@ if (!ctype_alnum($username) || !preg_match('/^(?:[a-z0-9_-]|\.(?!\.))+$/iD', $us
|
||||
<programlisting role="php">
|
||||
<![CDATA[
|
||||
<?php
|
||||
|
||||
$file = $_GET['file']; // "../../etc/passwd\0"
|
||||
if (file_exists('/home/wwwrun/'.$file.'.php')) {
|
||||
// file_exists will return true as the file /home/wwwrun/../../etc/passwd exists
|
||||
include '/home/wwwrun/'.$file.'.php';
|
||||
// the file /etc/passwd will be included
|
||||
|
||||
if (file_exists('/home/wwwrun/' . $file . '.php')) {
|
||||
// File_exists will return true as the file /home/wwwrun/../../etc/passwd exists
|
||||
include '/home/wwwrun/' . $file . '.php';
|
||||
|
||||
// The file /etc/passwd will be included
|
||||
}
|
||||
|
||||
?>
|
||||
]]>
|
||||
</programlisting>
|
||||
@@ -178,6 +192,7 @@ if (file_exists('/home/wwwrun/'.$file.'.php')) {
|
||||
<programlisting role="php">
|
||||
<![CDATA[
|
||||
<?php
|
||||
|
||||
$file = $_GET['file'];
|
||||
|
||||
// Whitelisting possible values
|
||||
@@ -185,11 +200,12 @@ switch ($file) {
|
||||
case 'main':
|
||||
case 'foo':
|
||||
case 'bar':
|
||||
include '/home/wwwrun/include/'.$file.'.php';
|
||||
include '/home/wwwrun/include/' . $file . '.php';
|
||||
break;
|
||||
default:
|
||||
include '/home/wwwrun/include/main.php';
|
||||
}
|
||||
|
||||
?>
|
||||
]]>
|
||||
</programlisting>
|
||||
|
||||
Reference in New Issue
Block a user