Security Advisories (10)
CPANSA-Mojolicious-2022-03 (2022-12-10)

Mojo::DOM did not correctly parse <script> tags.

CPANSA-Mojolicious-2021-02 (2021-06-01)

Small sessions could be used as part of a brute-force attack to decode the session secret.

CVE-2021-47208 (2021-03-16)

A bug in format detection can potentially be exploited for a DoS attack.

CVE-2018-25100 (2018-02-13)

Mojo::UserAgent::CookieJar leaks old cookies because of the missing host_only flag on empty domain.

CPANSA-Mojolicious-2015-01 (2015-02-02)

Directory traversal on Windows

CPANSA-Mojolicious-2018-03 (2018-05-19)

Mojo::UserAgent was not checking peer SSL certificates by default.

CVE-2020-36829 (2020-11-10)

Mojo::Util secure_compare can leak the string length. By immediately returning when the two strings are not the same length, the function allows an attacker to guess the length of the secret string using timing attacks.

CPANSA-Mojolicious-2018-02 (2018-05-11)

GET requests with embedded backslashes can be used to access local files on Windows hosts

CPANSA-Mojolicious-2014-01 (2014-10-07)

Context sensitivity of method param could lead to parameter injection attacks.

CVE-2024-58134 (2025-05-03)

Mojolicious versions from 0.999922 for Perl uses a hard coded string, or the application's class name, as a HMAC session secret by default. These predictable default secrets can be exploited to forge session cookies. An attacker who knows or guesses the secret could compute valid HMAC signatures for the session cookie, allowing them to tamper with or hijack another user's session.

NAME

Mojolicious::Controller - Controller base class

SYNOPSIS

use Mojo::Base 'Mojolicious::Controller';

DESCRIPTION

Mojolicious::Controller is the base class for your Mojolicious controllers. It is also the default controller class for Mojolicious unless you set controller_class in your application.

ATTRIBUTES

Mojolicious::Controller inherits all attributes from Mojo::Base and implements the following new ones.

app

my $app = $c->app;
$c      = $c->app(Mojolicious->new);

A reference back to the Mojolicious application that dispatched to this controller, defaults to a Mojolicious object.

match

my $m = $c->match;
$c    = $c->match(Mojolicious::Routes::Match->new);

Routes dispatcher results for the current request, defaults to a Mojolicious::Routes::Match object.

tx

my $tx = $c->tx;
$c     = $c->tx(Mojo::Transaction::HTTP->new);

The transaction that is currently being processed, usually a Mojo::Transaction::HTTP or Mojo::Transaction::WebSocket object.

METHODS

Mojolicious::Controller inherits all methods from Mojo::Base and implements the following new ones.

$c         = $c->cookie(foo => 'bar');
$c         = $c->cookie(foo => 'bar', {path => '/'});
my $value  = $c->cookie('foo');
my @values = $c->cookie('foo');

Access request cookie values and create new response cookies.

finish

$c->finish;
$c->finish('Bye!');

Gracefully end WebSocket connection or long poll stream.

flash

my $foo   = $c->flash('foo');
$c        = $c->flash({foo => 'bar'});
$c        = $c->flash(foo => 'bar');

Data storage persistent only for the next request, stored in the session.

on

my $cb = $c->on(finish => sub {...});

Register event with tx, which is usually a Mojo::Transaction::HTTP or Mojo::Transaction::WebSocket object.

# Emitted when the transaction has been finished
$c->on(finish => sub {
  my $c = shift;
  say 'We are done!';
});

# Emitted when new WebSocket messages arrive
$c->on(message => sub {
  my ($c, $message) = @_;
  say "Message: $message";
});

param

my @names = $c->param;
my $foo   = $c->param('foo');
my @foo   = $c->param('foo');
$c        = $c->param(foo => 'ba;r');

Access GET/POST parameters and route captures that are not reserved stash values.

# Only GET parameters
my $foo = $c->req->url->query->param('foo');

# Only GET and POST parameters
my $foo = $c->req->param('foo');

