Implement CSRF for post_thread

This commit is contained in:
swaggboi 2024-08-10 15:24:32 -04:00
parent 66bbd9da67
commit 32393fd8f3
3 changed files with 36 additions and 11 deletions

View file

@ -15,8 +15,15 @@ sub create($self) {
$v->required('title' )->size(1, 127); $v->required('title' )->size(1, 127);
$v->required('body' )->size(2, $body_limit); $v->required('body' )->size(2, $body_limit);
$v->optional('preview'); $v->optional('preview');
$v->csrf_protect;
if ($v->has_error) { if ($v->has_error('csrf_token')) {
$self->stash(
status => 403,
error => 'Something went wrong, please try again. 🥺'
);
}
elsif ($v->has_error) {
$self->stash(status => 400) $self->stash(status => 400)
} }
else { else {

View file

@ -51,12 +51,15 @@ $t->post_ok($bump_thread_url, form => \%good_captcha)
$t->ua->max_redirects(1); $t->ua->max_redirects(1);
subtest 'Post new thread', sub { subtest 'Post new thread', sub {
my $csrf_token;
# GET # GET
$t->get_ok('/human/thread/post')->status_is(200) $t->get_ok('/human/thread/post')->status_is(200)
->element_exists('form input[name="author"]' ) ->element_exists('form input[name="author"]' )
->element_exists('form input[name="title"]' ) ->element_exists('form input[name="title"]' )
->element_exists('form textarea[name="body"]' ) ->element_exists('form textarea[name="body"]' )
->element_exists('form button[type="submit"]' ) ->element_exists('form button[type="submit"]' )
->element_exists('form input[name="csrf_token"]')
->text_like(h2 => qr/New Thread/); ->text_like(h2 => qr/New Thread/);
# POST # POST
@ -67,14 +70,28 @@ subtest 'Post new thread', sub {
->element_exists('form button[type="submit"]') ->element_exists('form button[type="submit"]')
->text_like(h2 => qr/New Thread/); ->text_like(h2 => qr/New Thread/);
# No CSRF token
$t->post_ok('/human/thread/post', form => \%valid_thread)
->status_is(403)
->text_like(p => qr/Something went wrong/);
$invalid_title{'csrf_token'} =
$t->tx->res->dom->at('input[name="csrf_token"]')->val;
$t->post_ok('/human/thread/post', form => \%invalid_title) $t->post_ok('/human/thread/post', form => \%invalid_title)
->status_is(400) ->status_is(400)
->text_like(p => qr/Must be between/); ->text_like(p => qr/Must be between/);
$invalid_thread{'csrf_token'} =
$t->tx->res->dom->at('input[name="csrf_token"]')->val;
$t->post_ok('/human/thread/post', form => \%invalid_thread) $t->post_ok('/human/thread/post', form => \%invalid_thread)
->status_is(400) ->status_is(400)
->text_like(p => qr/Must be between/); ->text_like(p => qr/Must be between/);
$valid_thread{'csrf_token'} =
$t->tx->res->dom->at('input[name="csrf_token"]')->val;
$t->post_ok('/human/thread/post', form => \%valid_thread) $t->post_ok('/human/thread/post', form => \%valid_thread)
->status_is(200) ->status_is(200)
->text_like(h2 => qr/Thread #\d+/); ->text_like(h2 => qr/Thread #\d+/);

View file

@ -61,5 +61,6 @@
<%= check_box preview => 1, id => 'preview' %> <%= check_box preview => 1, id => 'preview' %>
<%= label_for preview => 'Preview' %> <%= label_for preview => 'Preview' %>
</div> </div>
<%= csrf_field %>
<button type="submit" class="form-button">Post</button> <button type="submit" class="form-button">Post</button>
</form> </form>