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 )