Sanitize HTML::Mason arguments in the handler?

Go To StackoverFlow.com

1

I'm using HTML::Mason, and after a recent security audit, it was discovered that some of our software is vulnerable to a header injection. Specifically this is related to the session_id argument, which is passed around through GET and POST requests.

I've tried to modify the environment in my handler() method from a custom handler, but the Apache2::RequestRec is already created, so it doesn't pick up the changes.

Is there a good way to sanitize all of the input into HTML::Mason at the handler level?

2012-04-04 20:19
by Jack M.
Ick, the provided guidance for this is surprisingly optimistic. This site provides some additional guidance. Have you tried using <code>HTML::Mason::CGIHandler</code> - MrGomez 2012-04-09 20:48
Can you post a minimal sample of code that doesn't work - benrifkah 2012-04-10 16:25
Yes, I tried HTML::Mason::DGIHandler and it caused issues when used with both POST and GET data. I was able to find a working patch, but I don't find it optimal. I'll post the response shortly - Jack M. 2012-04-11 19:01


1

So I worked this out using HTML::Mason Plugins. This is not the solution I was hoping for, as it does not sanitize the arguments before they are parsed, but after. If there is an exploitable piece of code in the argument parsing, it still may cause problems. This is better than nothing, but it does not feel like a true solution.

Adding Plugins to the ApacheHandler:

my $ah = HTML::Mason::ApacheHandler->new (
    ...
    session_use_cookie          =>  0,
    args_method                 =>  "mod_perl",
    session_args_param          =>  'session_id',
    plugins                     =>  [PolMaker::Plugins::SanitizeArgs->new],
  );

Plugin code: $context->args does most of the heavy lifting. Given the input:

?session_id=c45a0309191691cd5b4714c936d0f9a2&foo=bar&baz=pop

We get the following in $context->args:

['session_id', 'c45a0309191691cd5b4714c936d0f9a2', 'foo', 'bar', 'baz', 'pop']

This also works for POST requests, and follows the same rules as HTML::Mason's normal parsing. The actual plugin looks like this:

package PolMaker::Plugins::SanitizeArgs;
use base qw(HTML::Mason::Plugin);

my %SANITIZE = (      
        "session_id" => 1,
        ## Room for future expansion.
    );

sub start_request_hook { ## Executes once per request.
    my $self = shift;
    my $context = shift;
    my @clean_args;
    my $next = 0;
    foreach my $arg (@{ $context->args } ) {
        if (defined($SANITIZE{$arg})) { 
            $next = 1;
        } elsif ($next > 0) {
            $arg =~ s/[^\w \d\-\.]//g; # Leave words, digits, dashes and periods. 
            $next = 0;
        }
        push @clean_args, $arg;
    }
    @{$context->args} = @clean_args;
}
1;

Again, this option isn't as optimal as I wanted, but it will work. Additions and enhancements to this "solution" would also be welcomed.

2012-04-11 21:17
by Jack M.
Ads