[cgiapp] CAP::Security::CSRF -- useful?

Mark Rajcok mrajcok at gmail.com
Thu Dec 3 01:16:25 EST 2009


I tried using CAP::ProtectCSRF and ran into a problem.
The plugin uses attribute handlers, which work great when a form is
initially displayed -- postrun callback _add_csrf_id() is magically called
to add the token (as a hidden field) to the HTML form, based on the
"PublishCSRFID" attribute being present:

sub create : Runmode :PublishCSRFID {
    my ($self, $errs) = @_;
    my $t = $self->load_tmpl('request_form.html');
...
   $t->output
}  # <------ _add_csrf_id() gets called

sub create_check : Runmode :ProtectCSRF {
    my $self = shift;
    my $dfv_results = $self->check_rm('create', Request::dfv_create_rules)
||
        return $self->check_rm_error_page;  # <-----  _add_csrf_id() does
not get called
...
}

If there is a problem with the form, check_rm_error_page() calls create()
and the form will be redisplayed to the user with errors, but the postrun
callback does not get executed, so the HTML form will not have the hidden
field with the token.  Trying to submit a corrected form then fails with a
CSRF error, since there is no CSRF token in the submitted form.
(I suppose this is a ProtectCSRF bug, since I don't think I'm doing anything
odd here.)

Anyone see a solution to this problem?  (other than abandoning attribute
handlers and requiring functions like create() above to explicitly call
_publish_csrf_id() and _add_csrf_id())

The above may boil down to this general issue/question:  if a plugin
installs a (say prerun) callback for (say) rm2, and rm1 calls rm2 directly,
is there any way to force the callbacks to be executed for rm2 (without
using a redirect)?  For example:

sub rm1 {  # does not require authentication
  ...
  $self->rm2;   # <--- no callbacks are executed for rm2 -- sometimes that's
a problem
}
sub rm2 { # requires authentication and uses a prerun callback to enforce it
...
}

-- Mark

On Sat, Nov 28, 2009 at 10:08 PM, Mark Rajcok <mrajcok at gmail.com> wrote:

> I should have searched CPAN some more first:
>  http://search.cpan.org/perldoc?CGI::Application::Plugin::ProtectCSRF
>
>
> On Sat, Nov 28, 2009 at 6:21 PM, Mark Rajcok <mrajcok at gmail.com> wrote:
>
>> I want to guard against multiple form submissions (reload, resubmit, etc.)
>> and CSRF in my app:
>>
>
>


More information about the cgiapp mailing list