Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 7 of 7
  1. #1
    Supreme Master coder! _Aerospace_Eng_'s Avatar
    Join Date
    Dec 2004
    Location
    In a place far, far away...
    Posts
    19,291
    Thanks
    2
    Thanked 1,043 Times in 1,019 Posts

    PHP File Upload that sends email to person of choice depending on upload directory.

    I recently code this for a user on the forums. Basically its a file upload script that will email a person depending on which directory was chosen. I think I've put in sufficient error checking. Once the file is uploaded successfully it redirects the user to a page and outputs that the file was uploaded to so and so directory. If any one sees any problems with it let me know please. One thing you should know if you use this script is that you should NOT allow it to be viewable to the public because you server could be filled up with junk. This should be used in a members only type area on your site. With that said here is the code. I commented it pretty well so it should be easy to follow. The directories you are uploading to must be chmodded to 777 for this script to work properly.

    uploader.php
    PHP Code:
    <?php
    $error 
    ""// Set a variable that will be used for errors
    $sendTo ""// Set a variable that will be used for emailing
    if(isset($_POST['upload']) && $_POST['upload'] == 'Upload File'// Form is submitted
    {
        
    $whereto $_POST['where']; // Gets post value from select menu
        
    $whatfile $_FILES['uploadedfile']['name']; // Gets file value from file upload input
        
    $subject "File uploaded to "$whereto ." directory"// This is the subject that will appear in the email
        
    $from "Upload form <noreply@yourdomain.com>";
        if(empty(
    $whereto)) // Checks to see if $whereto is empty, if so echo error
        
    {
            
    $error "You need to choose a directory.<br />";
        }
        if(
    $whatfile == NULL// Checks to see if file input field is empty, if so throw an error
        
    {
            
    $error .= "You need to choose a file.";
        }
        if(!empty(
    $whereto) && $whatfile != NULL//if no errors so far then continue uploading
        
    {
            
    $target_path "$whereto/"// The directory the file will be placed
            
            /* Add the original filename to our target path. Result is "uploads/filename.extension" */
            
    $target_path $target_path basename($whatfile);
            if(
    move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path))
            {
                
    header("Location: index.php?to=$whereto"); // Directs user back to page of choice
            
    }
            else
            {
                
    /* if there was a problem then throw an error */
                
    $error .= "There was an error uploading the file, please try again!";
            }
            if(empty(
    $error))
            {
                if(
    $whereto == "uploads1"// Change $sentTo depending on the directory chosen
                
    {
                    
    $sendTo "Jim <jim@yourdomain.com>"// Change this to an email address of your own
                
    }
                if(
    $whereto == "uploads2")
                {
                    
    $sendTo "Kim <kim@yourdomain.com>"// Change this to an email address of your own
                
    }
                
    /* The below will be what is shown in the email */
                
    $body "You have received the following from the web based upload form:\r\n";
                
    $body .= "---------------------------------------------------------------\r\n";
                
    $body .= "Subject:    File uploaded to "$whereto ." directory\r\n";
                
    $body .= "File name:  "$whatfile ."\r\n";
                
    $body .= "Upload directory: "$whereto ."\r\n";
                
    $body .= "Uploader's IP address: "$_SERVER['REMOTE_ADDR'] ."\r\n";
                
    $body .= "---------------------------------------------------------------\r\n";
              
                  
    /* headers used to show from field in email client */
                
    $headers 'From: '.$from."\r\n" .
                    
    'Reply-To: '.$from
                
                
    /* this actually sends the mail */
                
    mail($sendTo$subject$body$headers);
            }
        }
    }
    ?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    <title>File Upload</title>
    </head>

    <body>
    <div>
    <?php
    if(!empty($error))
    {
    echo 
    $error;
    }
    ?>
    </div>
    <form enctype="multipart/form-data" action="<?php echo $_SERVER['SCRIPT_NAME']?>" method="POST">
        <input type="hidden" name="MAX_FILE_SIZE" value="100000" />
        Choose a file to upload: <input name="uploadedfile" type="file" /><br />
        <select name="where">
            <option value="">Choose a directory</option>
            <option value="uploads1">uploads1</option>
            <option value="uploads2">uploads2</option>
        </select>
        <input type="submit" name="upload" value="Upload File" />
    </form>
    </body>
    </html>
    index.php
    PHP Code:
    <?php
    $directory 
    $_GET['to']; // This checks the url getting the value for the to=
    ?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    <title>Index Page</title>
    </head>

    <body>
    <?php
    if(!empty($directory)) // if to=something then echo that the file was uploaded in so and so directory
    {
        echo 
    "Your file has been uploaded to the "$directory ." directory.";
    }
    ?>
    </body>
    </html>
    ||||If you are getting paid to do a job, don't ask for help on it!||||

  • #2
    fci
    fci is offline
    Senior Coder
    Join Date
    Aug 2004
    Location
    Twin Cities
    Posts
    1,345
    Thanks
    0
    Thanked 0 Times in 0 Posts
    I do not recommend the usage of empty() since it allows some ambiguity, if you want to look for an empty string, actually check for it $str=="" (someone could send in an array for $whereto which I believe would allow someone to see errors on the page which could reveal limited information about the server/file/error/blah).
    also, your $whereto does not appear to be properly sanitized which may not make a difference but someone could do some http splitting when you do header(...).

    (note: I haven't had the chance to test these but.. yeah).

  • #3
    Senior Coder Nightfire's Avatar
    Join Date
    Jun 2002
    Posts
    4,265
    Thanks
    6
    Thanked 48 Times in 48 Posts
    ^ Someone as paranoid as me.

    Anything involving file uploading is worth being over paranoid about.

  • #4
    fci
    fci is offline
    Senior Coder
    Join Date
    Aug 2004
    Location
    Twin Cities
    Posts
    1,345
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by Nightfire
    ^ Someone as paranoid as me.

    Anything involving file uploading is worth being over paranoid about.
    mmmm.. the code also isn't using is_uploaded_file()..

    I'd say its preferable to be paranoid all the time.. although I would say it is about being 'security conscious' ..

  • #5
    Regular Coder ralph l mayo's Avatar
    Join Date
    Nov 2005
    Posts
    951
    Thanks
    1
    Thanked 31 Times in 29 Posts
    You use basename but then don't include any restriction on $_POST['where']? So if $_POST['where'] == '/etc' and $_FILES[]['name'] == 'passwd', unless I'm missing something, you better hope all your permissions are secure?

    OTOH, is_uploaded_file is implied by move_uploaded_file, so don't worry about that. I just don't think there's any easy way to sanitize a user supplied directory, I'd rather drop it all in ./upload/ or something and know the area of effect is restricted.

    Also, is this arbitrary file upload ending up somewhere inside document root? So I can upload blah.php == <?php eval($_GET['f']); ?>? If so it can be used to get a remote shell as apache's user and probably to elevate to root by a determined hacker.

  • #6
    Supreme Master coder! _Aerospace_Eng_'s Avatar
    Join Date
    Dec 2004
    Location
    In a place far, far away...
    Posts
    19,291
    Thanks
    2
    Thanked 1,043 Times in 1,019 Posts
    Quote Originally Posted by fci
    I do not recommend the usage of empty() since it allows some ambiguity, if you want to look for an empty string, actually check for it $str=="" (someone could send in an array for $whereto which I believe would allow someone to see errors on the page which could reveal limited information about the server/file/error/blah).
    also, your $whereto does not appear to be properly sanitized which may not make a difference but someone could do some http splitting when you do header(...).

    (note: I haven't had the chance to test these but.. yeah).
    Okay I'll take that into account.
    Quote Originally Posted by ralph l mayo
    You use basename but then don't include any restriction on $_POST['where']? So if $_POST['where'] == '/etc' and $_FILES[]['name'] == 'passwd', unless I'm missing something, you better hope all your permissions are secure?

    OTOH, is_uploaded_file is implied by move_uploaded_file, so don't worry about that. I just don't think there's any easy way to sanitize a user supplied directory, I'd rather drop it all in ./upload/ or something and know the area of effect is restricted.

    Also, is this arbitrary file upload ending up somewhere inside document root? So I can upload blah.php == <?php eval($_GET['f']); ?>? If so it can be used to get a remote shell as apache's user and probably to elevate to root by a determined hacker.
    I did recommend that the directory be password protected but I see what you are getting at. I wasn't really sure what the user wanted to do with the file. This could be implemented by using the absolute path of the server.

    So would this be okay in checking the upload directories?
    PHP Code:
    <?php
    $error 
    ""// Set a variable that will be used for errors
    $sendTo ""// Set a variable that will be used for emailing
    if(isset($_POST['upload']) && $_POST['upload'] == 'Upload File'// Form is submitted
    {
        
    $whereto $_POST['where']; // Gets post value from select menu
        
    $whatfile $_FILES['uploadedfile']['name']; // Gets file value from file upload input
        
    $subject "File uploaded to "$whereto ." directory"// This is the subject that will appear in the email
        
    $from "Upload form <noreply@yourdomain.com>";
        if(
    $whereto == ""// Checks to see if $whereto is empty, if so echo error
        
    {
            
    $error "You need to choose a directory.<br />";
        }
        if(
    $whatfile == NULL// Checks to see if file input field is empty, if so throw an error
        
    {
            
    $error .= "You need to choose a file.";
        }
        if(
    $whereto != "" && $whatfile != NULL && $whereto == "uploads1" || $whereto == "uploads2"//if no errors so far then continue uploading
        
    {
            
    $target_path "$whereto/"// The directory the file will be placed
            
            /* Add the original filename to our target path. Result is "uploads/filename.extension" */
            
    $target_path $target_path basename($whatfile);
            if(
    move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path))
            {
                
    header("Location: index.php?to=$whereto"); // Directs user back to page of choice
            
    }
            else
            {
                
    /* if there was a problem then throw an error */
                
    $error .= "There was an error uploading the file, please try again!";
            }
            if(
    $error == "")
            {
                if(
    $whereto == "uploads1"// Change $sentTo depending on the directory chosen
                
    {
                    
    $sendTo "Jim <jim@yourdomain.com>"// Change this to an email address of your own
                
    }
                if(
    $whereto == "uploads2")
                {
                    
    $sendTo "Kim <kim@yourdomain.com>"// Change this to an email address of your own
                
    }
                
    /* The below will be what is shown in the email */
                
    $body "You have received the following from the web based upload form:\r\n";
                
    $body .= "---------------------------------------------------------------\r\n";
                
    $body .= "Subject:    File uploaded to "$whereto ." directory\r\n";
                
    $body .= "File name:  "$whatfile ."\r\n";
                
    $body .= "Upload directory: "$whereto ."\r\n";
                
    $body .= "Uploader's IP address: "$_SERVER['REMOTE_ADDR'] ."\r\n";
                
    $body .= "---------------------------------------------------------------\r\n";
              
                  
    /* headers used to show from field in email client */
                
    $headers 'From: '.$from."\r\n" .
                    
    'Reply-To: '.$from
                
                
    /* this actually sends the mail */
                
    mail($sendTo$subject$body$headers);
            }
        }
    }
    ?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    <title>File Upload</title>
    </head>

    <body>
    <div>
    <?php
    if(!empty($error))
    {
    echo 
    $error;
    }
    ?>
    </div>
    <form enctype="multipart/form-data" action="<?php echo $_SERVER['SCRIPT_NAME']?>" method="POST">
        <input type="hidden" name="MAX_FILE_SIZE" value="100000" />
        Choose a file to upload: <input name="uploadedfile" type="file" /><br />
        <select name="where">
            <option value="">Choose a directory</option>
            <option value="uploads1">uploads1</option>
            <option value="uploads2">uploads2</option>
        </select>
        <input type="submit" name="upload" value="Upload File" />
    </form>
    </body>
    </html>
    or is there a more efficient way of doing this?
    Last edited by _Aerospace_Eng_; 04-28-2006 at 07:08 AM.
    ||||If you are getting paid to do a job, don't ask for help on it!||||

  • #7
    fci
    fci is offline
    Senior Coder
    Join Date
    Aug 2004
    Location
    Twin Cities
    Posts
    1,345
    Thanks
    0
    Thanked 0 Times in 0 Posts
    what ralph is getting is that someone can upload a PHP file which would be publically accessible.. which means you should be theoretically be checking against an allowed extensions array.
    and.. a more aesthetically pleasing way to check for a valid directory would be to use an array of directories then using in_array() (fewer ||'s).


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •