1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
|
Author: Nicholas Bamber <nicholas@periapt.co.uk>
Subject: Polish up English usage in Pod
Bug: http://rt.cpan.org/Ticket/Display.html?id=72342
Last-Upate: 2011-11-09
--- a/CGI/Application/Plugin/ProtectCSRF.pm
+++ b/CGI/Application/Plugin/ProtectCSRF.pm
@@ -4,7 +4,7 @@
=head1 NAME
-CGI::Application::Plugin::ProtectCSRF - Plug-in protected from CSRF
+CGI::Application::Plugin::ProtectCSRF - generate and verify anti-CSRF tickets
=head1 VERSION
@@ -14,7 +14,7 @@
use Your::App;
use base qw(CGI::Application);
- use CGI::Application::Plugin::Session; # require!!
+ use CGI::Application::Plugin::Session; # mandatory !!
use CGI::Application::Plugin::ProtectCSRF;
sub input_form : PublishCSRFID {
@@ -30,9 +30,20 @@
=head1 DESCRIPTION
-CGI::Application::Plugin::ProtectCSRF is C::A::P protected from CSRF.
-
-When CSRF is detected, Forbidden is returned and processing is interrupted.
+CGI::Application::Plugin::ProtectCSRF provides tools to protect forms in
+L<CGI::Application> web applications from CSRF attacks. Run mode handlers
+may be declared with the C<PublishCSFRID> or C<ProtectCSFR> attributes.
+The former should usually be applied to a run mode, whose HTML includes
+a C<form> tag. In this case a ticket is generated and stored in the session
+during a prerun callback and a C<hidden> control field, publishing the
+ticket, is added to the form during a postrun callback. Conversely the
+C<ProtectCSRF> attribute should normally be applied to the corresponding
+run modes that process data from a submitted form. A prerun callback checks
+for the hidden field and checks that it matches the ticket saved
+in the session. If the check fails the page is redirected to a
+customizable error page. On success the form processing run mode should
+use the C<clear_csrf_id> method, so that subsequent calls to forms from that
+session will generate fresh tickets.
=cut
@@ -67,7 +78,7 @@
<head><title>CSRF ERROR</title></head>
<body>
<h1>CSRF ERROR</h1>
-<p>This access is illegal. you don't have permission to access on this server.</p>
+<p>Access denied. Please contact the website administrator.</p>
</body>
</html>
};
@@ -82,7 +93,7 @@
my $pkg = caller;
# C::A::P::Session method check
- croak("C::A::P::Session module is not load to your app") if !$pkg->can("session");
+ croak("CGI::Aplication::Plugin::Session module is not loaded in your app") if !$pkg->can("session");
$pkg->add_callback("prerun", \&_publish_csrf_id);
$pkg->add_callback("prerun", \&_csrf_forbidden);
@@ -97,10 +108,18 @@
=head2 PublishCSRFID
-PublishCSRFID is action publishes CSRF ticket. CSRF ticket is published when I
-define it as an attribute of runmode method publishing CSRF ticket, and it is saved in session.
-If there is form tag in HTML to display after the processing end, as for runmode method to
-publish, CSRF ticket is set automatically by hidden field
+Run modes declared with the C<PublishCSRFID> attribute, take the following
+actions:
+
+=over
+
+=item - generate CSRF ticket and store it in the session;
+
+=item - generate the form as per the module code;
+
+=item - add a hidden element to the form publishing the CSRF ticket.
+
+=back
# publish CSRF ticket
sub input_form : PublishCSRFID {
@@ -124,15 +143,33 @@
=head2 ProtectCSRF
-ProtectCSRF is action to protect from CSRF Attack. If session CSRF ticket does not accord
-with query CSRF ticket, application consideres it to be CSRF attack and refuse to access it.
-Carry out the processing that you want to perform after having carried out clear_csrf_id method
-when access it, and it was admitted.
+Run modes declared with the C<ProtectCSRF> attribute, take the following
+actions:
+
+=over
+
+=item - verify that the submitted CSRF ticket matches the ticket saved in the
+session. If there is any sort of issue with the ticket the page is
+redirected to a customizable error page;
+
+=item - the form is processed as per the module code;
+
+=item - the form should call the C<clear_csfr_id> method so that subsequent forms
+generate fresh tickets. The code does not do this because if the form validation
+fails it might be best to retain the same ticket.
+
+=back
sub finish : ProtectCSRF {
my $self = shift;
- $self->clear_csrf_id; # require! There is not a meaning unless I do it
- do_something(); # The processing that you want to perform (DB processing etc)
+
+ # required! Unless forms and their processing are tightly
+ # coupled by clearing the ticket between invocations,
+ # the meaning of the ticket is lost.
+ $self->clear_csrf_id;
+
+ # The processing that you want to perform (DB processing etc)
+ do_something();
}
=cut
@@ -154,7 +191,7 @@
=head2 csrf_id
-Get ticket for protect CSRF
+This method returns the CSRF ticket saved in the session.
Example:
@@ -175,16 +212,44 @@
=head2 protect_csrf_config
-Initialize ProtectCSRF
+This method initializes the ProtectCSRF state using any configuration options
+that were passed to it. The available options are:
+
+=over
+
+=item B<csrf_error_status> - The HTTP status code that would be set on the
+CSRF error page if a CSRF attack is identified. It defaults to 200.
+
+=item B<csrf_error_mode> - The L<CGI::Application> runmode name. This defaults to C<_csrf_error>.
+
+=for comment
+
+The Debian maintainer is unclear why this option is useful. Surely an
+anonymous run mode would be cleaner here.
+
+=end comment
+
+=item B<csrf_error_tmpl> - The HTML displayed in the event of a CSRF attack being
+detected in the form of a scalarref or filepath or filehandle. One may
+consider L<HTML::Template> for inspiration on thse formats. The default is
+C<$CSRF_ERROR_TMPL> which is a scalarref.
+
+=item B<csrf_error_tmpl_param> - A hashref of parameters to be placed in the
+above template. See L<HTML::Template>.
+
+=for comment
+
+The Debian maintainer thinks other templating systems should work but is
+unlikely to experiment with this in the near future.
+
+=end comment
+
+=item B<csrf_id> - The name of the session parameter used to store the CSRF ticket.This defaults to C<_csrf_id>.
-Option:
+=item B<csrf_post_only> - If set non-POST requests to a run mode which is protected
+by this module would be rejected. By default this is 0.
- csrf_error_status : CSRF error status code (default: 200)
- csrf_error_mode : CSRF error runmode name (default: _csrf_error)
- csrf_error_tmpl : CSRF error display html. scalarref or filepath or filehandle (default: $CSRF_ERROR_TMPL - scalarref)
- csrf_error_tmpl_param : CSRF error display html parameter (for HTML::Template)
- csrf_id : CSRF ticket name (default: _csrf_id)
- csrf_post_only : CSRF protect runmode request method check(default:0 1:POST Only)
+=back
Example:
@@ -233,7 +298,8 @@
=head2 clear_csrf_id
-Clear csrfid. It is preferable to make it execute after processing ends.
+This method clears the CSFR ticket. This should be done during the processing
+of a form request.
Example :
@@ -415,11 +481,21 @@
=head1 CAUTION
-It has only the protection function of basic CSRF,and mount other security checks in the application, please.
+This module should not be seen as a panacea for all web security issues.
+The user should fully understand and act on all security threats his
+application may face, including whether this module is an adequate and
+useful tool.
=head1 SEE ALSO
-L<Attribute::Handlers> L<Carp> L<CGI::Application> L<CGI::Application::Plugin::Session> L<Digest::SHA1> L<Exporter> L<HTML::TokeParser>
+L<Attribute::Handlers>,
+L<Carp>,
+L<CGI::Application>,
+L<CGI::Application::Plugin::Session>,
+L<Digest::SHA1>,
+L<Exporter>,
+L<HTML::TokeParser>,
+L<HTML::Template>
=head1 AUTHOR
|