Sending an uploaded file through email without saving it first - javascript

I am creating an application that allows a user to attach a file, type a message, then an email is sent using the PHP mailer plugin for wordpress. I use javascript to get the file information from the upload html form and then php to send the email. The plugin works when sending a file that is saved on the server in a specific location using this function:
$mail->AddAttachment("./new6.txt","attachment");
I was wondering if there is a way to email the file selected without having to save it to the server. In other words, can a user select a file to upload, but send the file with this php function without saving it in a location to be retrieved? I know there is a $_FILES array that you can get the file's information but will that file be able to be sent without it being saved somewhere first? I'm guessing not since the whole point of the upload form is to "upload" it but just wondering if something could be done in javascript or something.
Thanks for any help

You can't truly do that, but you could do this to get a close effect:
$filename = $_FILES['file_name']['tmp_name'];
$main->AddAttachment($filename, "attachment");
// Send the email... then:
unset($filename);
This adds the file as an attachment, sends the email, then deletes the file. The uploaded files in the $_FILES array will automatically be flushed out eventually, so I'm not sure if the unset() part even does anything significant, but it surely gets rid of the file.

Without Saving file in Server, you can not attach it for mail.
1> Mailing function is executing in Server.
2> It is not possible from Server to get the absolute file path in client machine as in web, the client machines do not have any absolute address.
3> So the file is needed to be uploaded in server to get a real path for the file to have in attachment of Mail.

I know this is a rather old question, but I think there's a rather useful answer that was never given. For the sake of those like me who happned along this question while searching for an answer to this question or similar, here you go.
When you upload a file to a server from a form, it's saved to the tmp directory automatically. Technically it's impossible to do anything with a form uploaded file without saving, because it's done for you automatically. However, because tmp is automatically cleaned on every reboot, this shouldn't be an issue in terms of building up too much backlog, if you either reboot often or set up a cron to delete your tmp directories contents regularly.
However, because it's saved to tmp, and because you can manipulate the file from there, it is possible to send the file without saving it for any form of longevity, and without actually writting anything to save it. Provided you perform all the necessary security checks on the file (verifying the contents, MIME-type and such that I won't go into now, but you can read up on how to do here), you can use the following php function which I got from Codexworld and modified to use the tmp files. All you need to do is pass
the parameters, and the $files is an array of files you've hopefully already vetted.
function multi_attach_mail($to, $subject, $message, $senderEmail, $senderName, $files = array()){
$from = $senderName." <".$senderEmail.">";
$headers = "From: $from";
// Boundary
$semi_rand = md5(time());
$mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";
// Headers for attachment
$headers .= "\nMIME-Version: 1.0\n" . "Content-Type: multipart/mixed;\n" . " boundary=\"{$mime_boundary}\"";
// Multipart boundary
$message = "--{$mime_boundary}\n" . "Content-Type: text/html; charset=\"UTF-8\"\n" .
"Content-Transfer-Encoding: 7bit\n\n" . $message . "\n\n";
// Preparing attachment
if(!empty($files)){
for($i=0; $i<count($files); $i++){
if(is_file($files[$i]["tmp_name"])){
$tmp_name = basename($files[$i]["tmp_name"]);
$file_name = $files[$i]["name"];
$file_size = filesize($files[$i]["tmp_name"]);
$message .= "--{$mime_boundary}\n";
$fp = fopen($files[$i]["tmp_name"], "rb");
$data = fread($fp, $file_size);
fclose($fp);
$data = chunk_split(base64_encode($data));
$message .= "Content-Type: application/octet-stream; name=\"".$file_name."\"\n" .
"Content-Description: ".$file_name."\n" .
"Content-Disposition: attachment;\n" . " filename=\"".$file_name."\"; size=".$file_size.";\n" .
"Content-Transfer-Encoding: base64\n\n" . $data . "\n\n";
}
}
}
$message .= "--{$mime_boundary}--";
$returnpath = "-f" . $senderEmail;
// Send email
$mail = mail($to, $subject, $message, $headers, $returnpath);
// Return true, if email sent, otherwise return false
if($mail){
return true;
}else{
return false;
}
}

Related

how to save tensorflow save model multiple files in php

