Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things

XSS protection in CGI::Application

by srdst13 (Pilgrim)
on Mar 02, 2010 at 19:24 UTC ( #826236=perlquestion: print w/replies, xml ) Need Help??
srdst13 has asked for the wisdom of the Perl Monks concerning the following question:

I have an old application that I have recently resurrected. The application is CGI::Application based. After our security team scanned the app, a single parameter was noted to be problematic. If the runmode parameter is specified as a non-existing runmode, then the application generates a run-time error and dumps the error--not a problem except if the runmode parameter was specified to have malicious javascript or something else like that. That code is also dumped as part of the error. I have tried to use the error_mode specification to return a custom error page, but it appears that the header that is sent specifies the content-type as "httpd/unix-directory" despite my setting the content-type in my setup subroutine:


I am running this all as a mod_perl 2 handler under apache and I have taint checking on. What am I missing here?

The safest thing to do here is probably to url-escape or otherwise scrub the parameters coming in, but I haven't figured out a convenient way to do that in the CGI::Application framework. Is there a standard way of doing this type of thing?


Replies are listed 'Best First'.
Re: XSS protection in CGI::Application
by skx (Parson) on Mar 02, 2010 at 19:30 UTC

    The way I'd solve this is to explicitly catch an unknown mode via:

    my $self = shift; $self->run_modes( # default 'index' => 'index', # user's tag cloud 'tag_cloud' => 'tag_cloud', 'edit_tags' => 'edit_tags', 'tag_find' => 'tag_find', .. # called on unknown mode. 'AUTOLOAD' => 'unknown_mode', );

    In your unknown mode you can then handle it as you wish - without echoing the mode back to the client and potentially allowing an XSS attack.

    My own method is generally:

    sub unknown_mode { my ( $self, $requested ) = (@_); my $q = $self->query(); my $session = $self->param('session'); my $username = $session->param('logged_in'); $requested = HTML::Entities::encode_entities($requested); if ( defined($username) && length($username) ) { return "<p>unknown mode '$requested' for logged in user $usern +ame</p>"; } else { return "<p>Unknown mode '$requested' for anonymous user.</p>"; } }

    Obviously the username section is specific to the sites I design .. but the idea of handling the unknown mode yourself should be simple enough to understand?


      This worked as expected. Thanks for the help.


Re: XSS protection in CGI::Application
by jaldhar (Vicar) on Mar 02, 2010 at 20:04 UTC

    To change the content-type, do this:

    $self->header_add(content_type => 'text/html');

    However I agree with skx about using AUTOLOAD for this purpose.


Re: XSS protection in CGI::Application
by Anonymous Monk on Mar 03, 2010 at 00:27 UTC
    -not a problem except if the runmode parameter was specified to have malicious javascript or something else like that.

    If CGI::Application or your subclass aren't properly escaping variable parts of error messages (runmode), that is a bug that needs to be fixed ( $self->query->escapeHTML($rm) ).

    What am I missing here?

    You seem to be using the query object to set headers which isn't the documented way to do it (Probably because of bad advice from CGI::Application::Plugin::Apache).

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://826236]
Approved by marto
Front-paged by Old_Gray_Bear
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (3)
As of 2018-07-21 21:46 GMT
Find Nodes?
    Voting Booth?
    It has been suggested to rename Perl 6 in order to boost its marketing potential. Which name would you prefer?

    Results (450 votes). Check out past polls.