I wanted to make a mail function in php to let visitors create and activate a user account. For this I made a mail with a link which refers to the page that activates the account. Now the problem is that some people want to use characters that interfere with the code inside the email. for example: " " and ' '. I tried to escape these characters, but when such character appears, the link becomes inactive. The mail is sent, but the link is unclickable.
This is what the code looks like.
The variables are set in PHP
$New_user->Username = $db->real_escape_string($_POST['un']);
$RawUn = $_POST['un'];
$New_user->Password = $_POST['pw'];
$New_user->Email = $_POST['em'];
$CheckEmail = explode("#", $New_user->Email);
$New_user->Country = $_POST['cn'];
$New_user->City = $_POST['ct'];
//$NEW_USER IS AN OBJECT CREATED TO HOLD ACCOUNT INFORMATION SUCH AS USERNAME AND EMAIL
//$RAWUN IS A VARIABLE TO HAVE AN UNESCAPED VALUE OF THE USERNAME TO INSERT IN THE INPUT FIELD IF SOMETHING WENT WRONG
After checking the values, the mail is sent:
$message = array(
'Hello ' . $New_user->Username . ',<br/>',
'<br/>',
'Welcome to MakeAMemo.<br/>',
'To start working with your account you will have to activate it.<br/>',
'Just click on the link and you are ready to go.<br/>',
'Log in and check if it works. If not, please contact us(E-mail is on the website).<br/>',
'Your password: ' . $New_user->Password . '<br/>',
'<br/>',
'Kind regards,<br/>',
'<br/>',
'Administration');
$header = array(
'From: makeamemoofficial#gmail.com',
'Reply-To: makeamemoofficial#gmail.com',
'Content-type: text/html');
mail($New_user->Email,"MakeAMemo => New account",implode("\r\n", $message),implode("\r\n", $header));
I have made a connection to the datebase, so the escaping using $db->real_escape_string works fine.
The location of the link will be changed when the website is finished.
I checked if the code worked without the str_replace in the href. No succes. Neither I got succes trying to not escape the username.
The tags are invisible in the mail, so it is recognised. The link is not blocked, because it does work when I don't use special characters. When changing the double quotation marks into single quotation marks, you reverse the effect, which means that instead of " ", ' ' don't work.
I do not think the headers have something to do with it, because the link does work when using normal characters.
Any idea what the cause of my problem is?
Every answer is appreciated.
adear11: here is the generated tag:
link
"s avonds is an incorrect dutch word that contains some of the characters that need to be tested.
Rather than using str_replace in your email, you should use urlencode http://php.net/urlencode
This function is specifically for encoding strings for use in urls
As for the link not always working when it is formed properly, would be that the user isn't using HTML email.
Also, while not specific to your problem, this script is crazy insecure. You never ever ever need to use user supplied input ($_POST in your case) without sanitizing the input first. At a minimum, all of those assignments need to be run through htmlspecialchars.
Update
Given the trouble that you are having, I would consider not passing the actual data around in the URL. Rather, I would save the data to the DB and then generate a token to put in the url. If you generate a token with uniqid you won't have any trouble with these special characters because the string will be alphanumeric. Once the user clicks the link, just grab the data associated with the token and proceed as you would if the data was in the URL.
Related
We have a website with restricted access (only for exclusive members) coded in PHP.
On the Contact page we have a bunch of mailto links, for example:
address#domain.com
If a visitor clicks on one of the links, it does the usual stuff (opens a new email in Thunderbird with the To: field correctly filled in).
The problem is when a visitor right-clicks on one of the links, selects "Copy email address" and then pastes it in the To: field or wherever (even in a document), in which case the result would be:
Name%20SURNAME%20%3Caddress#domain.com%3E
instead of
Name SURNAME <address#domain.com>
I've been searching for a solution for hours and already tried rawurlencode(), urlencode() and other possible tricks, with absolutely no effect.
Can some of you please help me?
Here is the PHP code that generates the link:
<?php echo ''.$email.''; ?>
//where $email is a valid email address
//and $name is plain text (usually two words with a space character between)
I believe you're trying to do something that simply cannot be done.
I understand the idea but... it's not a thing.
I found no docs saying that you can put a name and enclose the email address in <>.
https://developer.mozilla.org/.../a#Creating_an_email_link
https://developer.mozilla.org/.../Creating_hyperlinks#E-mail_links
IETF RFC6068
You can of course do:
address#domain.com
I found this : https://stackoverflow.com/a/25854290/3376036.
It seems it's actually not supported but it usually works
I am building an emailing template system using PHP. The idea is that the same system can be used to send a variety of automated email, eg when people join a site etc. The contents of each email are held on a MySQL database and I use placeholders to represent dynamic elements such as name, email, etc. The placeholders take the form of two underscores before and after a name: __name__, (NB the stackoverflow markup may convert the underscores to make the placeholder name appear in bold here) and a separate field matches the placeholder to the variable it represents eg:
__name__=[($user['name'])], __email=[($user['email'])]
When I construct the email, the system takes the placeholders and holds them in an associative array:
$placeholders( '__name__' => $user['name'], '__email__' => $user['email'] );
This is exactly how the array appears. I have used explode to strip out the enclosing [( and )] brackets.
I am able to loop through the email content and use Parsedown and preg_replace to swap the placeholders with their corresponding variables, eg:
$body = 'Dear __name__, your email is __email__'
becomes:
$body = 'Dear $user['name'], your email is $user['email']
However, this is exactly how the content appears in the final email that is actually sent. The value of these variables (which I have successfully established previously in an array $user ) do not appear in the final text, eg:
'Dear John, your email is john#smith.com'.
How do I get PHP to replace the variables with their values before the email is sent?
PS I have also tried:
'Dear ' . $user['name'] . 'Your email is ' . $user['email']
(ie with an inverted comma and a period to differentiate the variables from the rest of the text ) but no avail. It appears as:
Dear Mr Mercer,
Thank you for registering your details with mercermania.com.
Please verify your email address now
We now need to verify that the email address you supplied when you registered does indeed belong to you. Please click on the following link:
http://www.mercermania.com/activation/?x=' . $user_info['email'] . '&y=' . $user_info['active'] . '
I have done it before, so know it can be done but for the life of me I cannot remember how!
Any help greatly appreciated.
PS I am using PHP Mail::factory to send the email and an email is actually sent, and is received, so that is not the issue.
I'm using a mailto link to send e-mail with a php string variable inside it as follows:
'Would you like to E-mail stakeholders? <a class="emailLink" href="mailto:stakeholders?subject=Alert '.$ticket.'&body=Experience: %0D%0A'.$exp.'">Review and Send!</a><br><br>';
I discovered that in the e-mail client it prints it out like:
Experience:
Th Experience should contain:\r\n\r\nImpact\r\nHow to replicate\r\nComprehensive notes
So I tried:
$charactersToRemove = array("\r\n","\n","\r");
$replaceWith = "%0D%0A";
$exp = str_replace($charactersToRemove,$replaceWith,$exp);
Which doesn't seem to make a difference...Can someone tell me why? Thanks.
Can you post more of your code to show how $exp was assigned it's value?
I've edited out my answer until I can provide better help.
EDIT: Can you seriously try using "\r\n" with \" to escape "'s instead, just in case PHP is somehow localizing %0D$0A in your HTML output? What does the source of your page look like?
From a form, I'm asking the user to enter some text. I will retrieve this text using $_POST['text'].
The user enters the string "It's my text!"
$newText = mysql_real_escape_string($_POST['text']);
Now on the very same page after I've inserted $newText into the database I want to display
the text to the user and also use it as the value of an input text box using PHP.
// I want to make sure the user hasn't added any unsafe html in their string
$newText = htmlentities($newText);
echo "You've entered: " . $newText . "<br />";
echo "<form action=someaction.php method=post>";
echo "<input type=text value=\"" . $newText . "\">";
echo "</form>";
The output is:
You've entered: It\'s my text!
[It\'s my text!]
How do I avoid these slashes, and should I be doing anything else with my data?
You're passing the text through mysql_real_escape_string() which, as the name suggests, escapes the string, including apostrophes. mysql_real_escape_string() is meant only for preparing the data for saving to database. You shouldn't use it when displaying data to the user.
So, the solution is simple: remove the line and use htmlentities() only. Use mysql_real_escape_string() when you're saving the string to database (and only then).
Only use mysql_real_escape_string() on the variable you want to use in the query, because it will add slashes to escape some of the characters in the string. This works great for mysql, but when want to use it on the page it will look weird.
You could make 2 variables, 1 for MySQL and 1 for displaying the raw text.
$text = $_POST['text'];
$db_text = mysql_real_escape($text);
Also note that you should use strip_slashes() on the data you get from the database later, to remove the slashes.
Hope this clear things up a little bit.
Now on the very same page after I've inserted $newText into the database I want to display the text to the user
That's what you are doing wrong.
An HTTP standard require a GET method redirect after every successful POST request.
So, you have to redirect the user on the same page, where you may read inserted data from the database and show it to the user.
As for the mistake you made - just move escaping somewhere closer to the database operations, to make sure it is used only for the purpose (YET it is used obligatory, without the risk of forgetting it!).
Ideally you have to use some variables to represent the data in the query, and some handler to process them.
So, the query call may look like
DB::run("UPDATE table SET text=s:text",$_POST['text']);
where s:text is such a variable (called placeholder), which will be substituted with the $_POST['text'] value, properly prepared according to the type set in the placeholder name (s means "string", tells your function to escape and quote the data)
So, all the necessary preparations will be done inside and will spoil no source variable.
save normally using mysql_real_escape_string()
and when you want to display it in a form:
htmlspecialchars(stripslashes($row['text_data']))
it will do the trick.
I have the following test line in my PHP which works fine as a way of posting to Twitter from within my PHP code.
$oauth->post('statuses/update', array('status' => "hello world"));
However I want to post the contents of a variable as opposed to Hello World
If I change the code as follows, then all that gets posted is $message
$oauth->post('statuses/update', array('status' => '$message'));
I also tried without the ' but then nothing got posted, ie
$oauth->post('statuses/update', array('status' => $message));
How can I correctly parse the contents of $message?
$message is created as follows
$message = "http://www.smartphonesoft.com/index.php?option=com_mtree&task=viewlink&link_id=" .$link_id . " " ."Windows Phone Software" . " " .$link_name . " " . $metadesc;
I added an echo $message which showed me what I expected, namely:
http://www.smartphonesoft.com/index.php?option=com_mtree&task=viewlink&link_id=33183073
Windows Phone Software Pocket Player
Pocket Player is a rockin' way to
enjoy music and video on your Windows
Mobile device. Through multiple media
and playlist formats, Internet
connectivity, plugin extensions, and
an intuitive interface, Pocket Player
means less taps, more music!
Thanks,
Greg
From the Twitter API doc for status/update:
status The text of your status update, up to 140 characters. URL encode as necessary.
So I'd say you have to shorten the $message, because yours has 369 characters.
The last code you quote is correct. Are you sure $message has meaningful content?
(Aside: The reason for '$message' posting "$message" verbatim is that single-quoted strings in PHP do not get variable interpolation nor escape characters: '\n' is literally "\n", whereas "\n" would result in a string containing the newline character.)
'$message' can't work because you're actually passing the string "'$message'", and not the $message variable.
If the second code you posted doesn't work, it's either because $message is not defined in your script, or because something else in your script is wrong, but we can't really tell that without seeing the rest of the code.
Since your URL is way too long for twitter, perhaps you'd like to shorten the url before posting it.
The bit.ly API documentation page will help you set up an account and your own api key.
You could then either devise your own code from the official documentation or follow this bit.ly api tutorial by David Walsh