View Full Version : Sanitizing User Input with PHP
Modred
04-21-2006, 2:10 AM
I'm developing a page that will allow a user to share a page on a website with another person. What I have is the link on the page to be shared will pass the filename in the URL, and on the sharing page I can grab the filename with $_GET. The user then fills in a short message, their name, and the email to send it to. When the user clicks submit, some javascript will check that the email is in the right format, name was provided, etc, and then submit the form using the POST method. The form submits to the same php page, which then uses $_POST to access the contents of the form, formats the email, and sends it.
So far, so good. Now the ISP that hosts the site I'm making this for warned that spammers could use a page like this to spam, so I would need to sanitize any user input and ensure as much as possible that no one could hijack it for spam.
And that brings me here, and I want to know if the solution I've come up with is extensive enough. Since several people here have more experience with PHP (and programming on the web, in general) than I, I want to get an opinion or two before implementing this code.
My options, as I see it are to do the following, in some combination:
1) Javascript on the HTML form: Check the contents and don't submit the form if it has bad stuff in it.
2) PHP: Check all of my data after I've retrieved it from $_POST and don't send the email if it has bad stuff in it.
I had a third idea, also implemented on the server side, but can't recall it at the moment. I'm thinking #1 might not even be needed, since a smart hijacker would not even use my form to start with and would get around that control. I just feel a little uncomfortable only having one safeguard (option #2). What I'm really getting at, could a hijacker possible gain access to my variables any way besides posting data to them?
This is pretty much my "learn PHP" project, and I don't want to be blindsided by something I didn't even know existed.
Graeme
04-21-2006, 7:39 AM
I think the person that hosts the site may be more concerned with people spamming the boards with countless messages using a bot. In other words, you may want to do some human checking. The easiest way to get around this is to use a jargled image and have users post the contents of the image (like Warboards does for registration). Additionally, you could use this beta auth test:
http://www.kittenauth.com/ka.php
You have to click three kittens from the nine images before you can move on. See here:http://www.thepcspy.com/kittenauthtest
for more info.
Modred
04-21-2006, 12:26 PM
Alright, thanks for the suggestion. I didn't really catch from the guy that they might expect something like that, but it isn't such a large jump from passing a huge list of recipients via post to writing a bot that passes them one at a time. (Remember, this is sending emails, not a message board)
If I were to put in a human check, should I still do the data checking, just to be safe?
Just use some basic javascript to text for certain html tags, like embed or what have you.
<script type="text/javascript">
function stripHTML(){
var re= /<\S[^><]*>/g
for (i=0; i<arguments.length; i++)
arguments[i].value=arguments[i].value.replace(re, "")
}
</script>
quick google found that. I assume you could just;
onSubmit="stripHTML(comments, email, name)"
or some such.
yay for google.
-Neo
Modred
04-21-2006, 3:16 PM
Just use some basic javascript to text for certain html tags, like embed or what have you.
The code itself isn't the problem (I can write it myself), I'm just trying to make sure I get all the bases covered and don't leave an opening without realizing it. But as I said before, if I were to only use javascript to strip out HTML, or something similar, what stops someone else from making their own page and sending it it to my php script (with method=POST) to get around the javascript?
So I'd still need to do some checking with php. The only danger left that I see is something like what Grame pointed out, where a bot could send individual requests instead of trying to slip a large number of email addresses in at once. Is that danger prominent enough to warrant putting up security system like an image with text that must be retyped in a validation box?
just trim(htmlspecialchars()) the user input and you are safe.
Markpyro
04-21-2006, 3:43 PM
at least from harmful functions, but that still doesnt mean it couldn't be spammed by a bot >.>
its quite unlikely that spambots come out of nowhere -- they need usually be configured per-site to work. anyway, to thwart them, there is several kinds of "human detection" available, for example a list of VERY EASY and pointless questions and answers to them -- ask a question for every post being made (such as "What color is a white horse?" -> "white"). with a large enough collection of questions:answers, not many evildoer wants to go through them. make sure the user is able to cycle those questions couple of times in case (s)he cannot answer it for some reason.
The code itself isn't the problem (I can write it myself), I'm just trying to make sure I get all the bases covered and don't leave an opening without realizing it. But as I said before, if I were to only use javascript to strip out HTML, or something similar, what stops someone else from making their own page and sending it it to my php script (with method=POST) to get around the javascript?
So I'd still need to do some checking with php. The only danger left that I see is something like what Grame pointed out, where a bot could send individual requests instead of trying to slip a large number of email addresses in at once. Is that danger prominent enough to warrant putting up security system like an image with text that must be retyped in a validation box?
Couldn't you just restrict access via htaccess or something so that the script will only run with input from your own site? Or maybe via the script itself? Set it up so that it will reject outside posts?
-Neo
Any input you check in JavaScript must be double-checked in PHP. JavaScript makes things nicer for legitimate users, but really isn't good for keeping the unwanted stuff out. JavaScript is client-side code and can be easily circumvented. Good PHP should fix most problems regarding bad input (unwanted HTML, bad email addresses, etc.)
As for spam bots, unfortunatly there is no easy way to check where a form's input came from. htaccess really won't help here, and the only other way is checking the referrer string using PHP, but that can be faked too, to look like the form was submitted on your site, even though it wasn't.
One option, and perhaps the easiest, is don't allow custom messages at all. Spammers wouldn't bother if they can't control both the content and the recipient. If that's not an option, here's what I'd do. First of all, log everything that's sent to a text file or database, including the sender's IP address. Check the IP on each message against the database or log file and block them if they've sent a lot. Keep an eye on the log and set something up to wipe it every day or week or so. If you can implement that, I think you shouldn't have to worry about spammers. Just do sufficient checking of the message and email address in the PHP code (make sure it's not too long, doesn't have nasty characters, etc.) and you should be set. Oh, and obviously add your own text to the message as well, to let the recipient know where it came from and why, and where to report any abuse.
A last resort would be to implement a captcha (http://en.wikipedia.org/wiki/CAPTCHA) system, but I think you'll be fine without it.
Good luck, and let us know if you have any questions with the PHP :)
vBulletin® v3.7.2, Copyright ©2000-2008, Jelsoft Enterprises Ltd.