I have developed a neural network model with tensorflow. I want to save weights of my model on each time they update. So i though of updating a file on the server every time it learns. but the documentation on tensorflow js website on saving model using http server is really confusing. So i did some research and found some code. Still it is not working. I know i am missing the "multipart/form-data" and fact that there are two files, "The body consist of two files, with filenames model.json and model.weights.bin". Could not find anything that could help me. link to tensorflow documentation!
javascript to save
model.save('http://example.com/save.php');
save.php
<?php
$putdata = fopen("php://input", "r");
$fname = "weights.json";
$file = fopen("../static/" .$fname, 'w');
while ($data = fread($putdata, 1024)){
fwrite($file, $data);
}
fclose($file);
fclose($putdata);
?>
http://php.net/manual/en/function.file-put-contents.php
I don't see the input section with php stdin. This makes me feel like the connection isn't sending a stream like a socket connection, but rather a standard HTTP payload with a body attribute. But wait, theirs caveats. If it is a JSON payload you'll need the second two lines (like you had in your code, but not as a resource). The first two are my guess as to what may be going on. Remember you can debug through your browsers console to see the data payload, request method, ect...
$data = '<pre>' . json_encode($_POST) . '</pre>';
file_put_contents('stdPost.html', $data);
$data = file_get_contents('php://input');
file_put_contents('stdInput.json', $data);

What is wrong with my form.php (reCaptcha) [duplicate]

