My PHP scripts recieves information (from a user submitted form) and sends it (almost) straight away as an email. What kind of sainitization should I do on the data?
I want to know exactly which PHP function to use to sanitize the data.
You need to read up on email injection. Take a look here:
http://www.damonkohler.com/2008/12/email-injection.html
Have a look at PHP Data Filtering. There are a lots of built in php functions which can be used for data validation and sanitization.
You'll want to:
validate the email address
sanitize (or not) HTML tags to avoid XSS attacks
sanitize the e-mail contents to avoid e-mail header injections
Related
This question already has answers here:
How to prevent XSS with HTML/PHP?
(9 answers)
Closed 2 years ago.
I need to implement a logic where the user sends some content (it can be just a string but also can be part of HTML markup), we store that info to a database, and at some period of time, we replace the base email template placeholder with that data and sending that email.
And there is a chance that data sent by the user can contain some HTML/XSS injections. How can we efficiently validate the data before storing it to the database???
Against XSS injection you can use htmlspecialchars in general, however, we know that you intend to allow HTML to be sent, so your validation will have to check against the presence of <script. If that's present in your input, then you should render it invalid. Now, there is another way of providing Javascript in HTML, that is, inline Javascript, being the values of onclick, onhover and so on. I would advise to make sure that, if such an event handler is present between the < and > of a tag, then simply render the input invalid.
Now, you have also mentioned HTML injection, that is, some HTML is injected which causes undesirable behavior. However, due to the fact that you welcome HTML in the input, distinguishing between "bad HTML injection" and "good HTML injection" can be decided by:
checking the validity of the html you get
checking against any problems that the HTML might cause in your application
The first criteria is easy to determine, read the link, the second criteria depends on business logic. That HTML might ruin your design, for example, if there are some expectations for it, so you need to lay down the foundations of what you expect in terms of HTML.
And also, since we are speaking about security, make sure you protect your database against SQL injection as well.
I understand about mysql_real_escape_string and such, But what about when i am just sending an email?
So I have form, and a textbox, is there any vulnerabilities in just directly emailing the $_POST data to a user? I guess they wouldnt be able to execute any PHP.. or can they if they run it from a web address? I am not sure.
If it is being sent directly to an email then it will be fine. If it is being stored in a database to be displayed on an administrator page such as a helpdesk, etc. then it will need to be escaped for both html output and mysql. You can escape mysql using a number of functions:
If using PDO then use prepare statement :
http://php.net/manual/en/pdo.prepare.php
Otherwise I would use :
http://php.net/manual/en/mysqli.real-escape-string.php
That said because Emails can contain HTML, if you don't want to receive emails that people have put bogus HTML in such as <blink> (Which is really annoying) then you can use htmlspecialchars() : http://php.net/manual/en/function.htmlspecialchars.php
If you are worried about Javascript in emails then using htmlspecialchars() noted above will escape this also.
The problem is don't trust a user input. The biggest problem is, when you set the Email adress or BCC from your POST variable. That any email address can be set over the Request.
But its possible to send links or something else to user over your form. For this you should implement a captcha. That a bot cannot send your form with defined values to anyone.
A last solution is a hidden text field in your form. You can hide them with CSS. When the field is not empty you know that a bot has filled them.
But i think its good when you escape your POST vars with htmlspecialchars()
So there are a lot of possibilities to secure a form. You should use not only one of them and trust the user.
I have a script that registers users based on their user input. This uses prepared statements plus whitelists to prevent sql injection. But I am struggling to understand the prevention of XSS.
From what I understand, you only need to prevent XSS if you are outputting HTML onto the page? What does this mean???
Im guessing that with this register page it doesn't apply because I am not outputting HTML to the web page? Is that right?
If I was to prevent XSS, do I use htmlspecialchars?
Generally correct, if you are having any returned values show up on the page, or if you are inserting information into the database for later retrieval and display (like user profile information) you will want to use htmlspecialchars.
For me, when I do my user registration, if they fail to enter a correct value in an input field, I redisplay the page with the values they entered. In this case, I have it encoded with htmlspecialchars.
If at any point ever, you plan on redisplaying the information from the DB into a webpage (as mentioned with profiles and the like) you should use htmlspecialchars.
Better safe than sorry I always say - never trust user input
Basically, XSS happens when you are taking the user's input un-sanitized and display in your webpage.
For example: A user inputs
<script>alert('hello you are hacked');</script>
In a text box, and you show this in your webpage after it is registered like
Hello, $username
This suddenly gets turned into
Hello, <script>alert('hello you are hacked');</script>
This is one of the form of XSS
One of a effiecient way to prevent XSS is like this
echo htmlspecialchars($varname, ENT_QUOTES, 'UTF-8');
From what I understand, you only need to prevent XSS if you are
outputting HTML onto the page? What does this mean???
XSS is an attack carried out by the server outputting HTML (in practice, Javascript) to the client when it did not mean to do so (and obviously when that HTML was specially crafted and supplied by a hostile user).
Im guessing that with this register page it doesn't apply because I am
not outputting HTML to the web page? Is that right?
If you are not outputting anything that comes from user input you are safe.
If I was to prevent XSS, do I use htmlspecialchars?
Yes, that is sufficient.
I am passing a textarea input boxs' contents via POST to my php file from html (no javascript allowed).
I then use simplexml to get the feed at the url the user entered.
Unfortunately, the user can enter anything into the textarea. Which I am told is dangerous.
What is the recommended way to clean and secure the POST contents using PHP to get them ready and safe for the simplexml procedure?
(basically, to be sure they are not malicious and check they are a valid url)
Content inside a $_POST array are strings, so there's nothing ineherently unsafe there.
User enters php code? It surely won't be executed, so no problem here (this, among many others, is a reason not to use such things as eval()). So whatever php function or command he writes it will be read as a simple string, and string are no harmful whatever they contain.
User enters malicious javascript? Still no problem, as javascript inside php, or inside a database for what that matters, is pretty useless since it needs a browser to execute.
This leads to the real issue: user supplied contents needs to be "sanitized" only right before passing it to the target medium. If you're going to feed a database , use the escaping tools provided by your engine. If you're going to output it on the webpage, that's when you need to sanitize from malicious XSS attacks.
Sanitizing a POST array per se , before actually doing anything with its content, is wrong as you never know for sure when and where that content needs to be used; so don't even think to use strip_tags() or analogue functions that comes to your mind right after you get the POST value, but pass it as is and add the necessary escaping/sanitizing just when needed.
What you actually need to do, then, you only know, so act accordingly
Which I am told is dangerous.
it is wrong.
What is the recommended way to clean and secure the POST contents
it am afraid there is nothing to secure
What's a method to sanitize PHP POST data for passing to a mail function? (I prefer a method that's not part of the mysql_function() family of functions.)
I take the data, sanitize it, print it back to the user and send it in an email to a preset address.
EDIT:
I'm just sending the email to our email address so we can send out a mailing to the address in the email.
Have you looked at the filter functions
e.g http://www.php.net/manual/en/function.filter-var.php
Since you're printing it back to the user, you need to escape any HTML content.
strip_tags()
and
html_special_chars() are quite useful in filtering the message content, especially if you're using html messages.
See also:
How to sanitze user input in PHP before mailing?
which mentions doing a find & replace on newlines that could allow injecting content into the mail headers.
As you're using a pre-set mail address the risk is reduced, but the subject field is still vulnerable.
Sanitizing for an e-mail would be equivalent to sanitizing for HTML output. I see some suggestions on SO for HTML Purifier.