Add a warning about the security hole :-(
[raven/abandoned/asp.git] / README.md
1 WARNING: THIS SOFTWARE IS UNSUPPORTED AND HAS A SECURITY PROBLEM - DO NOT USE WITHOUT MODIFICATION
2 =========================================================================
3
4 This code has a path traversal vulnerability, and needs updating to
5 validate the new, stricter definition of the "kid" field (1-8 digits,
6 not beginning '0'). **Do not use it** without fixing this issue. If
7 you do fix this issue, please email raven-support@ucs.cam.ac.uk your
8 patch ;-)
9
10 University of Cambridge Classic ASP/VBScript Raven Authentication Module - v.1.0 (29/04/2014)
11 ==========================================================================
12
13 Description
14 -----------
15 This software comprises a VBScript class 'Ucam\_Webauth' and sample
16 files that provide a Classic ASP/VBScript implementation of a 'Raven'
17 authentication module; Raven is the web authentication protocol used
18 by the University of Cambridge, UK. The logic and code of the
19 'Ucam\_Webauth' class are loosely based on the PHP Raven authentication
20 class provided at [http://raven.cam.ac.uk/project/](http://raven.cam.ac.uk/project/).
21 - For a full description of the latest Raven specification and an explanation
22 of how Raven works, go to [http://raven.cam.ac.uk/project/](http://raven.cam.ac.uk/project/).
23 - This software was originally created for the Careers Service,
24 University of Cambridge by sh801@cam.ac.uk. For support, please
25 contact raven-support@ucs.cam.ac.uk
26
27 Files and folders
28 -----------------
29 - [certificates]: Temporary location for Raven public key certificates.
30 - [js]: Folder containing Javascript cryptography libraries.
31 - [docs]: Supporting documentation.
32 - [logs]: Possible location for log files created by the module.
33 - Default.asp: A sample file showing how the 'Ucam_Webauth' class is used
34 to provide Raven authentication.
35 - Test.asp: A test file for unit testing the 'Ucam\_Webauth' module using the
36 'Ucam\_RavenWLS' dummy Raven server (separate project, not included).
37 - Ucam\_Webauth.vbs: The main 'Ucam\_Webauth' VBScript class.
38
39 Platform requirements
40 ---------------------
41 This module has been tested on IIS7 with .NET Framework set to
42 'No managed code', ie. classic ASP.
43
44 Installation
45 ------------
46 ### Cryptographic functions
47 Cryptographic functions are provided by the Javascript libraries
48 within the 'js' folder. These libraries are versions of the
49 client-side Javascript libraries provided at
50 [http://kjur.github.io/jsrsasign/index.html](http://kjur.github.io/jsrsasign/index.html)
51 but modified to run server-side. There is no need to install any
52 additional cryptography libraries.
53
54 ### Install Raven certificates
55 The authentication module uses the Raven public key certificate at
56 [https://raven.cam.ac.uk/project/keys/](https://raven.cam.ac.uk/project/keys/)
57 to verify authentication responses. Download the certificate from
58 [https://raven.cam.ac.uk/project/keys/](https://raven.cam.ac.uk/project/keys/)
59 and copy to the 'certificates' folder provided with this
60 authentication module download - the 'certificates' folder is a
61 temporary location for the certificate while you get the module up and
62 running. You will need to supply the full path to the 'certificates'
63 folder as either a 'key\_dir' argument to the 'Ucam\_Webauth'
64 constructor or by modifying the 'Ucam\_Webauth' variable
65 'DEFAULT\_KEY\_DIR' directly.
66
67 Once you have everything working, move the 'certificates' folder
68 to a new location on your webserver that is not web- or publicly-accessible
69 and modify the 'key\_dir' string accordingly.
70
71 - NOTE: you may have to change the name of the key file from 'pubkey2.crt'
72 to '2.crt'.
73
74 If you're using the Raven test server
75 ([http://raven.cam.ac.uk/project/test-demo/](http://raven.cam.ac.uk/project/test-demo/))
76 for testing purposes, make sure you install the test server keys
77 instead, but ensure you remove these keys before using the
78 authentication module in a production environment, as recommended by
79 the demo Raven server:
80
81 > It is vital to keep these demo keys seperate from keys
82 > used with a production service - failure to do so could
83 > allow an attacker to successfully replay a response
84 > from the demonstration server, which anyone can easily
85 > obtain, against a production service.
86
87 Getting started
88 ---------------
89
90 The 'Ucam\_Webauth' VBScript class must be used within an ASP server-side page
91 as it interacts directly with a user's browser session. To use the
92 'Ucam\_Webauth' VBScript class:
93
94 1. Ensure the 'Ucam\_Webauth.vbs' class file and the folder 'js' are in the
95 same directory as your ASP script. The folders 'certificates' and 'logs' may
96 also be located here temporarily.
97 2. Include the 'Ucam_Webauth.vbs' class file in the 'head' of your ASP file:
98
99
100 <head>
101 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
102 <!--#include file="Ucam_Webauth.vbs"-->
103 </head>
104
105 3. Set up the initial arguments for the 'Ucam_Webauth' class:
106
107 Set args = CreateObject("Scripting.Dictionary")
108 args.Add "hostname", "localhost"
109 args.Add "auth_service", "https://demo.raven.cam.ac.uk/auth/authenticate.html"
110 args.Add "key_dir", "C:/Ucam_Webauth/certificates"
111
112 'args' is an associative array of *text* strings so parameter values must
113 be converted into strings, ie. numbers and booleans must be supplied within
114 quotes as in "23", "TRUE", "FALSE".
115 A full list of allowed parameters is provided at the end of this README.
116
117 4. Create an instance of the 'Ucam_Webauth' class from within your ASP
118 server page and initialize with setup variables:
119
120 Set oUcam_Webauth = New Ucam_Webauth
121 Call oUcam_Webauth(args)
122
123 5. Call 'Authenticate()' on the Ucam_Webauth object and act according to
124 the value returned:
125
126 Select Case oUcam_Webauth.Authenticate()
127
128 Case oUcam_Webauth.AUTHENTICATE_INCOMPLETE
129
130 ...
131 Exit Sub
132
133 Case oUcam_Webauth.AUTHENTICATE_COMPLETE_AUTHENTICATED
134
135 ...
136
137 Case oUcam_Webauth.AUTHENTICATE_COMPLETE_NOT_AUTHENTICATED
138
139 ...
140
141 Case oUcam_Webauth.AUTHENTICATE_COMPLETE_ERROR
142
143 ...
144
145 End Select
146
147 The four possible return values of 'Authenticate()' are:
148
149 - AUTHENTICATE\_INCOMPLETE : The authentication process has yet to complete.
150 The user may have been redirected to the Raven server and has yet to enter
151 their login details.
152 - AUTHENTICATE\_COMPLETE\_AUTHENTICATED : The authentication process completed
153 and the user has been successfully authenticated.
154 - AUTHENTICATE\_COMPLETE\_NOT\_AUTHENTICATED : The authentication process
155 completed and the user was not successfully authenticated.
156 The user may have clicked 'Cancel' at the Raven server.
157 - AUTHENTICATE\_COMPLETE\_ERROR : There was an error during the authentication
158 process forcing the authentication cycle to terminate early.
159
160 As the 'Authenticate()' function may need to send HTTP headers, it must be
161 called before any output (e.g. HTML, HTTP headers) is sent to the browser.
162
163 The 'Default.asp' file provided is a sample of a simple server page using
164 the 'Ucam_Webauth' VBScript class.
165
166 Overview of Raven process
167 -------------------------
168 A diagram of the Raven authentication process is located within the 'docs'
169 folder as [I - Overview of Raven Authentication Process.pdf].
170
171 The authentication cycle consists of the following key stages:
172
173 #### User first tries to access authenticated page
174 User tries to load an authenticated page on a particular website.
175 The 'Ucam_Webauth' class is loaded and the 'Authenticate()' function is called.
176 If no authentication cookie is found to indicate the user is authenticated,
177 the user's browser is redirected to a separate Raven server using a special
178 'Authentication Request'. The authentication request consists of a series of
179 authentication parameters encoded into the URL redirect as name/value pairs.
180
181 #### User is prompted for login information
182 The Raven server interprets the authentication request sent by the main
183 website and prompts the user for their username and password. The user may
184 then be successfully authenticated or may decide to click 'Cancel'. They are
185 redirected back to the main website with a series of 'Authentication Response'
186 parameters encoded into a 'WLS-Response' GET variable.
187
188 #### User redirected back to main webserver
189 The user's original page is loaded again and 'Authenticate()' is called a
190 second time. 'Ucam_Webauth' processes the new 'WLS-Response' GET value and,
191 if it's valid, sets an authentication cookie on the user's browser. The
192 user's original page is then loaded again.
193
194 #### User redirected back to main webserver again
195 With an authentication cookie now set, 'Authenticate()' checks the status
196 code contained in the value of the authentication cookie and returns either
197 'AUTHENTICATE\_COMPLETE\_AUTHENTICATED' or
198 'AUTHENTICATE\_COMPLETE\_NOT\_AUTHENTICATED'. If
199 'AUTHENTICATE\_COMPLETE\_AUTHENTICATED' is returned , the original page can
200 go on to display authenticated content to the user.
201
202 Specifics of module
203 -------------------
204 The 'Authenticate()' function is the overarching authentication function of
205 'Ucam_Webauth'. It performs some basic sanity checks using 'CheckSetup()'
206 then uses 'GetCurrentState()' to establish the current state of the
207 authentication process before branching accordingly. The possible return
208 values of 'GetCurrentState()' are:
209
210 #### STATE\_NEW\_AUTHENTICATION
211 A completely fresh authentication. 'SendAuthenticationRequest()' [*1*] is
212 then triggered which performs some basic data checks, sets the authentication
213 cookie to 'AUTHENTICATIONCOOKIE\_REDIRECT\_WLS' (to record where we are in the
214 authentication process) and redirects the user's browser to the Raven
215 authentication server with a series of authentication parameters
216 encoded as name/value pairs.
217
218 #### STATE\_WLS\_RESPONSE\_RECEIVED
219 The Raven authentication server has processed the user and has returned the
220 user's browser back to the original website with a series of authentication
221 response parameters encoded into the 'WLS-Response' GET variable.
222 'ProcessAuthenticationResponse()' [*2*] is then called which checks the
223 validity of the 'WLS-Response' value, sets an authentication cookie and
224 redirects the user back to the original page.
225
226 #### STATE\_WAA\_AUTHENTICATIONCOOKIE\_SET
227 A valid authentication cookie has been set
228 (<> AUTHENTICATIONCOOKIE\_REDIRECT\_WLS).
229 'ProcessAuthenticationCookie()' [*3*] is then called which checks the
230 validity of the cookie. If the cookie has expired,
231 'SendAuthenticationRequest()' is called again in case the user needs to
232 reauthenticate themselves. If the cookie is still valid, an
233 'AUTHENTICATE\_COMPLETE\_XXX' value is returned, indicating that the
234 authentication cycle has completed successfully.
235 NOTE: this may be true if the user has cancelled the authentication process,
236 in which case 'AUTHENTICATE\_COMPLETE\_NOT\_AUTHENTICATED' will be returned.
237
238 #### STATE\_ERROR
239 An error occurred, breaking the authentication cycle and returning
240 AUTHENTICATE\_COMPLETE\_ERROR to 'Authenticate()'. This return value will
241 also be generated by the other functions above if they generate an error.
242
243 ## Accompanying diagrams
244 Detailed diagrams of the Raven process flow for (i) a successful
245 authentication (ii) a cancelled authentication, are located in the 'docs'
246 folder as [II - Ucam\_Webauth - Flowchart for Valid Authentication.pdf] and
247 [III - Ucam\_Webauth - Flowchart for Cancelled Authentication.pdf], respectively.
248
249 The numbers on these diagrams correspond to the three key secondary functions
250 described above:
251 - *1*. SendAuthenticationRequest()
252 - *2*. ProcessAuthenticationResponse()
253 - *3*. ProcessAuthenticationCookie()
254
255 Other important functions include:
256
257 ### ResetState()
258 Attempts to reset state as if a new user has just loaded a fresh browser
259 window. This is typically used when a user has experienced an error and we
260 want to give them a fresh opportunity to try again.
261
262 ### check_signature(...)
263 Checks the signature provided by the Raven server, when it signed the
264 'WLS-Response' variable, is a valid signature for the data. This ensures the
265 data has not been tampered with.
266
267 ### hmac_sha1(...)
268 Creates a hash value for signing the local authentication cookie.
269
270 ### wls_encode/decode(...)
271 Encoding/decoding functions to allow base64 signatures to be sent within URLs.
272
273 Possible arguments to 'Ucam_Webauth'
274 ------------------------------------
275 (Based on documentation for PHP Raven authentication module)
276
277 - log_file :
278 The location for a log file that will record progress and track possible
279 errors. The folder containing the file must be read/writable by the webserver.
280 Default: log.txt
281
282 - response_timeout :
283 Responses from the central authentication server are time-stamped.
284 This parameter sets the period of time in seconds during which these
285 responses are considered valid.
286 Default: 30 seconds.
287
288 - key\_dir :
289 The name of the directory containing the public key certificate(s) required
290 to validate the authentication responses sent by the server.
291 Default: '/etc/httpd/conf/webauth\_keys'.
292
293 - max\_session\_life :
294 The maximum period of time in seconds for which an established session will
295 be valid. This may be overriden if the authentication reply contains a
296 shorter 'life' parameter. Note that this does NOT define an expiry time for
297 the session cookie. Session cookies are always set without an expiry time,
298 causing them to expire when the browser session finishes.
299 Default: 7200 (2 hours).
300
301 - timeout_message :
302 A re-authentication by the authentication service will be triggered when an
303 established session expires. This option sets a text string which is sent to
304 the authentication server to explain to the user why they are being asked to
305 authenticate again. HTML markup is suppressed as for the description
306 parameter described below.
307 Default: 'your login to the site has expired'.
308
309 - hostname (required) :
310 The fully-qualified TCP/IP hostname that should be used in request URLs
311 referencing the Ucam_Webauth-enabled application. This *must* be set, as it
312 is needed for multiple reasons - primarily security but also to avoid varying
313 hostnames in URLs leading to failed or inconsistent authentication.
314 No default.
315
316 - cookie\_key (required):
317 A random key used to protect session cookies from tampering. Any reasonably
318 unpredictable string (for example the MD5 checksum of a rapidly changing
319 logfile) will be satisfactory. This key must be the same for all uses of the
320 web authentication system that will receive the same session cookies (see the
321 cookie\_name, cookie\_path and cookie\_domain parameters below).
322 No default.
323
324 - cookie_name :
325 The name used for the session cookie.
326 When used for access to resources over HTTPS the string '-S' is appended to
327 this name.
328 Default: 'Ucam-Webauth-Session'.
329
330 - cookie\_path :
331 The 'Path' attribute for the session cookie. The default is the directory
332 component of the path to the script currently being executed. This should
333 result in the cookie being returned for future requests for this script and
334 for the other resources in the same 'directory'; see the important
335 information about the cookie\_key parameter above.
336 Default: '/'.
337
338 - cookie_domain :
339 The 'Domain' attribute for the session cookie. By default the 'Domain'
340 attribute is omitted when setting the cookie. This should result in the
341 cookie being returned only to the server running the script. Be aware that
342 some people may treat with suspicion cookies with domain attributes that are
343 wider than the host setting the cookie.
344 No default.
345
346 - auth_service : The full URL for the web login service to be used.
347 Default: 'https://raven.cam.ac.uk/auth/authenticate.html'
348
349 #### Authentication request properties
350 The following setup parameters prefixed with 'authrequest_' relate to
351 properties that will be sent to the authentication server as part of an
352 authentication request:
353
354 - authrequest_desc : A text description of the resource that is requesting
355 authentication. This may be displayed to the user by the authentication
356 service. It is restricted to printable ASCII characters (0x20 - 0x7e) though
357 it may contain HTML entities representing other characters. The characters
358 '<' and '>' will be converted into HTML entities before being sent to the
359 browser and so this text cannot usefully contain HTML markup.
360 No default.
361
362 - authrequest_params : Data that will be returned unaltered to the WAA in
363 any 'authentication response message' issued as a result of this request.
364 This could be used to carry the identity of the resource originally requested
365 or other WAA state, or to associate authentication requests with their
366 eventual replies. When returned, this data will be protected by the digital
367 signature applied to the authentication response message but nothing else is
368 done to ensure the integrity or confidentiality of this data - the WAA MUST
369 take responsibility for this if necessary.
370 No default.
371
372 - authrequest\_skew : Interpretation of response\_timeout is difficult if the
373 clocks on the server running the PHP agent and on the authentication server
374 are out of step. Both servers should use NTP to synchronize their clocks,
375 but if they don't then this parameter should be set to an estimate of the
376 maximum expected difference between them (in seconds).
377 Default: 0.
378
379 - authrequest_fail :
380 If TRUE, sets the fail parameter in any authentication request sent to the
381 authentication server to 'yes'. This has the effect of requiring the
382 authentication server itself to report any errors that it encounters, rather
383 than returning an error indication. Note however that even with this parameter
384 set errors may be detected by this module that will result in authentication
385 failing here.
386 Default: FALSE.
387
388 - authrequest\_iact :
389 If TRUE, then the 'iact' parameter provided to the authentication server is
390 set to 'yes'. If FALSE, then the 'iact' parameter is set to 'no'. If no value
391 is provided for 'authrequest\_iact', the 'iact' parameter is left blank.
392 The value 'yes' for 'iact' requires that a re-authentication exchange takes
393 place with the user. This could be used prior to a sensitive transaction in
394 an attempt to ensure that a previously authenticated user is still present
395 at the browser. The value 'no' requires that the authentication request will
396 only succeed if the user's identity can be returned without interacting with
397 the user. This could be used as an optimisation to take advantage of any
398 existing authentication but without actively soliciting one. If omitted or
399 empty, then a previously established identity may be returned if the WLS
400 supports doing so, and if not then the user will be prompted as necessary.
401 Default: omitted.