diff -ruN perl-CGI-FormMagick-0.93.old/lib/CGI/FormMagick/Events.pm perl-CGI-FormMagick-0.93/lib/CGI/FormMagick/Events.pm --- perl-CGI-FormMagick-0.93.old/lib/CGI/FormMagick/Events.pm 2018-10-22 15:37:29.557795203 +0200 +++ perl-CGI-FormMagick-0.93/lib/CGI/FormMagick/Events.pm 2018-10-22 15:39:25.003464188 +0200 @@ -130,6 +130,11 @@ sub page_post_event { my ($self) = @_; $self->debug_msg("This is the page post-event."); + if ($self->{csrf} and ($self->{cgi}->request_method || 'POST') eq 'POST' and + ($self->{cgi}->param('csrf_token') || '') ne $self->{cgi}->param('csrf_token_compare')){ + warn "CSRF protection blocked request\n"; + return $self->error($self->localise('CSRF_VALIDATION_FAILURE')); + } if (my $post_page_routine = $self->page->{'post-event'}) { $self->debug_msg("The post-routine is $post_page_routine"); $self->do_external_routine($post_page_routine); diff -ruN perl-CGI-FormMagick-0.93.old/lib/CGI/FormMagick/HTML.pm perl-CGI-FormMagick-0.93/lib/CGI/FormMagick/HTML.pm --- perl-CGI-FormMagick-0.93.old/lib/CGI/FormMagick/HTML.pm 2018-10-22 15:37:29.574796035 +0200 +++ perl-CGI-FormMagick-0.93/lib/CGI/FormMagick/HTML.pm 2018-10-22 15:39:59.995182470 +0200 @@ -182,6 +182,9 @@ print qq( \n); print qq( \n); print " ",$fm->{cgi}->state_field(), "\n"; # hidden field with state ID + if ($fm->{cgi}->param('csrf_token_compare')){ + print " {cgi}->param('csrf_token_compare') . "\">\n"; + } print " \n"; if ($menu) diff -ruN perl-CGI-FormMagick-0.93.old/lib/CGI/FormMagick.pm perl-CGI-FormMagick-0.93/lib/CGI/FormMagick.pm --- perl-CGI-FormMagick-0.93.old/lib/CGI/FormMagick.pm 2018-10-22 15:37:29.557795203 +0200 +++ perl-CGI-FormMagick-0.93/lib/CGI/FormMagick.pm 2018-10-22 15:41:24.889351176 +0200 @@ -24,6 +24,7 @@ use CGI::FormMagick::Utils; use CGI::FormMagick::Sub; use File::Basename; +use Session::Token; use strict; use Carp; @@ -181,6 +182,7 @@ $self->{charset} = $args{charset} || 'UTF-8'; $self->{cgi} = $args{cgi}; $self->{debug} = $args{debug} || 0; + $self->{csrf} = $args{csrf} || 0; if ($self->{cgi}) { if ($args{sessiondir}) { @@ -195,6 +197,11 @@ $self->{cgi} = new CGI::Persistent $self->{sessiondir}; } + # Create a CSRF token to compare later with. And store it in the session + if ($self->{csrf} and not $self->{cgi}->param('csrf_token_compare')){ + $self->{cgi}->param(-name => 'csrf_token_compare', -value => Session::Token->new(entropy => 256)->get); + $self->commit_session; + } foreach (qw(PREVIOUSBUTTON RESETBUTTON STARTOVERLINK NEXTBUTTON)) { if (exists $args{$_}) {