My previous question on StackOverflow was about that someone was sending me hundreds of spam emails every few hours. Now, I fixed the script on the server side but the next morning I still got 30 emails or something and my hosting company gave me a new password to my FTP and moved my index files to a backup map(website offline), they said it was hacked because of the suspicious script below. They said "This often happens via a leaked script in your website, a script that is "out of date". What does that mean? They say in the email that there is something with this script file. Which is impossible to hack in right because I used reCaptcha on the server side, is there something missing?
<?php
if(isset($_POST['g-recaptcha-response'])){
$captcha=$_POST['g-recaptcha-response'];
}
/* OUTCOMMENTED CODE BELOW DOESN'T LET FORM SEND IF EVERYTHING IS CHECKED????
if(!$captcha){
echo '<h2>Check captcha .</h2>';
exit;
}*/
$response=file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=(SECRETKEY)&response=".$captcha."&remoteip=".$_SERVER['REMOTE_ADDR']);
if($response.success==false)
{
echo '<span id="status" style="font-size:1vmax;color:red;">ReCaptcha ERROR</span>';
}else
{
if( isset($_POST['n']) && isset($_POST['e']) && isset($_POST['mn']) &&
isset($_POST['m']) ){
$n = $_POST['n']; // HINT: use preg_replace() to filter the data
$e = $_POST['e'];
$mn = $_POST['mn'];
$m = nl2br($_POST['m']);
$to = "gesternl#gester.nl";
$from = $e;
$subject = 'Contact Formulier-eng';
$message = '<b>Naam:</b> '.$n.' <br><b>Email:</b> '.$e.' <br><b>Mobiel-nummer:</b> '.$mn.' <p>'.$m.'</p>';
$headers = "Van: $from\n";
$headers .= 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
if( mail($to, $subject, $message, $headers) ){
echo "success";
} else {
echo "The server failed to send a message. Please try again later. Thank you!";
}
}
}
?>
I just uploaded it again to see what is going to happen now. Can someone please help me make this file secure for a hacker. Nobody really helped in the previous question but only gave advice without code (and I am nooby).
(The outcommented code around line 8 doesn't work which i don't understand, does someone know why is that why someone can hack into it maybe?)
And yes the code in the HTML for recaptcha is well linked with the public key
$response=file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=(SECRETKEY)&response=".$captcha."&remoteip=".$_SERVER['REMOTE_ADDR']);
if($response.success==false)
This fragment of code is an unfortunate bit of nonsense that has found its way into a lot of (terrible) tutorials. It provides no protection whatsoever -- the condition is always false, because $response.success is interpreted as concatenating the constant success to the API response returned by the reCaptcha API. This will cause the CAPTCHA to be always treated as valid, regardless of the user's input.
Use the Google reCaptcha library to verify responses from the reCaptcha API. It is available at: https://github.com/google/recaptcha
You're not sanitizing user input, for one. You should fix that right away as it's a security flaw.
You've to sanitizing user input as said #kevin Cai
You've an error in line: if($response.success==false)
$response=file_get_contents("......");
$result = json_decode($response);
if($result->success==false){

Sending data to PHP page to make a spreadsheet out of it

For some reason, when I try to send JSON data to a PHP page (where it gets downloaded as a spreadsheet), it runs without error, but doesn't bring up the prompt to download the spreadsheet. The JSON has generated without problem (I have made the PHP page create the file on the server, before trying to make it download without creating it).
Here is the JavaScript code that sends the JSON data to the server:
function writeToSpreadsheet()
{
// get the json for #theTable
var tableJSON = tableToJSON("tr:not(#titleRow)");
//alert(tableJSON);
alert("Sending table data to be written to the spreadsheet...");
$.post('/ResearchProject/tableContent/exportTable.php', {'table': tableJSON}).done(
function(response) { alert(((response == '') ? response : (tableJSON.title + ' written to file!')));})
.fail(function (xhr, ajaxOptions, thrownError) { alert("ERROR:" + xhr.responseText+" - "+thrownError); });
}
and here is exportTable.php
<?php
function cleanData(&$str)
{
$str = preg_replace("/\t/", "\\t", $str); // escaping all of the tabs
$str = preg_replace("/\r?\n/", "\\n", $str); // escaping any and all cases of carriage return
// if there is a single double-quote in the string, we wrap the string in quotes, replace every single double-quote with double double-quotes, and
// end with a double-quote
if(strstr($str, '"')) $str = '"' . str_replace('"', '""', $str) . '"';
}
// the data is coming from a JSON object that is being sent here
if (isset($_POST['table']))
{
$tableJSON = $_POST['table']; # somehow, this is already a PHP array (exactly the one we need)!!
// get the name of the table from the $tableJSON
$tableName = $tableJSON['title'];
// get the title row from $tableJSON
$titleRow = $tableJSON['titleRow'];
// fix the titleRow
foreach ($titleRow as $heading)
{
$heading = trim(preg_replace('/\s+/', ' ', $heading));
}
// get the rows from $tableJSON
$rows = $tableJSON['rows'];
// form the filename from the tableName
$fileName = $tableName . '.xls';
// here, we download the file without even creating it
header("Content-Disposition: attachment; filename=\"$fileName\"");
header("Content-Type: application/vnd.ms-excel");
// we echo the titleRow first
array_walk($titleRow, 'cleanData');
echo implode(chr(9), $titleRow) . "\r\n";
?>
<script>console.log('Title row written to file.');</script>
<?php
// now we echo the data
foreach($rows as $row)
{
array_walk($row, 'cleanData');
echo implode(chr(9), $row) . "\r\n";
?>
<script>console.log('Data row written to file.');</script>
<?php
}
}
else
{
echo 'You sent me no data :(\n';
}
?>
OK, MikeWarren, how do I test this??
You can test it by selecting a table from the dropdown menu and clicking the "Export table to spreadsheet" button here: http://dinotator.biokdd.org/ResearchProject/tableViewer.php
I am trying to have it where the table that is on the HTML page gets converted into an JSON object, and then downloaded. Thus, I would need to POST the data to the PHP page, right? (Query strings don't work.)
Query strings won't work because you are using jQuery's $.post call which means that your data is sent in the body of the request, as opposed to a query string which is what a GET uses. For JSON you do indeed want to use a POST.
As for what's going wrong, you need to decode your JSON into a PHP array using json_decode. Unfortunately it can't simply handle JSON how it is.
So most likely you'll want to do:
// now a poorly named variable
$tableJSON = json_decode($_POST['table']);
Also, looking at your Ajax, $.post does accept a .fail() listener, but it doesn't pass any error data as part of the callback. So if you want to be able to handle incoming response errors you'll need to use $.ajax:
$.ajax({
type: "POST",
url: "/your/url.php",
dataType: "json",
error: errorCallback
});
Finally, looking at how your code is structured, if you're actually trying to save to file, you're going to need some more logic. Right now, you're just rendering that table, and then returning it as a response which will show up in your done function. You're going to add some more logic in order to make it actually download. This question entails your exact problem.
Good luck!
I have found so much bad advice on the internet about how to solve this problem. One of the answers here also didn't work. :(
I have decided to get advice from a friend of mine, and me and him have decided on this approach:
Have my exportData.php simply write the data to $_SESSION, echo a JSON-encoded "success", and then exit
On exit, on the client-side of things, if "success" has been received, have the JavaScript open up a new tab to a file that I have created called downloadFile.php which actually does the downloading.
Why didn't sending the data between files work?
Downloading data entails setting the right headers and printing the data. When you send data to the file to do this (via AJAX), the buffer that the data is printed to is the one for response. You can see this by saying something like
success: function(response)
{
alert(response);
} and see the data that you "downloaded" not get downloaded, but get printed on-screen.
However, if you go to the file instead of simply passing data to it, your data will download, provided that it has access to the data that you are trying to download. You can see examples of this here: www.the-art-of-web.com/php/dataexport/ . In those examples, the data was "static" (that is, only existing in the scope of that PHP file, until download happened).
We then see that we should let another file handle the downloading. Here is what its contents should look like:
<?php
if (!isset($_SESSION))
session_start();
function cleanData(&$str)
{
$str = preg_replace("/\t/", "\\t", $str); // escaping all of the tabs
$str = preg_replace("/\r?\n/", "\\n", $str); // escaping any and all cases of carriage return
// if there is a single double-quote in the string, we wrap the string in quotes, replace every single double-quote with double double-quotes, and
// end with a double-quote
if(strstr($str, '"')) $str = '"' . str_replace('"', '""', $str) . '"';
}
// get the data from $_SESSION
if (isset($_SESSION))
{
$fileName = $_SESSION['fileName'];
$titleRow = $_SESSION['titleRow'];
$rows = $_SESSION['rows'];
// set the excel headers
header("Content-Type: application/vnd.ms-excel");
//header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"$fileName\"");
header("Pragma: no-cache");
header("Expires: 0");
// attempt download
array_walk($titleRow, 'cleanData');
echo implode(chr(9), $titleRow) . "\r\n";
// now we echo the data
foreach($rows as $row)
{
array_walk($row, 'cleanData');
echo implode(chr(9), $row) . "\r\n";
}
}
else
{
die('Problem with session variable. Data could not be sent for download.');
}
exit;
?>
Of course, before doing this, make sure that you have 'fileName', 'titleRow', and 'rows' already written to $_SESSION.
This should help anyone having problem downloading HTML table to Excel spreadsheet via PHP, and the best part is that you don't have to bloat your server by downloading an entire library, for potentially the functionality of one button!!

PHP capture form data and image upload, save to server

I know that this should not be a difficult thing to accomplish in PHP however it is giving me the hardest time!
I am trying to do this:
1) Capture form string data AND an image upload in a single form
2) Upload both types of data to the server with a single non-ajax/traditional POST to a simple PHP script (process.php in this case)
3) Take the image the user uploaded, save it in as a text file in a directory named dynamically by the first letter of the first name and the entire last name concagnated together so for me the directory structure would be as follows: /home/uploads/nabrams/image.jpg, /home/uploads/nabrams/userdata.txt,
*The text file will contain the text strings from the client side form, the image from the input[type="file"], once again contained in the same form, sent to the server with 1 submission.
I am using a text file in order to provide the simplest case possible.
Here is the code I am working with currently:
<?php
$uploaddir = '/home/nicholasabrams/public_html' + '/newprofiledata/' + $lname + '/' + $_FILES['userfile']['name'];
$uploadfile = $uploaddir . basename($_FILES['userfile']['name']);
echo "<p>";
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
echo "File is valid, and was successfully uploaded.\n";
} else {
echo "Upload failed";
}
echo "</p>";
echo '<pre>';
echo 'Here is some more debugging info:';
print_r($_POST);
print_r($_FILES);
print "</pre>";
However when attempting to upload an image of several formats and sizes (multiple attempts), I am stuck at an error-less blank window. To no surprise, the script did not upload or rename the image as desired.
Also - when trying to add the post data directly into the file name like so:
$uploaddir = '/home/nicholasabrams/public_html/' + $_POST['lname'] + '/' + $_FILES['userfile']['name']; $uploadfile = $uploaddir . basename($_FILES['userfile']['name']); if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile))...
I get filenames with 0pictureNameHere.jpg instead of NAbrams.jpg or if using post data to set the directory, I will never get the image or data in this way.
Side note:
I am a Javascript and jQuery ( <- mainly) developer, would it be worth it for me to attempt doing this with express or some other node module? I am not experienced with node although I have been "using it" for the last few months.
Thanks for the help!

