Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Escaping special characters

by tiny_monk (Sexton)
on Aug 12, 2015 at 01:15 UTC ( [id://1138250]=perlquestion: print w/replies, xml ) Need Help??

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

Hello Monks. I am just starting to learn the language of Perl. I came to your monastery in order to seek an answer to a question to which I haven't satisfactorily found an answer yet. I am currently finishing a form. I am at that point wherein I am learning how to sanitize the user's input. The code goes like this:

#!/usr/bin/perl use strict; use warnings; use diagnostics; use CGI; my $query = CGI->new; my $input = $query->param('team_name'); $input =~ s/[^a-zA-Z0-9\s!]/_/g; $input =~ s/!/!/g; # Escaping ! for HTML $input =~ s/!/\!/g; # Escaping ! for Perl

My goal is to escape the occurrences of exclamation symbols (!) that will be supplied by the user so that they are not interpreted as part of the HTML and Perl code. Some of you may probably recommend to use a module such as HTML::Entities and the likes. However, at this point, I just want to gain an understanding on how escaping works for HTML and Perl. If I use the above code, would it be safe to do so. I guess my real questions are: is it possible to escape the same special character for both Perl and HTML at the same time? would escaping ! for Perl cancel out the earlier escaping of ! for HTML - vice-versa? I'd very much appreciate your help on this topic. Thank you.

Replies are listed 'Best First'.
Re: Escaping special characters
by james28909 (Deacon) on Aug 12, 2015 at 01:41 UTC
    I think that the way you are trying to do it, it is modifying the original string each time. I think you should copy the result of the regex into a variable of its own like:
    use strict; use warnings; my $string = '123!'; my $new_string = $string =~ s/!/4/r; print "original - $string\nreplacement - $new_string";
    This way you leave the original string untouched and can modify it 20 different ways from tuesday if needed :)
      my $new_string = $string =~ s/!/4/r;

      Note that the  /r substitution modifier is only available with Perl versions 5.14+. Prior to that version, one can use the following trick (and using the  /g modifier is handy also):

      c:\@Work\Perl\monks>perl -wMstrict -le "print 'perl version: ', $]; ;; my $string = '123! 987!'; (my $new_string = $string) =~ s/!/bang/g; print qq{original '$string' new string '$new_string'}; " perl version: 5.008009 original '123! 987!' new string '123bang 987bang'


      Give a man a fish:  <%-(-(-(-<

Re: Escaping special characters
by aitap (Curate) on Aug 12, 2015 at 08:42 UTC
    to escape the occurrences of exclamation symbols (!) that will be supplied by the user so that they are not interpreted as part of the HTML and Perl code.
    First of all, I'm not sure why do you need to escape exclamation symbols. Are you going to feed user input to an HTML browser, to the Perl interpeter, or both? On the one hand, ! does not have a special meaning in HTML, so when you feed text with !s to a browser, you can leave them unchanged (but run the input through a proper HTML escaping function from a well-tested CPAN module). On the other hand, to make ! have no special meaning (negation operator) in Perl (ETA: special meaning in Perl source code, not inside Perl strings), you'll have to quote it (!"!", but now you have to do something with a string) or to comment it out (!# !, Perl will completely ignore the comment). \! won't help: it's "return the reference to the result of negation", not "verbatim exclamation mark". And feeding untrusted user input to Perl is not a good thing to do anyway. Good thing that you can safely work with arbitrary strings without escaping them in Perl unless you eval them (or feed to shell, see also: perlsec, Safe) What exactly do you really need to do with $query->param('team_name')?
Re: Escaping special characters
by crusty_collins (Friar) on Aug 12, 2015 at 15:30 UTC
    Why don't you use quotemeta ?

    Code below

    use strict; use warnings; my $sentence = 'The quick brown fox jumped over the lazy dog'; print "$sentence \n"; my $substring = 'The quick.!*?fox'; print "$substring \n"; my $quoted_substring = quotemeta($substring); print "$quoted_substring \n"; $sentence =~ s/quick brown/$quoted_substring/; print "$sentence \n";
Re: Escaping special characters
by tiny_monk (Sexton) on Aug 12, 2015 at 04:28 UTC

        james28909,AnomalousMonk thank you for sharing your thoughts. The methods that you have introduced can be used to escape the HTML metacharacter !. If I escaped the metacharacter ! for perl, using the code below,

        $input =~ s/!/\!/g;

        would it cancel out the effects of the method that you have introduced? Or is it enough to escape the HTML metacharacter ! and not to do anything with the perl metacharacter !? would that be secure enough as not to cause any malicious scripting by the user?

          I personally do not see an exclamation point in Metacharacters but if your just trying to remove the '!' from user input, whether it be Perl or HTML, please take this into consideration:
          use strict; use warnings; while (<DATA>){ print "Perl string - ", my $perl_string = $_ =~ s/!//rg if $_ !~ /<.*? +>/g; print "HTML string - ", my $html_string = $_ =~ s/!//rg if $_ =~ /<.*? +>/g; } __DATA__ 123!!!!!! <p>123!!!!!</p>
          As for the security of your website, I think I will leave that to some professionals ;) Update: Changed link, thanks soonix

    Log In?
    Username:
    Password:

    What's my password?
    Create A New User
    Domain Nodelet?
    Node Status?
    node history
    Node Type: perlquestion [id://1138250]
    Approved by Athanasius
    help
    Chatterbox?
    and the web crawler heard nothing...

    How do I use this?Last hourOther CB clients
    Other Users?
    Others browsing the Monastery: (3)
    As of 2024-04-25 07:34 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      No recent polls found