Plack-Middleware-XSRFBlock
view release on metacpan or search on metacpan
lib/Plack/Middleware/XSRFBlock.pm view on Meta::CPAN
messages will be of the form C<XSRF detected [reason]>
=over 4
=item form field missing
The request was submitted but there was no value submitted in the form field
specified by <C$self->parameter_name> [default: xsrf_token]
=item xsrf token missing
The application has been configured to accept an 'X-' header and no token
value was found in either the header or a suitable form field. [default: undef]
=item cookie missing
There is no cookie with the name specified by C<$self->cookie_name> [default:
PSGI-XSRF-Token]
=item invalid token
The cookie token and form value were both submitted correctly but the values
do not match.
=item invalid signature
The cookies signature is invalid, indicating it was tampered with on the way
to the browser.
=back
=head2 detect_xsrf($self, $request, $env)
returns a message explaining the XSRF-related problem, or C<undef> if
there's no problem
=head2 should_be_filtered($self, $request, $env, $res)
returns true if the response should be filtered by this middleware
(currently, if its content-type matches C<contents_to_filter_regex>)
=head2 generate_token($self, $request, $env, $res)
Returns the token value to use for this response.
If the cookie is already set, and we do not want a different token for
each request, returns the cookie's value.
Otherwise, generates a new value based on some random data. If
C<secret> is set, the value is also signed.
=head2 cookie_handler($self, $request, $env, $res, $token)
sets the given token as a cookie in the response
=head2 filter_response_html($self, $request, $env, $res, $token)
Filters the response, injecting C<< <input> >> elements with the token
value into all forms whose method matches C<http_method_regex>.
Streaming responses are still streaming after the filtering.
=head2 filter_response($self, $request, $env)
Calls the application, and (if the response L<< /C<should_be_filtered>
>>), it injects the token in the cookie and (if L<<
/C<inject_form_input> >>) the forms.
=head2 invalid_signature($self, $value)
Returns true if the value is not correctly signed. If we're not
signing tokens, this method always returns false.
=head2 xsrf_detected($self, $args)
Invoked when the XSRF is detected. Calls the L<< /C<blocked> >>
coderef if we have it, or returns a 403.
The C<blocked> coderef is invoked like:
$self->blocked->($env,$msg, app => $self->app);
=over
=item *
the original request PSGI environment
=item *
the error message (from L<< /C<detect_xsrf> >>)
=item *
a hash, currently C<< app => $self->app >>, so you can call the
original application
=back
=head2 log($self, $level, $msg)
log through the PSGI logger, if defined
=head1 EXPLANATION
This module is similar in nature and intention to
L<Plack::Middleware::CSRFBlock> but implements the xSRF prevention in a
different manner.
The solution implemented in this module is based on a CodingHorror article -
L<Preventing CSRF and XSRF Attacks|http://www.codinghorror.com/blog/2008/10/preventing-csrf-and-xsrf-attacks.html>.
The driving comment behind this implementation is from
L<the Felten and Zeller paper|https://www.eecs.berkeley.edu/~daw/teaching/cs261-f11/reading/csrf.pdf>:
When a user visits a site, the site should generate a (cryptographically
strong) pseudorandom value and set it as a cookie on the user's machine.
The site should require every form submission to include this pseudorandom
value as a form value and also as a cookie value. When a POST request is
sent to the site, the request should only be considered valid if the form
value and the cookie value are the same. When an attacker submits a form
( run in 0.783 second using v1.01-cache-2.11-cpan-39bf76dae61 )