Plack-Middleware-XSRFBlock

 view release on metacpan or  search on metacpan

README.mkdn  view on Meta::CPAN


# ERRORS

The module emits various errors based on the cause of the XSRF detected. The
messages will be of the form `XSRF detected [reason]`

- 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\]

- 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\]

- cookie missing

    There is no cookie with the name specified by `$self-`cookie\_name> \[default:
    PSGI-XSRF-Token\]

- invalid token

    The cookie token and form value were both submitted correctly but the values
    do not match.

- invalid signature

    The cookies signature is invalid, indicating it was tampered with on the way
    to the browser.

## detect\_xsrf($self, $request, $env)

returns a message explaining the XSRF-related problem, or `undef` if
there's no problem

## should\_be\_filtered($self, $request, $env, $res)

returns true if the response should be filtered by this middleware
(currently, if its content-type matches `contents_to_filter_regex`)

## 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
`secret` is set, the value is also signed.

## cookie\_handler($self, $request, $env, $res, $token)

sets the given token as a cookie in the response

## filter\_response\_html($self, $request, $env, $res, $token)

Filters the response, injecting `<input>` elements with the token
value into all forms whose method matches `http_method_regex`.

Streaming responses are still streaming after the filtering.

## filter\_response($self, $request, $env)

Calls the application, and (if the response ["`should_be_filtered`"](#should_be_filtered)), it injects the token in the cookie and (if ["`inject_form_input`"](#inject_form_input)) the forms.

## invalid\_signature($self, $value)

Returns true if the value is not correctly signed. If we're not
signing tokens, this method always returns false.

## xsrf\_detected($self, $args)

Invoked when the XSRF is detected. Calls the ["`blocked`"](#blocked)
coderef if we have it, or returns a 403.

The `blocked` coderef is invoked like:

    $self->blocked->($env,$msg, app => $self->app);

- the original request PSGI environment
- the error message (from ["`detect_xsrf`"](#detect_xsrf))
- a hash, currently `app => $self->app`, so you can call the
original application

## log($self, $level, $msg)

log through the PSGI logger, if defined

# EXPLANATION

This module is similar in nature and intention to
[Plack::Middleware::CSRFBlock](https://metacpan.org/pod/Plack::Middleware::CSRFBlock) but implements the xSRF prevention in a
different manner.

The solution implemented in this module is based on a CodingHorror article -
[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
[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
    on behalf of a user, he can only modify the values of the form. An
    attacker cannot read any data sent from the server or modify cookie
    values, per the same-origin policy.  This means that while an attacker can
    send any value he wants with the form, he will be unable to modify or read
    the value stored in the cookie. Since the cookie value and the form value
    must be the same, the attacker will be unable to successfully submit a
    form unless he is able to guess the pseudorandom value.

## What's wrong with Plack::Middleware::CSRFBlock?

[Plack::Middleware::CSRFBlock](https://metacpan.org/pod/Plack::Middleware::CSRFBlock) is a great module.
It does a great job of preventing CSRF behaviour with minimal effort.

However when we tried to use it uses the session to store information - which



( run in 0.675 second using v1.01-cache-2.11-cpan-39bf76dae61 )