redirect_to

$c = $c->redirect_to('named');
$c = $c->redirect_to('named', foo => 'bar');
$c = $c->redirect_to('/path');
$c = $c->redirect_to('http://127.0.0.1/foo/bar');

Prepare a 302 redirect response, takes the exact same arguments as url_for.

return $c->redirect_to('login') unless $c->session('user');

render

$c->render;
$c->render(controller => 'foo', action => 'bar');
$c->render({controller => 'foo', action => 'bar'});
$c->render(text => 'Hello!');
$c->render(template => 'index');
$c->render(template => 'foo/index');
$c->render(template => 'index', format => 'html', handler => 'epl');
$c->render(handler => 'something');
$c->render('foo/bar');
$c->render('foo/bar', format => 'html');

This is a wrapper around Mojolicious::Renderer exposing pretty much all functionality provided by it. It will set a default template to use based on the controller and action name or fall back to the route name. You can call it with a hash of options which can be preceded by an optional template name.

render_content

my $output = $c->render_content;
my $output = $c->render_content('header');
my $output = $c->render_content(header => 'Hello world!');
my $output = $c->render_content(header => sub { 'Hello world!' });

Contains partial rendered templates, used for the renderers layout and extends features.

render_data

$c->render_data($bits);
$c->render_data($bits, format => 'png');

Render the given content as raw bytes, similar to render_text but data will not be encoded.

render_exception

$c->render_exception('Oops!');
$c->render_exception(Mojo::Exception->new('Oops!'));

Render the exception template exception.$mode.$format.* or exception.$format.* and set the response status code to 500.

render_json

$c->render_json({foo => 'bar'});
$c->render_json([1, 2, -3]);

Render a data structure as JSON.

render_later

$c->render_later;

Disable auto rendering, especially for long polling this can be quite useful.

$c->render_later;
Mojo::IOLoop->timer(2 => sub {
  $c->render(text => 'Delayed by 2 seconds!');
});

render_not_found

$c->render_not_found;
$c->render_not_found($resource);

Render the not found template not_found.$mode.$format.* or not_found.$format.* and set the response status code to 404.

render_partial

my $output = $c->render_partial('menubar');
my $output = $c->render_partial('menubar', format => 'txt');

Same as render but returns the rendered result.

render_static

my $success = $c->render_static('images/logo.png');
my $success = $c->render_static('../lib/MyApp.pm');

Render a static file using Mojolicious::Static relative to the public directory of your application.

render_text

$c->render_text('Hello World!');
$c->render_text('Hello World', layout => 'green');

Render the given content as Perl characters, which will be encoded to bytes. See render_data for an alternative without encoding. Note that this does not change the content type of the response, which is text/html;charset=UTF-8 by default.

$c->render_text('Hello World!', format => 'txt');

rendered

$c = $c->rendered;
$c = $c->rendered(302);

Finalize response and run after_dispatch plugin hook.

req

my $req = $c->req;

Alias for $c->tx->req. Usually refers to a Mojo::Message::Request object.

res

my $res = $c->res;

Alias for $c->tx->res. Usually refers to a Mojo::Message::Response object.

respond_to

$c->respond_to(
  json => sub {...},
  xml  => {text => 'hello!'},
  any  => sub {...}
);

Automatically select best possible representation for resource from Accept request header, format stash value or format GET/POST parameter, defaults to rendering an empty 204 response. Note that this method is EXPERIMENTAL and might change without warning!

$c->respond_to(
  json => sub { $c->render_json({just => 'works'}) },
  xml  => {text => '<just>works</just>'},
  any  => {data => '', status => 204}
);

send_message

$c = $c->send_message('Hi there!');
$c = $c->send_message('Hi there!', sub {...});

Send a message non-blocking via WebSocket, the optional drain callback will be invoked once all data has been written. Note that this method is EXPERIMENTAL and might change without warning!

session

my $session = $c->session;
my $foo     = $c->session('foo');
$c          = $c->session({foo => 'bar'});
$c          = $c->session(foo => 'bar');

