chiark / gitweb /
docs: more work
[cgi-auth-flexible.git] / caf.pod
1 # -*- fundamental -*-
2
3 =head1 NAME
4
5 CGI::Auth::Flexible - web authentication optionally using cookies
6
7 =head1 SYNOPSYS
8
9  my $verifier = CGI::Auth::Flexible->new_verifier(setting => value,...);
10  my $authreq = $verifier->new_request($cgi_query_object);
11
12  # simple applications
13  $authreq->check_ok() or return;
14
15  # sophisticated applications
16  my $divert_kind = $authreq->check_divert();
17  if ($divert_kind) { ... print diversion page and quit ... }
18
19  # while handling the request
20  $user = $authreq->get_username();
21  $authreq->check_mutate();
22
23 =head1 DESCRIPTION
24
25 CGI::Auth::Flexible is a library which you can use to add a
26 forms/cookie-based login facility to a Perl web application.
27
28 CGI::Auth::Flexible doesn't interfere with your application's URL path
29 namespace and just needs a few (configurable) form parameter and
30 cookie name(s) for its own use.  It tries to avoid making assumptions
31 about the implementation structure of your application.
32
33 Because CGI::Auth::Flexible is licenced under the AGPLv3, you will
34 probably need to provide a facility to allow users (even ones not
35 logged in) to download the source code for your web app.  Conveniently
36 by default CGI::Auth::Flexible provides (for pure Perl webapps) a
37 mechanism for users to get the source.
38
39 CGI::Auth::Flexible is designed to try to stop you accidentally
40 granting access by misunderstanding the API.  (Also it, of course,
41 guards against cross-site scripting.)  You do need to make sure to
42 call CGI::Auth::Flexible before answering AJAX requests as well as
43 before generating HTML pages, of course, and to call it in every
44 entrypoint to your system.
45
46 =head2 CHECKLIST
47
48 As a minimum you need to do all of the things on this checklist, where
49 applicable.  The items marked SECURITY are the ones that you might
50 forget: without them your application may appear to work, but will be
51 insecure.
52
53 =over
54
55 =item *
56
57 Call C<new_verifier> (once at application startup)
58
59 =item *
60
61 Call C<new_request> (once per request)
62
63 =item *
64
65 B<SECURITY>: Call C<check_ok> or C<check_divert> on every request, and
66 honour the return value.
67
68 =item *
69
70 If you're using C<check_ok>, implement either the
71 C<username_password_error> or C<login_ok> hook.
72
73 =item *
74
75 Call C<get_username> when you need to know who's logged in.
76
77 =item *
78
79 B<SECURITY>: Call C<check_mutate> or C<mutate_ok>, if you specified
80 C<promise_check_mutate>.
81
82 =item *
83
84 B<SECURITY>: Call C<check_nonpage> for every request which is not a page load
85 (if your application has any of those).
86
87 =item *
88
89 When generating URLs and forms (including AJAX requests), include the
90 hidden form parameter using C<secret_hidden_val> or
91 C<secret_hidden_html> when appropriate (see below).
92
93 =item *
94
95 B<SECURITY>: If you do not override the source provision facility (see
96 L</SOURCE CODE DOWNLOAD>), check that the assumptions it makes aren't
97 going to leak security-critical data.
98
99 =back
100
101 These points will now be covered in more detail.
102
103 =head2 INITIALISATION
104
105 Your application should, on startup (eg, when it is loaded by
106 mod_perl) do
107 C<< $verifier = CGI::Auth::Flexible->new_verifier(settings...) >>.
108 This call can be expensive and is best amortised.
109
110 The resulting verifier object can be used to process individual
111 requests, in each case with
112 C<< $authreq = CGI::Auth::Flexible->new_request($cgi_query) >>.
113
114 =head2 RESPONSES - SIMPLE APPLICATIONS
115
116 The simplist usage is to call C<< $request->check_ok() >> which will
117 check the user's authentication.  If the user is not logged in it will
118 generate a login form (or redirection or other appropriate page) and
119 return false; your application should not then processing that request
120 any further.  If the user is logged in it will return true.
121
122 Various hooks are provided to customise the responses generated by
123 C<check_ok>.
124
125 After C<check_ok> returns true you should go ahead and process the
126 request; you can use C<< $request->get_username >> to find out which
127 user the request came from.
128
129 =head2 RESPONSES - SOPHISTICATED APPLICATIONS
130
131 If you want to handle the control flow and to generate login forms,
132 redirections, etc., yourself, you can say
133 C<< $divert = $request->check_divert >>.  This returns undef if
134 the user is logged in, or I<divert spec> if some kind of login
135 page or diversion should be generated.
136
137 =head2 MUTATING OPERATIONS AND EXTERNAL LINKS - MUTATION-IGNORANT APPLICATIONS
138
139 By default CGI::Auth::Flexible does not permit external links into
140 your site.  All GET requests give a "click to continue" page which
141 submits a form which loads your app's main page.  In this
142 configuration all your application's forms and AJAX requests should
143 use C<POST>.  This restriction arises from complicated deficiencies
144 in the web's security architecture.
145
146 Such applications are also not able to provide user-specific CSS
147 stylesheets, javascript, favicons, etc.
148
149 =head2 MUTATING OPERATIONS AND EXTERNAL LINKS - MUTATION-AWARE APPLICATIONS
150
151 The alternative is for your application to always make a special check
152 when the incoming request is going to do some kind of action (such as
153 modifying the user's setup, purchasing goods, or whatever) rather than
154 just retrieve and/or display information.  We term such requests
155 "mutating" requests.
156
157 Then non-mutating pages can be linked to from other, untrustworthy,
158 websites.
159
160 To support external links, and C<GET> requests, pass
161 C<< promise_check_mutate => 1 >> in I<settings>, and then call
162 C<< $authreq->check_mutate() >> before taking any actions.  If the
163 incoming request is not suitable then C<< $authreq->check_mutate() >>
164 will call C<die>.
165
166 There have to be no mutating C<GET> requests in your application (but
167 you shouldn't have any of those anyway); if there are, they won't
168 work.  (CGI::Auth::Flexible will spot them and cause them to fail,
169 rather than allow them to be insecure.)
170
171 =head2 GENERATING URLS, FORMS AND AJAX QUERIES
172
173 When you generate a URL, C<POST> form or AJAX request you may need to
174 include a secret hidden form parameter for the benefit of
175 CGI::Auth::Generic.  This form parameter will be checked by
176 C<check_ok>/C<check_divert> and should be ignored by your application.
177
178 By default the hidden parameter is called C<caf_assochash>.
179
180 After calling C<check_ok> or C<check_divert> the value to put in your
181 form can be obtained from C<secret_hidden_val>; C<secret_hidden_html>
182 will generate the whole HTML C<< <input...> >> element.
183
184 =head3 Mutation-ignorant applications
185
186 For mutation-ignorant applications (see above), all forms etc. should
187 include the hidden parameter (and as discussed, they must all use
188 POST rather than GET).
189
190 =head3 Mutation-aware applications
191
192 For mutation-aware applications, whether to include the secret
193 parameter depends on the kind of request.  CGI::Auth::Flexible knows
194 when it is necessary.  You should find out by calling
195 C<need_add_hidden>.
196
197 If it is inconvenient to call C<need_add_hidden> at runtime, you can
198 rely instead on the following promises:  All POST requests (which
199 includes all mutating requests) need the parameter.  The return value
200 of need_add_hidden depends only on the $method and $reqtype
201 parameters, so you can query it once and remember the answer.
202 HTML page load GETs do not need the parameter.  It is better to
203 err on the side of including the parameter.
204
205 If you really must, you can call C<need_add_hidden> "on the bench"
206 during development and bake the answer into your application code
207 structure.  However, if you do that and a new vulnerability was
208 discovered which is fixed by changing the answer, updating
209 CGI::Auth::Flexible wouldn't be sufficient to fix it.
210
211 =head3 Mutation-aware applications - non-page requests
212
213 If your mutation-aware application supports non-page resources (AJAX
214 and JSON requests, stylesheets, favicons, etc.) it must inform
215 CGI::Auth::Flexible when it is handling such a request, by calling
216 C<check_nonpage>.
217
218 Normally C<check_nonpage> will simply return (and you can ignore the
219 return value).  However, if there is an attack (or, perhaps, a bug) it
220 will die, stopping the attack.
221
222 (You do not need to call C<check_nonpage> for POST requests, but it is
223 harmless to do so.)
224
225 =head2 DATA STORAGE
226
227 CGI::Auth::Flexible needs to store various information in plain files;
228 it does this in the directory specified by the C<dir> parameter.
229
230 =head1 SOURCE CODE DOWNLOAD
231
232 By default, CGI::Auth::Flexible provides a facility for users to
233 download the source code for the running version of your web
234 application.
235
236 This facility makes a number of important assumptions which you need
237 to check.  Note that if the provided facility is not sufficient
238 because your application is more sophisticated than it copes with (or
239 if you disable the builtin facility), you may need to implement a
240 functioning alternative to avoid violating the AGPLv3 licence.
241
242 Here are the most important (default) assumptions:
243
244 =over
245
246 =item *
247
248 Your app's source code is available by looking at @INC, $0 and
249 S<$ENV{'SCRIPT_FILENAME'}> (the B<source items>).  See
250 C<srcdump_listitems>.  Where these point to files or directories under
251 revision control, the source item is the whole containing vcs tree.
252
253 =item *
254
255 Specifically, there are no compiled or autogenerated Perl
256 files, Javascript resources, etc., which are not contained in one of
257 the source item directories.  (Files which came with your operating
258 system install don't need to be shipped as they fall under the system
259 library exception.)
260
261 =item *
262
263 You have not installed any modified versions of system
264 libraries (including system-supplied Perl modules) in C</usr> outside
265 C</usr/local>.  See C<srcdump_system_dir>.
266
267 =item *
268
269 For each source item in a dvcs, the entire dvcs history does
270 not contain anything confidential (or libellous).  Also, all files which
271 contain secrets are in the dvcs's I<.ignore> file.  See
272 C<srcdump_vcsscript_git> et al.
273
274 =item *
275
276 For each source item NOT in a dvcs, there are no confidential
277 files with the world-readable bit set (being in a world-inaccessible
278 directory is not sufficient).  See C<srcdump_excludes>.
279
280 =item *
281
282 You have none of your app's source code in C</etc>.
283
284 =item *
285
286 You don't regard pathnames on your server as secret.
287
288 =item *
289
290 You don't intentionally load Perl code by virtue of C<.>
291 being in C<@INC> by default.  (See C<srcdump_filter_cwd>.)
292
293 =back
294
295 =head1 MAIN FUNCTIONS AND METHODS
296
297 =over
298
299 =item C<< CGI::Auth::Flexible->new_verifier(setting => value, ...) >>
300
301 Initialises an instance and returns a verifier object.
302 The arguments are setting pairs like a hash initialiser.
303 See L</SETTINGS> below.
304
305 =item C<< $verifier->new_request($cgi_query) >>
306
307 Prepares to process a request.  I<$cgi_query> should normally
308 be the query object from L<CGI(3perl)>.  Most of the default
309 hook methods assume that it is; however if you replace enough of
310 the hook methods then you can pass any value you like and it
311 will be passed to your hooks.
312
313 The return value is the authentication request object (I<$authreq>)
314 which is used to check the incoming request and will contain
315 information about its credentials.
316
317 =item C<< $authreq->check_divert() >>
318
319 Checks whether the user is logged in.  Returns undef if the user is
320 logged in and we should service the request.  Otherwise returns a
321 divert spec (see L</DIVERT SPEC>) saying what should happen instead.
322
323 This method may die if it doesn't like the request, in which case
324 the request needs to be rejected.
325
326 =item C<< $authreq->check_ok() >>
327
328 Checks whether the user is logged in.  Returns true if the user is
329 logged in and we should service the request.
330
331 Otherwise it handles the request itself, generating any appropriate
332 redirect, login form, or continuation page.  It then returns false and
333 the application should not process the request further.
334
335 =item C<< $verifier->disconnect() >>
336
337 Discards the resources (open files, etc.) in the verifier object.
338
339 =back
340
341 =head REQUEST-HANDLING FUNCTIONS AND METHODS
342
343 All of these are only valid after C<check_divert> or C<check_ok> has
344 been called.  (In the case of C<check_ok> it won't normally be sensible
345 to call these functions unless C<check_ok> returned true.)
346
347 =item C<< $authreq->get_divert() >>
348
349 Returns the value previously returned by C<check_divert>.
350
351 =item C<< $authreq->get_username() >>
352
353 Returns the name of the logged-in user.  If the user was not logged
354 in (or their session had timed out, or something), returns undef.
355
356 =head RESPONSE-RELATED FUNCTIONS AND METHODS
357
358 =item C<< $authreq->url_with_query_params($params, [$nonpagetype]) >>
359
360 Convenience function which returns a url for a GET request to this
361 application.
362
363 I<$params> is a hashref specifying the parameters and the PATH_INFO.
364 The keys are the parameter names, and the values are array refs with
365 the parameter value(s) (as strings, as yet unquoted).  (They are array
366 refs because it is possible to pass multiple values for the same
367 parameter in a single request; normally each arrayref would be a
368 singleton.)
369
370 The request path will be the path to the application.  If a parameter
371 with name C<< '' >> is supplied, it is taken as the PATH_INFO to
372 supply - its value will be appended to the application path.  (It
373 should normally start with C<< / >>, and only one value should be
374 supplied.)
375
376 =item C<< $authreq->chain_params() >>
377
378 Returns a hash of the "relevant" parameters to this request, in a form
379 used by XXX.  This is all of the query parameters which are not
380 related to CGI::Auth::Flexible.  The PATH_INFO from the request is
381 returned as the parameter C<< '' >>.
382
383 =back