<commit_before>=pod

=head1 NAME

Mojolicious::Plugin::ClosedRedirect - Defend Open Redirect Attacks

=head1 SYNOPSIS

  # Check for Open Redirect Attack
  return if $c->closed_redirect_to('return_url');

  # Open Redirect attack discovered
  return $c->redirect_to('home');

  # Protection for open redirect_to

  $app->routes->route('/mypath')->name('mypath');

  $c->url_for('acct_login')->query([
    return_url => $c->signed_url_for('mytest')
  ]);

  # Redirect to valid url from $c->param('return_url')
  return if $c->closed_redirect_to('return_url');

  # Fails
  return $c->redirect_to('home');


=head1 DESCRIPTION

This plugin helps you to protect your users not to tap into a
L<http://cwe.mitre.org/data/definitions/601.html|OpenRedirect>
vulnerabilities by using signed URLs.

=head1 METHODS

=head2 register

=over 2

=item C<silent>

Accepts a boolean value, if users should not receive a notification
on redirect attacs. Defaults to not being silent.

=item C<token_length>

Set the length of the secret token to append to redirect locations.
Defaults to C<16>.

=item C<secret>

Pass the secret to be used to hash on redirect locations.
Defaults to the first application secret.

=back

All parameters can be set either on registration or as part
of the configuration file with the key C<ClosedRedirect>
(with the configuration file having the higher precedence).

=head1 HELPERS

=head1 BUGS and CAVEATS

The URLs are currently signed using SHA-1 and a free, prefixed secret
(with the default being the application secret).
There are known attacks to SHA-1, so this solution does not mean
you should not validate the URL further.

It is not possible to change session information after a successfull redirect,
so the normal way to deal with that is to have a fallback for non valid
closed redirects in a controller.

=head1 AVAILABILITY

  https://github.com/Akron/Mojolicious-Plugin-ClosedRedirect

=head1 COPYRIGHT AND LICENSE

Copyright (C) 2016, L<<NAME>|http://nils-diewald.de/>.

This program is free software, you can redistribute it
and/or modify it under the terms of the Artistic License version 2.0.

=cut
<commit_msg>Updated Readme for GitHub<commit_after>=pod

=head1 NAME

Mojolicious::Plugin::ClosedRedirect - Defend Open Redirect Attacks


=head1 SYNOPSIS

  plugin ClosedRedirect => {
    secrets => [123, 'abz']
  };

  get '/login' => sub {
    my $c = shift;
    my $v = $c->validation;

    # Check for a redirection parameter
    $v->required('fwd')->closed_redirect;

    # ...

    # Redirect to redirection URL
    return $c->redirect_to($v->param('fwd')) unless $v->has_error;

    # Redirect to home page on failed validation
    return $c->redirect_to('/');
  };


=head1 DESCRIPTION

This plugin helps you to avoid
L<http://cwe.mitre.org/data/definitions/601.html|OpenRedirect>
vulnerabilities in your application by limiting redirections
to either local paths or
L<https://webmasters.googleblog.com/2009/01/open-redirect-urls-is-your-site-being.html|signed URLs>.

B<This is early software and the API and functionality may change in various ways!>
B<Wait until it's published on CPAN before you use it!>


=head1 ATTRIBUTES

=head2 secrets

  $plugin->secrets([123, 'abz']);
  print $plugin->secrets->[0];

Set secrets to be used to sign URLs.
Defaults to the application secrets.


=head1 CHECKS

=head2 closed_redirect

  # Check for a redirection parameter
  $c->validation->required('fwd')->closed_redirect;

Check the parameter in scope for being a valid URL to redirect to.

If no parameter is passed to the check, local paths or signed URLs are accepted.
If the parameter C<signed> is passed, only signed URLs are accepted.
If the parameter C<local> is passed, only local paths are accepted.

If the parameter was signed, the signature with the URI parameter C<crto>
will be removed on success (even if the URL was local).


=head1 HELPERS

=head2 close_redirect_to

  my $url = $c->url_for('/login')->query([
    fwd => $c->close_redirect_to('http://example.com/path')
  ]);

Sign a redirection URL with the defined secret.


=head1 HOOKS

=head2 on_open_redirect_attack

  $app->hook(on_open_redirect_attack => sub {
    my ($name, $url, $msg) = @_;
    ...
  });

Emitted when an open redirect attack was detected.
Passes the parameter name, the first failing URL,
and the error message of the check.


=head1 METHODS

=head2 register

  # Mojolicious
  $app->plugin('ClosedRedirect');

  # Mojolicious::Lite
  plugin 'ClosedRedirect';

Called when registering the plugin.
Accepts attributes as parameters.

All parameters can be set either on registration or as part
of the configuration file with the key C<ClosedRedirect>
(with the configuration file having the higher precedence).


=head1 BUGS and CAVEATS

The URLs are currently signed using HMAC-SHA-1 and a secret.
There are known attacks to SHA-1.

Local redirects need to be paths -
URLs with host information are not supported yet.


=head1 DEPENDENCIES

L<Mojolicious>.


=head1 AVAILABILITY

  https://github.com/Akron/Mojolicious-Plugin-ClosedRedirect


=head1 COPYRIGHT AND LICENSE

Copyright (C) 2016, L<<NAME>|http://nils-diewald.de/>.

This program is free software, you can redistribute it
and/or modify it under the terms of the Artistic License version 2.0.

=cut

{'fraction_non_alphanumeric': 0.09121813031161473, 'fraction_numerical': 0.012086874409820585, 'mean_word_length': 4.197252208047105, 'pattern_counts': {'":': 0, '<': 22, '<?xml version=': 0, '>': 57, 'https://': 3, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1392136', 'n_tokens_mistral': 1690, 'n_tokens_neox': 1586, 'n_words': 632}