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 CHECKING AND RESPONSE GENERATION
115
116 If the user is logged in, your application is to handle the request.
117 Otherwise, the user needs to be presented with a login form or error
118 message, as appropriate.  CGI::Auth::Flexible provides two alternative
119 interfaces for this:
120
121 =head3 Simple applications
122
123 The simplist usage is to call C<< $request->check_ok() >> which will
124 check the user's authentication.  If the user is not logged in it will
125 generate a login form (or redirection or other appropriate page) and
126 return false; your application should not then processing that request
127 any further.  If the user is logged in it will return true.
128
129 Various hooks are provided to customise the responses generated by
130 C<check_ok>.
131
132 After C<check_ok> returns true you should go ahead and process the
133 request; you can use C<< $request->get_username >> to find out which
134 user the request came from.
135
136 =head2 Sophisticated applications
137
138 If you want to handle the control flow and to generate login forms,
139 redirections, etc., yourself, you can say
140 C<< $divert = $request->check_divert >>.  This returns undef if
141 the user is logged in, or I<divert spec> if some kind of login
142 page or diversion should be generated.
143
144 xxx see below
145
146 =head2 MUTATING OPERATIONS AND EXTERNAL LINKS
147
148 =head3 Mutation-ignorant applications
149
150 By default CGI::Auth::Flexible does not permit external links into
151 your site.  All GET requests give a "click to continue" page which
152 submits a form which loads your app's main page.  In this
153 configuration all your application's forms and AJAX requests should
154 use C<POST>.  This restriction arises from complicated deficiencies
155 in the web's security architecture.
156
157 Such applications are also not able to provide user-specific CSS
158 stylesheets, javascript, favicons, etc.
159
160 =head3 Mutation-aware applications
161
162 The alternative is for your application to always make a special check
163 when the incoming request is going to do some kind of action (such as
164 modifying the user's setup, purchasing goods, or whatever) rather than
165 just retrieve and/or display information.  We term such requests
166 "mutating" requests.
167
168 Then non-mutating pages can be linked to from other, untrustworthy,
169 websites.
170
171 To support external links, and C<GET> requests, pass
172 C<< promise_check_mutate => 1 >> in I<settings>, and then call
173 C<< $authreq->check_mutate() >> before taking any actions.  If the
174 incoming request is not suitable then C<< $authreq->check_mutate() >>
175 will call C<die>.
176
177 There have to be no mutating C<GET> requests in your application (but
178 you shouldn't have any of those anyway); if there are, they won't
179 work.  (CGI::Auth::Flexible will spot them and cause them to fail,
180 rather than allow them to be insecure.)
181
182 =head2 GENERATING URLS, FORMS AND AJAX QUERIES
183
184 When you generate a URL, C<POST> form or AJAX request you may need to
185 include a secret hidden form parameter for the benefit of
186 CGI::Auth::Generic.  This form parameter will be checked by
187 C<check_ok>/C<check_divert> and should be ignored by your application.
188
189 By default the hidden parameter is called C<caf_assochash>.
190
191 After calling C<check_ok> or C<check_divert> the value to put in your
192 form can be obtained from C<secret_hidden_val>; C<secret_hidden_html>
193 will generate the whole HTML C<< <input...> >> element.
194
195 =head3 Mutation-ignorant applications
196
197 For mutation-ignorant applications (see above), all forms etc. should
198 include the hidden parameter (and as discussed, they must all use
199 POST rather than GET).
200
201 =head3 Mutation-aware applications
202
203 For mutation-aware applications, whether to include the secret
204 parameter depends on the kind of request.  CGI::Auth::Flexible knows
205 when it is necessary.  You should find out by calling
206 C<need_add_hidden>.
207
208 If it is inconvenient to call C<need_add_hidden> at runtime, you can
209 rely instead on the following promises:  All POST requests (which
210 includes all mutating requests) need the parameter.  The return value
211 of need_add_hidden depends only on the $method and $reqtype
212 parameters, so you can query it once and remember the answer.
213 HTML page load GETs do not need the parameter.  It is better to
214 err on the side of including the parameter.
215
216 If you really must, you can call C<need_add_hidden> "on the bench"
217 during development and bake the answer into your application code
218 structure.  However, if you do that and a new vulnerability was
219 discovered which is fixed by changing the answer, updating
220 CGI::Auth::Flexible wouldn't be sufficient to fix it.
221
222 =head3 Mutation-aware applications - non-page requests
223
224 If your mutation-aware application supports non-page resources (AJAX
225 and JSON requests, stylesheets, favicons, etc.) it must inform
226 CGI::Auth::Flexible when it is handling such a request, by calling
227 C<check_nonpage>.
228
229 Normally C<check_nonpage> will simply return (and you can ignore the
230 return value).  However, if there is an attack (or, perhaps, a bug) it
231 will die, stopping the attack.
232
233 (You do not need to call C<check_nonpage> for POST requests, but it is
234 harmless to do so.)
235
236 =head2 DATA STORAGE
237
238 CGI::Auth::Flexible needs to store various information in plain files;
239 it does this in the directory specified by the C<dir> parameter.
240
241 =head1 SOURCE CODE DOWNLOAD
242
243 By default, CGI::Auth::Flexible provides a facility for users to
244 download the source code for the running version of your web
245 application.
246
247 This facility makes a number of important assumptions which you need
248 to check.  Note that if the provided facility is not sufficient
249 because your application is more sophisticated than it copes with (or
250 if you disable the builtin facility), you may need to implement a
251 functioning alternative to avoid violating the AGPLv3 licence.
252
253 Here are the most important (default) assumptions:
254
255 =over
256
257 =item *
258
259 Your app's source code is available by looking at @INC, $0 and
260 S<$ENV{'SCRIPT_FILENAME'}> (the B<source items>).  See
261 C<srcdump_listitems>.  Where these point to files or directories under
262 revision control, the source item is the whole containing vcs tree.
263
264 =item *
265
266 Specifically, there are no compiled or autogenerated Perl
267 files, Javascript resources, etc., which are not contained in one of
268 the source item directories.  (Files which came with your operating
269 system install don't need to be shipped as they fall under the system
270 library exception.)
271
272 =item *
273
274 You have not installed any modified versions of system
275 libraries (including system-supplied Perl modules) in C</usr> outside
276 C</usr/local>.  See C<srcdump_system_dir>.
277
278 =item *
279
280 For each source item in a dvcs, the entire dvcs history does
281 not contain anything confidential (or libellous).  Also, all files which
282 contain secrets are in the dvcs's I<.ignore> file.  See
283 C<srcdump_vcsscript_git> et al.
284
285 =item *
286
287 For each source item NOT in a dvcs, there are no confidential
288 files with the world-readable bit set (being in a world-inaccessible
289 directory is not sufficient).  See C<srcdump_excludes>.
290
291 =item *
292
293 You have none of your app's source code in C</etc>.
294
295 =item *
296
297 You don't regard pathnames on your server as secret.
298
299 =item *
300
301 You don't intentionally load Perl code by virtue of C<.>
302 being in C<@INC> by default.  (See C<srcdump_filter_cwd>.)
303
304 =back
305
306 =head1 MAIN FUNCTIONS AND METHODS
307
308 =over
309
310 =item C<< CGI::Auth::Flexible->new_verifier(setting => value, ...) >>
311
312 Initialises an instance and returns a verifier object.
313 The arguments are setting pairs like a hash initialiser.
314 See L</SETTINGS> below.
315
316 =item C<< $verifier->new_request($cgi_query) >>
317
318 Prepares to process a request.  I<$cgi_query> should normally
319 be the query object from L<CGI(3perl)>.  Most of the default
320 hook methods assume that it is; however if you replace enough of
321 the hook methods then you can pass any value you like and it
322 will be passed to your hooks.
323
324 The return value is the authentication request object (I<$authreq>)
325 which is used to check the incoming request and will contain
326 information about its credentials.
327
328 =item C<< $authreq->check_divert() >>
329
330 Checks whether the user is logged in.  Returns undef if the user is
331 logged in and we should service the request.  Otherwise returns a
332 divert spec (see L</DIVERT SPEC>) saying what should happen instead.
333
334 This method may die if it doesn't like the request, in which case
335 the request needs to be rejected.
336
337 =item C<< $authreq->check_ok() >>
338
339 Checks whether the user is logged in.  Returns true if the user is
340 logged in and we should service the request.
341
342 Otherwise it handles the request itself, generating any appropriate
343 redirect, login form, or continuation page.  It then returns false and
344 the application should not process the request further.
345
346 =item C<< $verifier->disconnect() >>
347
348 Discards the resources (open files, etc.) in the verifier object.
349
350 =back
351
352 =head REQUEST-HANDLING FUNCTIONS AND METHODS
353
354 All of these are only valid after C<check_divert> or C<check_ok> has
355 been called.  (In the case of C<check_ok> it won't normally be sensible
356 to call these functions unless C<check_ok> returned true.)
357
358 =item C<< $authreq->get_divert() >>
359
360 Returns the value previously returned by C<check_divert>.
361
362 =item C<< $authreq->get_username() >>
363
364 Returns the name of the logged-in user.  If the user was not logged
365 in (or their session had timed out, or something), returns undef.
366
367 =head RESPONSE-RELATED FUNCTIONS AND METHODS
368
369 =item C<< $authreq->url_with_query_params($params, [$nonpagetype]) >>
370
371 Convenience function which returns a url for a GET request to this
372 application.
373
374 I<$params> is a hashref specifying the parameters and the PATH_INFO.
375 The keys are the parameter names, and the values are array refs with
376 the parameter value(s) (as strings, as yet unquoted).  (They are array
377 refs because it is possible to pass multiple values for the same
378 parameter in a single request; normally each arrayref would be a
379 singleton.)
380
381 The request path will be the path to the application.  If a parameter
382 with name C<< '' >> is supplied, it is taken as the PATH_INFO - its
383 value will be appended to the application path.  (It should normally
384 start with C<< / >>, and only one value should be supplied.)
385
386 =item C<< $authreq->chain_params() >>
387
388 Returns a hash of the "relevant" parameters to this request, in a form
389 used by XXX.  This is all of the query parameters which are not
390 related to CGI::Auth::Flexible.  The PATH_INFO from the request is
391 returned as the parameter C<< '' >>.
392
393 =back