Skip to content

Commit

Permalink
Merge pull request #2981 from movabletype/fix/mtc-29494-400-bad-reque…
Browse files Browse the repository at this point in the history
…st-mt7x

[MT7.x]If PSGI application initialization fails, return 400 Bad Request. MTC-29494
  • Loading branch information
usualoma committed May 10, 2024
2 parents 9dfc78f + 0080e08 commit aa69541
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 4 deletions.
9 changes: 8 additions & 1 deletion lib/MT/App.pm
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use base qw( MT );
use File::Spec;
use MT::Request;
use MT::Util qw( encode_html encode_url is_valid_email is_url );
use MT::Util::RequestError qw( parse_init_cgi_error );
use MT::I18N;
use MT::Util::Encode;

Expand Down Expand Up @@ -1140,7 +1141,13 @@ sub init_request {
}
require CGI;
$CGI::POST_MAX = $app->config->CGIMaxUpload;
$app->{query} = CGI->new( $app->{no_read_body} ? {} : () );
$app->{query} = eval { CGI->new( $app->{no_read_body} ? {} : () ) };
if (my $err = $@) {
my $res = parse_init_cgi_error($err);
$app->{query} = CGI->new( {} );
$app->response_code($res->{code});
die $res->{message};
}
}
}
$app->init_query();
Expand Down
2 changes: 1 addition & 1 deletion lib/MT/Bootstrap.pm
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ sub import {
}
my $page = $app->show_error(\%param)
or die $app->errstr;
print "Content-Type: text/html; charset=$charset\n\n";
$app->send_http_header("text/html; charset=$charset");
$app->print_encode($page);
exit;
};
Expand Down
13 changes: 11 additions & 2 deletions lib/MT/PSGI.pm
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use parent qw(Plack::Component);
use Plack::Util::Accessor qw(script application _app);
use MT;
use MT::Component;
use MT::Util::RequestError qw(parse_init_cgi_error);
use Carp;
use FindBin;
use CGI::PSGI;
Expand Down Expand Up @@ -55,7 +56,11 @@ my $mt_app = sub {
return sub {
my $env = shift;
eval "require $app_class";
my $cgi = CGI::PSGI->new($env);
my $cgi = eval { CGI::PSGI->new($env) };
if (my $err = $@) {
my $res = parse_init_cgi_error($err);
return [$res->{code}, [], [$res->{message}]];
}
local *ENV = { %ENV, %$env }; # some MT::App method needs this
my $app = $app_class->new(CGIObject => $cgi);
delete $app->{init_request};
Expand Down Expand Up @@ -85,7 +90,11 @@ my $mt_app_streaming = sub {
return sub {
my $env = shift;
eval "require $app_class";
my $cgi = CGI::PSGI->new($env);
my $cgi = eval { CGI::PSGI->new($env) };
if (my $err = $@) {
my $res = parse_init_cgi_error($err);
return [$res->{code}, [], [$res->{message}]];
}
local *ENV = { %ENV, %$env }; # some MT::App method needs this
my $app = $app_class->new(CGIObject => $cgi);
delete $app->{init_request};
Expand Down
52 changes: 52 additions & 0 deletions lib/MT/Util/RequestError.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Movable Type (r) (C) Six Apart Ltd. All Rights Reserved.
# This code cannot be redistributed without permission from www.sixapart.com.
# For more information, consult your Movable Type license.
#
package MT::Util::RequestError;

use strict;
use warnings;
use Exporter qw(import);

our @EXPORT_OK = qw(parse_init_cgi_error);

sub parse_init_cgi_error {
my ($err) = shift;

# CGI->new() throws an error if it fails to parse a POST request.
# If the boundary is invalid, etc., the error message contains "malformed", so 400 is returned.
# In other cases, return 500, most likely due to a bug in the web server or application.
# MTC-29494
$err =~ m/malformed/i
? {
code => 400,
message => "Bad Request: $err",
}
: {
code => 500,
message => 'Internal Server Error',
};
}

1;
__END__
=head1 NAME
MT::Util::RequestError - Provide utility functions for request error
=head1 METHODS
=head2 parse_init_cgi_error($error)
Parse the error that occurred when `CGI->new` was called.
Return the response code and message for the error.
Example:
my $cgi = eval { CGI->new };
if (my $error = $@) {
my $result = MT::Util::RequestError::parse_init_cgi_error($error);
$mt->response_code($result->{code});
$mt->print($result->{message});
}
1 change: 1 addition & 0 deletions t/00-compile.t
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ use_ok('MT::FileMgr');
use_ok('MT::FileMgr::Local');
use_ok('MT::FileMgr::FTP');
use_ok('MT::ParamValidator');
use_ok('MT::Util::RequestError');

# MT7
use_ok('MT::App::Search::ContentData');
Expand Down

0 comments on commit aa69541

Please sign in to comment.