Jump to content

Using file attachments from forms


onjegolders
 Share

Recommended Posts

Hi guys, have been trying to figure out how I can get hold of a file's path when it has been uploaded via a form.

I don't need to add it to the database, just email it.

I am currently using phpmailer to send the email and all I need for it to send the attachment is the path of the uploaded file.

I have tried using $input->post then I was thinking it may be something to do with $file or $files?

Link to comment
Share on other sites

Think I've figured it out thanks. Guessing using the native PHP $_FILES is the way to go?

This is now my code, which seems to be working.

Would I have to add much to it security-wise?

Thanks again.

<!-- Included from portfolio entry page/template -->

<?php
$output = '';

if (isset($input->post->submit)) {

if (empty($input->post->name) || empty($input->post->company) || empty($input->post->email) || empty($input->post->phone)) {
$output = "<h6 class='error'>Please fill out all fields marked with a *</h6>";
}

if (!file_exists($_FILES['logo']['tmp_name']) || !is_uploaded_file($_FILES['logo']['tmp_name'])) {
$output = "<h6 class='error'>Please upload your logo</h6>";
}

else { // end required fields

if (filter_var($input->post->email, FILTER_VALIDATE_EMAIL) === FALSE) {
$output = "<h6 class='error'>Please include a valid email address</h6>";
}

if ($_FILES["logo"]["type"] != "image/png" OR $_FILES["logo"]["size"] > 300000) {
$output = "<h6 class='error'>Please ensure that your file is a PNG and is less than 300KB</h6>";
}

else {

require_once("./scripts/class.phpmailer.php");

$form = array(
'name' => $input->post->name,
'company' => $input->post->company,
'email' => $input->post->email,
'skype' => $input->post->skype,
'url' => $input->post->url,
'phone' => $input->post->phone,
'address_1' => $input->post->address_1,
'address_2' => $input->post->address_2,
'town' => $input->post->town,
'zip' => $input->post->zip
);

$to_name = "My name";
$to = "me@gmail.com";
$subject = "Agent signup from website";
$message = "";
$file_path = $_FILES["logo"]["tmp_name"];
$file_name = $_FILES["logo"]["name"];
$return_url = "$page->url";
foreach ($form as $key => $value) {
$message .= "$key: $value\n";
}
$from = "$form[email]";
$from_name = "$form[name]";

$mail = new PHPMailer();
$mail->FromName = "$from_name";
$mail->From = "$from";
$mail->AddAddress ($to, $to_name);
$mail->Subject = "$subject";
$mail->Body = "$message";
$mail->AddAttachment($file_path,$file_name);

$mail->Send();

$output = "<h6 class='success'>Thank you, your request has been sent. Please click <a href='$return_url'>here</a> to go back to the portfolio page</h6>";

}

}

} // end if isset submit

?>
Link to comment
Share on other sites

I think that anything that enables an anonymous user to upload a file to a web server is a security concern and needs to be monitored closely. Disclaimer out of the way, your approach seems reasonable at first glance. At least, nothing jumps out at me initially, though I'm assuming that PHPMailer prevents header injection and does some of it's own validation. Also, in your foreach($form) where you generate the message, you may want to limit the length of both the $key and the $value that get added to the message body. For instance: $value = substr($value, 0, 255); to limit the max length to 255 characters. In addition to validating the uploaded file's 'type', you might also want to sanitize/validate the filename, and also ensure it actually ends with the expected extension (png).

Link to comment
Share on other sites

I think that anything that enables an anonymous user to upload a file to a web server is a security concern and needs to be monitored closely. Disclaimer out of the way, your approach seems reasonable at first glance. At least, nothing jumps out at me initially, though I'm assuming that PHPMailer prevents header injection and does some of it's own validation. Also, in your foreach($form) where you generate the message, you may want to limit the length of both the $key and the $value that get added to the message body. For instance: $value = substr($value, 0, 255); to limit the max length to 255 characters. In addition to validating the uploaded file's 'type', you might also want to sanitize/validate the filename, and also ensure it actually ends with the expected extension (png).

Thanks Ryan for taking the time to reply.

I'm not actually sure if phpmailer does add any protection to the forms, so I may have to look into all that.

The form is actually just getting emailed, would the file still get passed through the server?

Link to comment
Share on other sites

The file would still get passed through the server, though it sounds like it wouldn't go beyond PHP's temporary dir (and whatever holding areas are used by the SMTP server).

I would be very surprised if phpmailer wasn't sanitizing for header injection since it's asking you to set things like 'From' and 'FromName' separately, rather than as a string of headers as with PHP's mail(). If it were going through PHP's mail(), we'd want to sanitize it like this:

// validate email
$fromEmail = $sanitizer->email($input->post->email);
$subject = "Agent signup from website";
$body = "Your email body here";

if($fromEmail) {

 // makes sure it's 1 line (no CR/LF), max 50 chars and no tags
 $fromName = $sanitizer->text($input->post->name, array('maxLength' => 50));

 // The sanitizer->text may be enough, but we'll go further here just to be safe...
 // remove any chars that aren't word characters, dash, digit, apostrophe, period or space 
 $fromName = preg_replace('/[^-\w\d.\' ]/', ' ', $fromName); 

 $headers = "From: $fromName <$fromEmail>"; 

} else $headers = '';

// send message
mail($toEmail, $subject, $body, $headers); 
Link to comment
Share on other sites

The file would still get passed through the server, though it sounds like it wouldn't go beyond PHP's temporary dir (and whatever holding areas are used by the SMTP server).

I would be very surprised if phpmailer wasn't sanitizing for header injection since it's asking you to set things like 'From' and 'FromName' separately, rather than as a string of headers as with PHP's mail(). If it were going through PHP's mail(), we'd want to sanitize it like this:

// validate email
$fromEmail = $sanitizer->email($input->post->email);
$subject = "Agent signup from website";
$body = "Your email body here";

if($fromEmail) {

 // makes sure it's 1 line (no CR/LF), max 50 chars and no tags
 $fromName = $sanitizer->text($input->post->name, array('maxLength' => 50));

 // The sanitizer->text may be enough, but we'll go further here just to be safe...
 // remove any chars that aren't word characters, dash, digit, apostrophe, period or space
 $fromName = preg_replace('/[^-\w\d.\' ]/', ' ', $fromName);

 $headers = "From: $fromName <$fromEmail>";

} else $headers = '';

// send message
mail($toEmail, $subject, $body, $headers);

Thanks Ryan, I appreciate the guidance

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...