package SrvMngr::Plugin::CSRFDefender; use strict; use warnings; use Carp; our $VERSION = '0.0.8-1'; use base qw(Mojolicious::Plugin Class::Accessor::Fast); __PACKAGE__->mk_accessors(qw( parameter_name session_key token_length error_status error_content error_template onetime get_token_param )); use String::Random; use Path::Class; sub register { my ($self, $app, $conf) = @_; # Plugin config $conf ||= {}; # setting $self->parameter_name($conf->{parameter_name} || 'csrftoken'); $self->session_key($conf->{session_key} || 'csrftoken'); $self->token_length($conf->{token_length} || 32); $self->error_status($conf->{error_status} || 403); $self->error_content($conf->{error_content} || 'Forbidden'); $self->onetime($conf->{onetime} || 0); if ($conf->{error_template}) { my $file = $app->home->rel_file($conf->{error_template}); $self->error_template($file); } $self->get_token_param($conf->{get_token_param} || 'CsrfDef=TOKEN'); # added for GET method # input check $app->hook(before_dispatch => sub { my ($c) = @_; unless ($self->_validate_csrf($c)) { my $content; if ($self->error_template) { my $file = file($self->error_template); $content = $file->slurp; } else { $content = $self->{error_content}, } $c->render( status => $self->{error_status}, text => $content, ); }; }); # output filter $app->hook(after_dispatch => sub { my ($c) = @_; my $token = $self->_get_csrf_token($c); my $p_name = $self->parameter_name; my $g_token = $self->get_token_param; my $body = $c->res->body; $body =~ s{(
this becomes =head2 input check For every POST requests, this module checks input parameters contain the collect token parameter. If not found, throws 403 Forbidden. =head1 OPTIONS plugin 'Mojolicious::Plugin::CSRFDefender' => { parameter_name => 'param-csrftoken', session_key => 'session-csrftoken', token_length => 40, error_status => 400, error_template => 'public/400.html', }; =over 4 =item parameter_name(default:"csrftoken") Name of the input tag for the token. =item session_key(default:"csrftoken") Name of the session key for the token. =item token_length(default:32) Length of the token string. =item error_status(default:403) Status code when CSRF is detected. =item error_content(default:"Forbidden") Content body when CSRF is detected. =item error_template Return content of the specified file as content body when CSRF is detected. Specify the file path from the application home directory. =item onetime(default:0) If specified with 1, this plugin uses onetime token, that is, whenever client sent collect token and this middleware detect that, token string is regenerated. =back =head1 METHODS L