in reply to Back to acceptable untainted characters

I have been running client-side validation via an external .js file, but I read somewhere that 's a bad idea.

The main problem would be that people can set their browsers to ignore javascript, which means that your client-side validation does not execute, and anything goes.

My applications are HTML forms that are parsed and either send an e-mail with the data printed in the e-mail, or inserted into a MySQL db for later display via HTML::Template.

Here, it's not so much a question of what users type, but rather how you handle the data they send you. There are "safe" and "unsafe" methods of sending emails and inserting/updating database content.

In general terms, the difference is that the unsafe methods involve passing the user-supplied text to a process (a shell, mailer or db engine) as part of a single command or instruction string, so that the process will have the "opportunity" to parse, evaluate and try to execute the user-supplied string; usually the bad things that happen are innocent "mistakes" -- the user includes one or more of: single-quote, semi-colon, new-line, parentheses and/or other brackets, etc, which end up being "meaningful" to the process in unintended ways and cause the process to fail. But worst case would be someone who actually guesses the vulnerability and provides a parsable, executable and malicious string.

Safe methods, in contrast, run the mailer, shell or db engine with discrete arguments/parameters/strings. Instructions to the process (insert/update, email address, or whatever) are provided separately from user-supplied text ("free-form data entry"), and this latter stuff is therefore passed straight through (into the db, mail message or whatever) without trying to do further interpretation of its content, which is exactly what you want.

So in the case of passing content to MySQL, just make sure the SQL statement is prepared using the "?" placeholders for values to be searched for or written into the table, and pass the user-supplied text to DBI's execute method -- no worries about quote characters or anything when you do it this way.

I'm less conversant with mailer modules, but I think Mail::Mailer is a reasonably good tool that allows you to control how the mail header is assembled, and to supply the message body (user-supplied text) as a separate scalar value, keeping it safely away from any sort of executable context; search for "Mail" on the CPAN for a wide range of alternatives and supplements. (You might still want to "filter" user-supplied content, to watch out for things that look like base64-encoded virus attachments or whatever, but in your case, this is probably not really a thing to worry about.)

Trying to do shell operations based on user input is a rarer and trickier thing -- in general, this is not done, unless with a very limited scope; e.g. the CGI script itself has a limited set of specific shell operations it is able to perform, based on, say, filenames or other information present on the server, and user input is used only to decide which if any of the allowed/possible operations to do.

  • Comment on Re: Back to acceptable untainted characters