Persistent data storage, defaults to using signed cookies. Note that cookies are generally limited to 4096 bytes of data.

$c->session->{foo} = 'bar';
my $foo = $c->session->{foo};
delete $c->session->{foo};
$c         = $c->signed_cookie(foo => 'bar');
$c         = $c->signed_cookie(foo => 'bar', {path => '/'});
my $value  = $c->signed_cookie('foo');
my @values = $c->signed_cookie('foo');

Access signed request cookie values and create new signed response cookies. Cookies failing signature verification will be automatically discarded.

stash

my $stash = $c->stash;
my $foo   = $c->stash('foo');
$c        = $c->stash({foo => 'bar'});
$c        = $c->stash(foo => 'bar');

Non persistent data storage and exchange, application wide default values can be set with "defaults" in Mojolicious.

$c->stash->{foo} = 'bar';
my $foo = $c->stash->{foo};
delete $c->stash->{foo};

ua

my $ua = $c->ua;

Alias for $c->app->ua. Usually refers to a Mojo::UserAgent object.

# Blocking
my $tx = $c->ua->get('http://mojolicio.us');
my $tx = $c->ua->post_form('http://kraih.com/login' => {user => 'mojo'});

# Non-blocking
$c->ua->get('http://mojolicio.us' => sub {
  my ($ua, $tx) = @_;
  $c->render_data($tx->res->body);
});

# Parallel non-blocking
my $delay = Mojo::IOLoop->delay(sub {
  my ($delay, @titles) = @_;
  $c->render_json(\@titles);
});
for my $url ('http://mojolicio.us', 'https://metacpan.org') {
  $delay->begin;
  $c->ua->get($url => sub {
    my ($ua, $tx) = @_;
    $delay->end($tx->res->dom->html->head->title->text);
  });
}

url_for

my $url = $c->url_for;
my $url = $c->url_for(name => 'sebastian');
my $url = $c->url_for('test', name => 'sebastian');
my $url = $c->url_for('/perldoc');
my $url = $c->url_for('http://mojolicio.us/perldoc');

Generate a portable Mojo::URL object with base for a route, path or URL.

# "/perldoc" if application is deployed under "/"
say $c->url_for('/perldoc');

# "/myapp/perldoc" if application is deployed under "/myapp"
say $c->url_for('/perldoc');

write

$c->write;
$c->write('Hello!');
$c->write(sub {...});
$c->write('Hello!', sub {...});

Write dynamic content non-blocking, the optional drain callback will be invoked once all data has been written.

# Keep connection alive (with Content-Length header)
$c->res->headers->content_length(6);
$c->write('Hel', sub {
  my $c = shift;
  $c->write('lo!')
});

# Close connection when finished (without Content-Length header)
$c->write('Hel', sub {
  my $c = shift;
  $c->write('lo!', sub {
    my $c = shift;
    $c->finish;
  });
});

For Comet (long polling) you might also want to increase the connection timeout, which usually defaults to 15 seconds.

# Increase timeout for current connection to 300 seconds
Mojo::IOLoop->connection_timeout($c->tx->connection => 300);

write_chunk

$c->write_chunk;
$c->write_chunk('Hello!');
$c->write_chunk(sub {...});
$c->write_chunk('Hello!', sub {...});

Write dynamic content non-blocking with the chunked transfer encoding, the optional drain callback will be invoked once all data has been written.

$c->write_chunk('He', sub {
  my $c = shift;
  $c->write_chunk('ll', sub {
    my $c = shift;
    $c->finish('o!');
  });
});

You can call finish at any time to end the stream.

2
He
2
ll
2
o!
0

HELPERS

In addition to the attributes and methods above you can also call helpers on instances of Mojolicious::Controller. This includes all helpers from Mojolicious::Plugin::DefaultHelpers and Mojolicious::Plugin::TagHelpers.

$c->layout('green');
$c->title('Welcome!');

SEE ALSO

Mojolicious, Mojolicious::Guides, http://mojolicio.us.