package LIMS::Local::CSRF; use strict; use warnings; use base 'Exporter'; use Digest::SHA1 qw(sha1_base64); use vars qw($VERSION @EXPORT); @EXPORT = qw(csrf_insert_token csrf_check_token); $VERSION = '1.0'; sub csrf_insert_token { my $self = shift; my $token_name = shift || 'csrf_token'; # reuse the token that was submitted with the form; don't generate a new one return if $self->query->param('csrf_token'); # generate a new token (not intended to be highly secure, or use random seed): my $token = sha1_base64($self->session->param('_SESSION_ID') . time); $self->tt_params( csrf_token => $token ); $self->session->param( $token_name => $token ); } # returns true if POST'ed && query param token matches session token # can set explicit token name, or accept default: sub csrf_check_token { my $self = shift; my $token_name = shift || 'csrf_token'; my $session_token = $self->session->param($token_name); my $query_token = $self->query->param('csrf_token'); # ensure the form was POST'ed and session token == query token: return 0 unless $self->query->request_method eq 'POST' && $session_token eq $query_token; $self->session->clear($token_name); return 1; } 1;