1. Trang chủ
  2. » Công Nghệ Thông Tin

PHP and MySQL Web Development - P75 ppsx

5 228 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 5
Dung lượng 115,82 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

342 Chapter 16 Interacting with the File System and the Serverif !move_uploaded_file$userfile, $upfile { echo 'Problem: Could not move file to destination directory'; exit; } } else { ec

Trang 1

342 Chapter 16 Interacting with the File System and the Server

if (!move_uploaded_file($userfile, $upfile)) {

echo 'Problem: Could not move file to destination directory'; exit;

} } else { echo 'Problem: Possible file upload attack Filename: '.$userfile_name; exit;

}

// older versions code as recommended in PHP manual /*

function is_uploaded_file($filename) {

if (!$tmp_file = get_cfg_var('upload_tmp_dir')) {

$tmp_file = dirname(tempnam('', ''));

}

$tmp_file = '/' basename($filename);

// User might have trailing slash in php.ini

return (ereg_replace('/+', '/', $tmp_file) == $filename);

}

if (is_uploaded_file($userfile)) {

copy($userfile, $upfile);

} else { echo 'Problem: Possible file upload attack Filename: '.$userfile_name'; }

*/

// end older version

echo 'File uploaded successfully<br /><br />';

// reformat the file contents

$fp = fopen($upfile, 'r');

$contents = fread ($fp, filesize ($upfile));

fclose ($fp);

$contents = strip_tags($contents);

$fp = fopen($upfile, 'w');

fwrite($fp, $contents);

fclose($fp);

Listing 16.2 Continued

Trang 2

// show what was uploaded echo 'Preview of uploaded file contents:<br /><hr />';

echo $contents;

echo '<br /><hr />';

?>

</body>

</html>

Interestingly enough, most of this script is error checking File upload involves potential security risks, and we need to mitigate these where possible.We need to validate the uploaded file as carefully as possible to make sure it is safe to echo to our visitors

Let’s go through the main parts of the script

We begin by checking the error code returned in $HTTP_POST_FILES ['userfile']['error'].This error code was introduced at PHP 4.2.0 From PHP 4.3 there is also a constant associated with each of the codes.The possible constants and val-ues are as follows:

n UPLOAD_ERROR_OK, value 0, means no error occurred

n UPLOAD_ERR_INI_SIZE, value 1, means that the size of the uploaded file exceeds the maximum value specified in your php.ini file with the upload_max_

filesizedirective

n UPLOAD_ERR_FORM_SIZE, value 2, means that the size of the uploaded file exceeds the maximum value specified in the HTML form in the MAX_FILE_SIZEelement

n UPLOAD_ERR_PARTIAL, value 3, means that the file was only partially uploaded

n UPLOAD_ERR_NO_FILE, value 4, means that no file was uploaded

If you are using an older version of PHP, you can perform a manual version of some of these checks as follows You can check whether $userfileis "none".This is the value set by PHP if no file was uploaded.We also test that the file has some content (by testing that $userfile_sizeis greater than 0)

Finally, regardless of version, in this case we have decided that we only want text files

to be uploaded so we test the MIME type by testing $userfile_type)

We then check that the file we are trying to open has actually been uploaded and is not a local file such as /etc/passwd.We’ll come back to this in a moment

If that all works out okay, we then copy the file into our include directory.We use /uploads/in this example—it’s outside the Web document tree, and therefore a good place to put files that are to be included elsewhere

We then open up the file, clean out any stray HTML or PHP tags that might be in the file using the strip_tags()function, and write the file back

Finally we display the contents of the file so the user can see that their file uploaded successfully

Listing 16.2 Continued

Trang 3

344 Chapter 16 Interacting with the File System and the Server

The results of one (successful) run of this script are shown in Figure 16.2

Figure 16.2 After the file is copied and reformatted, the uploaded file is dis-played as confirmation to the user that the upload was successful.

In September 2000, an exploit was announced that could allow a cracker to fool your file upload script into processing a local file as if it had been uploaded.This exploit was documented on the BUGTRAQ mailing list.You can read the official security advisory

