X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FCatalyst%2FRequest.pm;h=0fe34b0b4a72297648840c78d2609b7ceef43be4;hb=c017b11bf96db335cf4efce1808d56d13651b10a;hp=7b41cfebcb0b0fe1036bcea5f6856fd16acffbd6;hpb=b9d96e27325fd2b5bc7ff2bd28e5c96675b42c7f;p=catagits%2FCatalyst-Runtime.git diff --git a/lib/Catalyst/Request.pm b/lib/Catalyst/Request.pm index 7b41cfe..0fe34b0 100644 --- a/lib/Catalyst/Request.pm +++ b/lib/Catalyst/Request.pm @@ -312,7 +312,7 @@ sub prepare_body_chunk { } sub prepare_body_parameters { - my ( $self ) = @_; + my ( $self, $c ) = @_; $self->prepare_body if ! $self->_has_body; @@ -320,9 +320,29 @@ sub prepare_body_parameters { return $self->_use_hash_multivalue ? Hash::MultiValue->new : {}; } + my $params = $self->_body->param; + + # If we have an encoding configured (like UTF-8) in general we expect a client + # to POST with the encoding we fufilled the request in. Otherwise don't do any + # encoding (good change wide chars could be in HTML entity style llike the old + # days -JNAP + + # so, now that HTTP::Body prepared the body params, we gotta 'walk' the structure + # and do any needed decoding. + + # This only does something if the encoding is set via the encoding param. Remember + # this is assuming the client is not bad and responds with what you provided. In + # general you can just use utf8 and get away with it. + # + # I need to see if $c is here since this also doubles as a builder for the object :( + + if($c and $c->encoding) { + $params = $c->_handle_unicode_decoding($params); + } + return $self->_use_hash_multivalue ? - Hash::MultiValue->from_mixed($self->_body->param) : - $self->_body->param; + Hash::MultiValue->from_mixed($params) : + $params; } sub prepare_connection { @@ -636,6 +656,56 @@ If multiple C parameters are provided this code might corrupt data or cause a hash initialization error. For a more straightforward interface see C<< $c->req->parameters >>. +B Interfaces like this, which are based on L and the C method +are now known to cause demonstrated exploits. It is highly recommended that you +avoid using this method, and migrate existing code away from it. Here's the +whitepaper of the exploit: + +L + +Basically this is an exploit that takes advantage of how L<\param> will do one thing +in scalar context and another thing in list context. This is combined with how Perl +chooses to deal with duplicate keys in a hash definition by overwriting the value of +existing keys with a new value if the same key shows up again. Generally you will be +vulnerale to this exploit if you are using this method in a direct assignment in a +hash, such as with a L create statement. For example, if you have +parameters like: + + user?user=123&foo=a&foo=user&foo=456 + +You could end up with extra parameters injected into your method calls: + + $c->model('User')->create({ + user => $c->req->param('user'), + foo => $c->req->param('foo'), + }); + +Which would look like: + + $c->model('User')->create({ + user => 123, + foo => qw(a user 456), + }); + +(or to be absolutely clear if you are not seeing it): + + $c->model('User')->create({ + user => 456, + foo => 'a', + }); + +Possible remediations include scrubbing your parameters with a form validator like +L or being careful to force scalar context using the scalar +keyword: + + $c->model('User')->create({ + user => scalar($c->req->param('user')), + foo => scalar($c->req->param('foo')), + }); + +Upcoming versions of L will disable this interface by default and require +you to positively enable it should you require it for backwards compatibility reasons. + =cut sub param {