I am working on an application that is used for managing the groups of recipients and multiple contents to send
I want to use different html design so i saved it in a table with some PHP code in it.
But problem is this, I m not getting the PHP code executed when send mail using these HTML contents.
I m using PHPMailer for sending mails and saved HTML contents using addslashes and getting back with stripslashes.
Thanks.
Saved HTML contents using addslashes and getting back with
stripslashes.
That's bad. I don't know why you did, but if your intention was to escape queries, use mysql_real_escape_string(), or an analgoue function for your DB driver (or use parametrized queries).
If your intention was to, I don't know, sanitize html? well, that's useless. So no need to add slashes here for any reason.
But problem is this, I m not getting the PHP code executed when send
mail using these HTML contents.
Because your content is returned as a string, so PHP will read it as such, tags included.
A dirtiest solution, AND HIGHLY DISCOURAGED, is using eval() to evaluate php code and have it executed. But this is very risky and can lead to serious security problems, so I'm not even going to show you some example :)
The BEST SOLUTION is to use some sort of templating system. I'm not suggesting using Smarty or another full-blown template engine, but you can roll-out a simple custom-code parser that can work along these lines:
You save your variables using a placeholder, like
{{variable_text}} {{recipient}} {{address}}
or something like this. The you just replace what you need, so in your PHP script that reads this e-mail you can do like
$change = array('recipient' => 'John Smith',
'address' => 'Unknown Avenue, 666',
'variable_text' => 'We are glad to invite you to');
$text = '<p>To: {{recipient}}.</p>
<p>Address: {{address}}.</p>
Message: Dear{{recipient}}<br />{{variable_text}}';
foreach($change as $k => $v)
{
$text = str_replace('{{'.$k.'}}', $v, $text);
}
Related
I'm using PHPMailer to send emails.
Now, we all know we need to always check user input.
But how about the subject and body of emails? (so i do not mean the emailadress)
What does need to be sanitized and how to do it? What are the (major) vulnerability's?
Should i'll use something like HTMLPurifier for this? Because i want the user to be able to markup there emails. Or should i'll use/write a BB-code function what can be used?
Update:
For mail body:
I now use htmlspecialchars with ent_quotes flag on. After this ill run a BB-code (jBBCode) parser over the message. This one looks safe now.
For subject:
I do not use any validation/sanitizing/etc. (exept min and max strlen) on the subject field.
Tested with some javascript but it looks like it's all okay.
Can i assume this is safe now? (P.s. the code does not get printed anywhere else than in the email.)
Yes, you need to clean user input before sending. HTMLPurifier and HTMLawed make a fair job of sanitising, but need to be tuned to not block out useful stuff - both err on the side of caution. BBCode or markdown do make things much easier to filter, so long as you don't need to do intricate layouts.
You can use
<?php
filter_var($body, FILTER_SANITIZE_FULL_SPECIAL_CHARS)
to help protect against special characters also you can use RAW such as
<?php
filter_var($body, FILTER_SANITIZE_RAW, FILTER_FLAG_ENCODE_HIGH)
Full details can be found here -> https://secure.php.net/manual/en/function.filter-var.php
I'm considering converting a website from Adobe to Yii. In the Adobe code, I have an include page of variables that uses the form POST data like this:
$firstContact = "This is an email I sent to {POST.userFirstName}";
When I submit, the post data is picked up by the variable and is sent nicely.
But as I start to convert these pages to Yii, I'm wondering if that {POST.userFirstName}
is something that Yii will recognize as php and properly deploy that POST data in the email message.
Can someone kindly tell me where to look in the Yii documentation that will actually
answer this, or, if you already know that it does work, just tell me that, too?
Thanks
Syntax in php would be like this
$firstContact = "words ".$_POST['userFirstName']." more words ";
Or
$firstContact = "words {$_POST['userFirstName']} more words ";
But I would personally include this
$userFirstName = isset($_POST['userFirstName']) ? $_POST['userFirstName'] : '';
$firstContact = "words $userFirstName more words ";
In the case of emails with post data injected into them I would very strongly recommend adding htmlentities
$userFirstName = isset($_POST['userFirstName']) ? htmlentities($_POST['userFirstName'], ENT_QUOTES, "UTF-8"); : '';
$firstContact = "words $userFirstName more words ";
But please note this will render html useless such as <p>html<\p> for example, so it largely depends on what you need and if you can 100% trust the content, who is sending the email and who it's being sent to. The reason is that a user could add html containing Javascript code that could hijack user data sessions etc. all kinds of evil things that is best avoided.
There are several ways to put variables in strings ( interpolation ), Yii may offer a way like that but it's not done in native php as such. A lot of template systems use similar syntax to what you have, but I am not of fan of using just POST, I would need the _ in front as in {_POST.var} but that is just me.
The . in php is the concatenation operator similar to the + in Javascript. Many template systems use it as an access operator, which is what Javascript does, this is simular to the -> in php or [ ] in the case of an array. In general template designers will be more familiar with Javascript, which is why they use the . that way.
I have a form with 2 textareas; the first one allows user to send HTML Code, the second allows to send CSS Code. I have to verify with a PHP function, if the language is correct.
If the language is correct, for security, i have to check that there is not PHP code or SQL Injection or whatever.
What do you think ? Is there a way to do that ?
Where can I find this kind of function ?
Is "HTML Purifier" http://htmlpurifier.org/ a good solution ?
If you have to validate the date to insert them in to database - then you just have to use mysql_real_escape_string() function before inserting them in to db.
//Safe database insertion
mysql_query("INSERT INTO table(column) VALUES(".mysql_real_escape_string($_POST['field']).")");
If you want to output the data to the end user as plain text - then you have to escape all html sensitive chars by htmlspecialchars(). If you want to output it as HTML, the you have to use HTML Purify tool.
//Safe plain text output
echo htmlspecialchars($data, ENT_QUOTES);
//Safe HTML output
$data = purifyHtml($data); //Or how it is spiecified in the purifier documentation
echo $data; //Safe html output
for something primitive you can use regex, BUT it should be noted using a parser to fully-exhaust all possibilities is recommended.
/(<\?(?:php)?(.*)\?>)/i
Example: http://regexr.com?2t3e5 (change the < in the expression back to a < and it will work (for some reason rexepr changes it to html formatting))
EDIT
/(<\?(?:php)?(.*)(?:\?>|$))/i
That's probably better so they can't place php at the end of the document (as PHP doesn't actually require a terminating character)
SHJS syntax highlighter for Javascript have files with regular expressions http://shjs.sourceforge.net/lang/ for languages that highlights — You can check how SHJS parse code.
HTMLPurifier is the recommended tool for cleaning up HTML. And as luck has it, it also incudes CSSTidy and can sanitize CSS as well.
... that there is not PHP code or SQL Injection or whatever.
You are basing your question on a wrong premise. While HTML can be cleaned, this is no safeguard against other exploitabilies. PHP "tags" are most likely to be filtered out. If you are doing something other weird (include-ing or eval-ing the content partially), that's no real help.
And SQL exploits can only be prevented by meticously using the proper database escape functions. There is no magic solution to that.
Yes. htmlpurifier is a good tool to remove malicious scripts and validate your HTML. Don't think it does CSS though. Apparently it works with CSS too. Thanks Briedis.
Ok thanks you all.
actually, i realize that I needed a human validation. Users can post HTML + CSS, I can verify in PHP that the langage & the syntax are correct, but it doesn't avoid people to post iframe, html redirection, or big black div that take all the screen.
:-)
I want to display on screen data send by the user,
remembering it can contain dangerous code, it is the best to clean this data with html entities.
Is there a better way to do html entities, besides this:
$name = clean($name, 40);
$email = clean($email, 40);
$comment = clean($comment, 40);
and this:
$data = array("name", "email," "comment")
function confHtmlEnt($data)
{
return htmlentities($data, ENT_QUOTES, 'UTF-8');
}
$cleanPost = array_map('confHtmlEnt', $_POST);
if so, how, and how does my wannabe structure
for html entities look?
Thank you for not flaming the newb :-).
"Clean POST", the only problem is you might not know in what context will your data appear. I have a Chat server now that works via browser client and a desktop client and both need data in a different way. So make sure you save the data as "raw" as possible into the DB and then worry about filtering it on output.
Do not encode everything in $_POST/$_GET. HTML-escaping is an output-encoding issue, not an input-checking one.
Call htmlentities (or, usually better, htmlspecialchars) only at the point where you're taking some plain text and concatenating or echoing it into an HTML page. That applies whether the text you are using comes from a submitted parameter, or from the database, or somewhere else completely. Call mysql_real_escape_string only at the point you insert plain text into an SQL string literal.
It's tempting to shove all that escaping stuff in its own box at the top of the script and then forget about it. But text preparation really doesn't work like that, and if you pretend it does you'll find your database irreparably full of double-encoded crud, backslashes on your HTML page and security holes you didn't spot because you were taking data from a source other than the (encoded) parameters.
You can make the burden of remembering to mysql_real_escape_string go away by using mysqli's parameterised queries or another higher-level data access layer. You can make the burden of typing htmlspecialchars every time less bothersome by defining a shorter-named function for it, eg.:
<?php
function h($s) {
echo(htmlspecialchars($s, ENT_QUOTES));
}
?>
<h1> Blah blah </h1>
<p>
Blah blah <?php h($title); ?> blah.
</p>
or using a different templating engine that encodes HTML by default.
If you wish to convert the five special HTML characters to their equivalent entities, use the following method:
function filter_HTML($mixed)
{
return is_array($mixed)
? array_map('filter_HTML',$mixed)
: htmlspecialchars($mixed,ENT_QUOTES);
}
That would work for both UTF-8 or single-byte encoded string.
But if the string is UTF-8 encoded, make sure to filter out any invalid characters sequence, prior to using the filter_HTML() function:
function make_valid_UTF8($str)
{
return iconv('UTF-8','UTF-8//IGNORE',$str)
}
Also see: http://www.phpwact.org/php/i18n/charsets#character_sets_character_encoding_issues
You need to clean every element bevor displaying it. I do it usually with a function and an array like your secound example.
If you use a framework with a template engine, there is quite likely a possibility to auto-encode strings. Apart from that, what's simpler than calling a function and getting the entity-"encoded" string back?
Check out the filter libraries in php, in particular filter_input_array.
filter_input_array(INPUT_POST, FILTER_SANITIZE_SPECIAL_CHARS);
I am using wmd markdown editor on a project and had a question:
When I post the form containing the markdown text area, it (as expected) posts html to the server. However, say upon server-side validation something fails and I need to send the user back to edit their entry, is there anyway to refill the textarea with just the markdown and not the html? Since as I have it set up, the server only has access to the post data (which is in the form of html) so I can't seem to think of a way to do this. Any ideas? Preferably a non-javascript based solution.
Update: I found an html to markdown converter called markdownify. I guess this might be the best solution for displaying the markdown back to the user...any better alternatives are welcome!
Update 2: I found this post on SO and I guess there is an option to send the data to the server as markdown instead of html. Are there any downsides to simply storing the data as markdown in the database? What about displaying it back to the user (outside of an editor)? Maybe it would be best to post both versions (html AND markdown) to the server...
SOLVED: I can simply use php markdown to convert the markdown to html serverside.
I would suggest that you simply send and store the text as Markdown. This seems to be what you have settled on already. IMO, storing the text as Markdown will be better because you can safely strip all HTML tags out without worrying about loss of formatting - this makes your code safer, because it will be harder to use a XSS attack (although it may still be possible though - I am only saying that this part will be safer).
One thing to consider is that WMD appears to have certain different edge cases from certain server-side Markdown implementations. I've definitely seen some quirks in the previews here that have shown up differently after submission (I believe one such case was attempting to escape a backtick surrounded by backticks). By sending the converted preview over the wire, you can ensure that the preview is accurate.
I'm not saying that should make your decision, but it's something to consider.
Try out Pandoc. It's a little more comprehensive and reliable than Markdownify.
The HTML you are seeing is just a preview, so it's not a good idea to store that in the database as you will run into issues when you try to edit. It's also not a good idea to store both versions (markdown and HTML) as the HTML is just an interpretation and you will have the same problems of editing and keeping both versions in synch.
So the best idea is to store the markdown in the db and then convert it server side before displaying.
You can use PHP Markdown for this purpose. However this is not 100% perfect conversion of what you are seeing on the javascript side and may need some tweaking.
The version that the Stack Exchange network is using is a C# implementation and there should be a python implementation you downloaded with the version of wmd you have.
The one thing I tweaked was the way new lines were rendered so I changed this in markdown.php to convert some new lines into <br> starting from line 626 in the version I have:
var $span_gamut = array(
#
# These are all the transformations that occur *within* block-level
# tags like paragraphs, headers, and list items.
#
# Process character escapes, code spans, and inline HTML
# in one shot.
"parseSpan" => -30,
# Process anchor and image tags. Images must come first,
# because ![foo][f] looks like an anchor.
"doImages" => 10,
"doAnchors" => 20,
# Make links out of things like `<http://example.com/>`
# Must come after doAnchors, because you can use < and >
# delimiters in inline links like [this](<url>).
"doAutoLinks" => 30,
"encodeAmpsAndAngles" => 40,
"doItalicsAndBold" => 50,
"doHardBreaks" => 60,
"doNewLines" => 70,
);
function runSpanGamut($text) {
#
# Run span gamut tranformations.
#
foreach ($this->span_gamut as $method => $priority) {
$text = $this->$method($text);
}
return $text;
}
function doNewLines($text) {
return nl2br($text);
}