at one of the many BUGTRAQ archives, such as http://lists.insecure.org/ bugtraq/2000/Sep/0237.html

We have used the is_uploaded_file()and move_uploaded_file()functions to make sure that the file we are processing has actually been uploaded and is not a local file such as /etc/passwd.This function is available from PHP version 4.0.3 onward If you are using an older version of PHP, we have again provided some sample code with equivalent functionality (commented out)

Unless you write your upload handling script carefully, a malicious visitor could pro-vide his own temporary filename and convince your script to handle that file as though

it were the uploaded file As many file upload scripts echo the uploaded data back to the user, or store it somewhere that it can be loaded, this could lead to people being able to access any file that the Web server can read.This could include sensitive files such as /etc/passwdand PHP source code including your database passwords

Common Problems

There are a few things to keep in mind when performing file uploads

n The previous example assumes that users have been authenticated elsewhere.You shouldn’t allow just anybody to upload files on to your site

n If you are allowing untrusted or unauthenticated users to upload files, it’s a good idea to be pretty paranoid about the contents of them.The last thing you want is a malicious script being uploaded and run.You should be careful, not just of the type and contents of the file as we are here, but of the filename itself It’s a pretty good idea to rename uploaded files to something you know to be “safe”

Trang 4

n If you are using a Windows-based machine, be sure to use \\or /instead of \in file paths as per usual

n If you are having problems getting this to work, check out your php.inifile.You will need to have set the upload_tmp_dirdirective to point to some directory that you have access to.You might also need to adjust the memory_limitdirective

if you want to upload large files—this will determine the maximum file size in bytes that you can upload

n If PHP is running in safe mode, you will get an error message about being unable

to access the temporary file.This can only be fixed either by not running in safe mode or by writing a non-PHP script that copies the file to an accessible location

You can then execute this script from your PHP script.We’ll look at how to exe-cute programs on the server from PHP toward the end of this chapter

Using Directory Functions

After the users have uploaded some files, it will be useful for them to be able to see what’s been uploaded and manipulate the content files

PHP has a set of directory and file system functions that are useful for this purpose

Reading from Directories

First, we’ll implement a script to allow directory browsing of the uploaded content

Browsing directories is actually very straightforward in PHP In Listing 16.3, we show a simple script that can be used for this purpose

Listing 16.3 browsedir.php—A Directory Listing of the Uploaded Files

<html>

<head>

<title>Browse Directories</title>

</head>

<body>

<h1>Browsing</h1>

<?php

$current_dir = '/uploads/';

$dir = opendir($current_dir);

echo "Upload directory is $current_dir<br />";

echo 'Directory Listing:<br /><hr /><br />';

while ($file = readdir($dir)) {

echo "$file<br />";

} echo '<hr /><br />';

Trang 5

346 Chapter 16 Interacting with the File System and the Server

closedir($dir);

?>

</body>

</html>

This script makes use of the opendir(),closedir(), and readdir()functions

The function opendir()is used to open a directory for reading Its use is very similar

to the use of fopen()for reading from files Instead of passing it a filename, you should pass it a directory name:

$dir = opendir($current_dir);

The function returns a directory handle, again in much the same way as fopen()returns

a file handle

When the directory is open, you can read a filename from it by calling readdir($dir) , as shown in the example.This returns false when there are no more files to be read (Note that it will also return false if it reads a file called "0"—you could,

of course, test for this if it is likely to occur.) Files aren’t sorted in any particular order, so

if you require a sorted list, you should read them into an array and sort that

When you are finished reading from a directory, you call closedir($dir)to finish This is again similar to calling fclose()for a file

Sample output of the directory browsing script is shown in Figure 16.3

Listing 16.3 Continued

Figure 16.3 The directory listing shows all the files in the chosen directory, including the (the current directory) and (one level up) directories.You can choose to filter these out.

If you are making directory browsing available via this mechanism, it is sensible to limit the directories that can be browsed so that a user cannot browse directory listings in areas not normally available to him

Ngày đăng: 07/07/2014, 03:20