Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
more CSRF protection tests
  • Loading branch information
kraih committed Dec 4, 2013
1 parent 59ca3a4 commit 37a1c8d
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 17 deletions.
16 changes: 10 additions & 6 deletions lib/Mojolicious/Controller.pm
Expand Up @@ -418,12 +418,16 @@ sub url_for {
sub validation {
my $self = shift;

my $req = $self->req;
my $hash = $req->params->to_hash;
$hash->{csrf_token} //= $req->headers->header('X-CSRF-Token')
if my $token = $self->session->{csrf_token};
return $self->stash->{'mojo.validation'}
||= $self->app->validator->validation->input($hash)->csrf_token($token);
my $stash = $self->stash;
return $stash->{'mojo.validation'} if $stash->{'mojo.validation'};

my $req = $self->req;
my $token = $self->session->{csrf_token};
my $header = $req->headers->header('X-CSRF-Token');
my $hash = $req->params->to_hash;
$hash->{csrf_token} //= $header if $token && $header;
my $validation = $self->app->validator->validation->input($hash);
return $stash->{'mojo.validation'} = $validation->csrf_token($token);
}

sub write {
Expand Down
2 changes: 1 addition & 1 deletion lib/Mojolicious/Validator/Validation.pm
Expand Up @@ -41,7 +41,7 @@ sub check {

sub csrf_protect {
my $self = shift;
my $token = delete $self->input->{csrf_token};
my $token = $self->input->{csrf_token};
$self->{error}{csrf_token} = ['csrf_protect']
unless $token && $token eq $self->csrf_token;
return $self;
Expand Down
20 changes: 10 additions & 10 deletions t/mojolicious/validation_lite_app.t
Expand Up @@ -26,9 +26,9 @@ any '/' => sub {

any '/forgery' => sub {
my $self = shift;
my $validation = $self->validation->csrf_protect;
my $validation = $self->validation;
return $self->render unless $validation->has_data;
$validation->required('foo');
$validation->csrf_protect->required('foo');
};

my $t = Test::Mojo->new;
Expand Down Expand Up @@ -176,29 +176,29 @@ $t->post_ok('/' => form => {foo => 'no'})->status_is(200)
# Missing CSRF token
$t->get_ok('/forgery' => form => {foo => 'bar'})->status_is(200)
->content_like(qr/Wrong or missing CSRF token!/)
->element_exists('[value=bar]');
->element_exists('[value=bar]')->element_exists_not('.field-with-error');

# Correct CSRF token
my $token
= $t->ua->get('/forgery')->res->dom->at('[name=csrf_token]')->{value};
$t->post_ok('/forgery' => form => {csrf_token => $token, foo => 'bar'})
->status_is(200)->content_unlike(qr/Wrong or missing CSRF token!/)
->element_exists('[value=bar]');
->element_exists('[value=bar]')->element_exists_not('.field-with-error');

# Correct CSRF token (header)
$t->post_ok('/forgery' => {'X-CSRF-Token' => $token} => form => {foo => 'bar'})
->status_is(200)->content_unlike(qr/Wrong or missing CSRF token!/)
->element_exists('[value=bar]');
->element_exists('[value=bar]')->element_exists_not('.field-with-error');

# Wrong CSRF token (header)
$t->post_ok('/forgery' => {'X-CSRF-Token' => 'abc'} => form => {foo => 'bar'})
->status_is(200)->content_like(qr/Wrong or missing CSRF token!/)
->element_exists('[value=bar]');
->element_exists('[value=bar]')->element_exists_not('.field-with-error');

# Missing CSRF token again
$t->post_ok('/forgery' => form => {foo => 'bar'})->status_is(200)
->content_like(qr/Wrong or missing CSRF token!/)
->element_exists('[value=bar]');
# Missing CSRF token and form
$t->get_ok('/forgery')->status_is(200)
->content_unlike(qr/Wrong or missing CSRF token!/)
->element_exists_not('.field-with-error');

# Failed validation for all fields (with custom helper)
$t->app->helper(
Expand Down

0 comments on commit 37a1c8d

Please sign in to comment.