Is This Contact Form Email Script Secure

I found the following contact form script online and I want to find out if it is secure, and if it is not how I might make it more secure. I just went back to the page where I think I got the code a long time ago and I see one commentor said :
"client side validation is only for user conveneicne, it doens't prevent spam, hackers, or annoying web devs. All a hacker has to do is create their own HTML file without javascript. Spam bots wouldn't even use the form they'll just parse it for the id's and send raw packets. Always check input on the server, never trust the user. "
I'm not exactly sure what that means, but hoping if someone sees a vulnerability in the code below it the comment may make more sense :
<?php
$EmailFrom = Trim(stripslashes($_POST['Email']));
$EmailTo = "info#mysite.com";
$Subject = "Customer Inquiry from MySite.com";
$Name = Trim(stripslashes($_POST['Name']));
$Tel = Trim(stripslashes($_POST['Tel']));
$Email = Trim(stripslashes($_POST['Email']));
$Message = Trim(stripslashes($_POST['Message']));
// validation
$validationOK=true;
if (!$validationOK) {
print "<meta http-equiv=\"refresh\" content=\"0;URL=http://www.mysite.com/contact-us-error.php\">";
exit;
}
// prepare email body text
$Body = "";
$Body .= "Name: ";
$Body .= $Name;
$Body .= "\n";
$Body .= "Tel: ";
$Body .= $Tel;
$Body .= "\n";
$Body .= "Email: ";
$Body .= $Email;
$Body .= "\n";
$Body .= "Message: ";
$Body .= $Message;
$Body .= "\n";
// send email
$success = mail($EmailTo, $Subject, $Body, "From: <$EmailFrom>");
// redirect to success page
if ($success){
print "<meta http-equiv=\"refresh\" content=\"0;URL=http://www.mysite.com/contact-us-success.php\">";
}
else{
print "<meta http-equiv=\"refresh\" content=\"0;URL=http://www.mysite.com/contact-us-error.php\">";
}
?>
Thanks for taking a look
You need to understand why some things aren't secure, not just ask people when you don't know.
First of all, you mentioned client-side validation. Are there any constraints you're trying to validate client-side? For instance, is there javascript (or maybe an HTML attribute) that prevents the user from typing more than a certain number of characters in the body of the email?
If so, and if you count this as a security breach, then the page is not secure. If I wanted to abuse your site in this way, I couldn't do it just by visiting the site in the normal way with a browser. But that doesn't stop me from sending whatever I want over the network. I could use something like curl ( http://curl.haxx.se/ ) to send a long request to your server; your server would have no way of knowing it wasn't from a browser, wouldn't check its length, and would send the email.
There's another way an attacker can use the server for something it's clearly not intended for. Namely, they can add extra headers. For instance, suppose they wanted to add the header MyHeader: something malicious. They could send a request in which $_POST['Email'] was the following string:
me#example.com>\r\nMyHeader: something malicious\r\nJunkHeader: junk
Then, the string "From: <$EmailFrom>" would look like this:
From: <me#example.com>
MyHeader: something malicious
JunkHeader: junk>
And those are the headers that would be sent. (I added a line of junk so that the extra > at the end wouldn't appear as part of MyHeader interfere with whatever nefarious plan I was attempting.)
Presumably because of this vulnerability, according to http://uk1.php.net/manual/en/function.mail.php : "The additional_parameters parameter is disabled in safe_mode and the mail() function will expose a warning message and return FALSE when used." (From PHP4.2.3 onwards.)
To fix this, I suppose it is sufficient to check that $EmailFrom contains no newline characters, and refuse to send the email if it does.

Categories

Resources