Corrected $* mismatch in CGIservlet.pl
[CGIscriptor.git] / PrivateTutorial.html
blob17a2e604b0ba7cfc2162a9096b9a6f5b3f783bf8
1 <html>
2 <head>
3 <title>Tutorial: How to set up login accounts</title>
4 </head>
5 <body>
6 <p>
7 <table width='100%'><tr>
8 <td style='text-align: left'><a href="/index.html">Home</a></td>
9 <td style='text-align: right'><a href="/Private/index.html?LOGOUT">Logout</a></td>
10 </tr></table>
11 </p>
12 <h1 style="text-align: Center">Tutorial: How to set up login accounts</h1>
13 <h3 style="text-align: Center">WARNING</h3>
14 <p style="margin-left: 20%; margin-right: 20%; text-align: justified;font-style: italic">
15 The current implementation of an authenticating and authorization procedure
16 (Password Login) in <em>CGIscriptor.pl</em> is experimental and meant as an illustration
17 for the use of the framework. The code has not been reviewed. <br />
18 Before you use this procedure on your site, be sure you understand the limitations of the
19 implemented procedures. You should evaluate first whether the procedures address your
20 security needs and second whether the code implements the procedures correctly.
21 </p>
24 <h2 style="text-align: Center">Introduction</h2>
25 <p style="text-align: Left">
26 In situations where pages and services must be limited to authorized
27 persons, it is possible to activate a login procedure when a certain page
28 or url is requested. The authentication is done by requesting a user
29 name and a password. The server stores information about the passwords
30 and privileges of individual users.
31 </p>
32 <p style="text-align: Left">
33 The method used to authorize requests is a server side session ticket.
34 The client (user) browser will send an identifier token that is compared
35 with the expected identifier. Only if the token is accepted, will the
36 requested page be processed and send to the client. Identifier tokens
37 can be send as cookies or as CGI variables. There is no difference
38 between these two methods. If possible, use cookies as they are more
39 convenient. Note that the ticket identifiers rely on the use of
40 <a href="http://www.xul.fr/en/html5/sessionstorage.php">browser
41 SessionStorage</a>. If the browsers of clients do not support
42 <a href="http://www.xul.fr/en/html5/sessionstorage.php">browser
43 SessionStorage</a>, your choices will be limited.
44 </p>
46 <h2 style="text-align: Center">How to protect services with a password login</h2>
47 <p style="text-align: Left">
48 The variable <em>%TicketRequiredPatterns</em> contains a set of URL patterns that
49 should be protected by a password login. Each pattern points to a
50 directory where login sessions are stored (<tt>Private/.Sessions</tt>),
51 account information (<tt>Private/.Passwords</tt>), the login page
52 that should be shown for that URL (<tt>Private/Login.html</tt>),
53 and finaly the default expire time for a session (<tt>+36000</tt>,
54 i.e., 36 thousand seconds = 10 hours).
55 <pre>
56 # File patterns of files which are handled by session tickets.
57 %TicketRequiredPatterns = (
58 '^/Private(/|$)' => "Private/.Sessions\tPrivate/.Passwords\t/Private/Login.html\t+36000"
60 </pre>
61 </p>
63 <h2 style="text-align: Center">Session types</h2>
65 <p style="text-align: Left">
66 Security comes with costs attached. The more stringent the authentication should
67 be, the more complex the authentication process will have to be. To allow a meaningful
68 tradeof between security and costs, three levels of authentication are implemented.
69 </p>
70 <p style="text-align: Left">
71 <ol>
72 <li>IPADDRESS: Remote client IP address<br />
73 Use the (apparent) IP address of the client as an identification.
74 Simple and not secure
75 </li>
76 <li>SESSION: Single session token<br />
77 Create a single token that the client can use during the session.
78 But also use the IP address. Relatively straightforeward and reasonably
79 secure.
80 </li>
81 <li>CHALLENGE: One time session tokens<br />
82 The client has to generate a new token for every request. Each token
83 can be used only once. The new token is constructed from a random
84 string send from the server and the stored password. This can be used
85 to prevent session hijacking by a third party who can simulate the same
86 IP address, or if the IP address is not fixed, e.g., when using Tor.
87 </li>
88 </ol>
89 It is adviced to use the SESSION (single session token) type unless there are
90 specific reasons to increase security, eg, for the admin acount or Tor sessions.
91 </p>
93 <h2 style="text-align: Center">Password account tickets</h2>
95 <p style="text-align: Left">
96 This is an annotated example of a PASSWORD account ticket. At the right hand side is the literal text as present in the Account file.
97 All regex patterns are <a href="http://www.regular-expressions.info/perl.html">Perl regex patterns</a>.
98 </p>
99 <p>
100 <table>
101 <tr><td style="text-align: Right">The type of the ticket</td><td>&nbsp;</td><td><tt>Type: PASSWORD</tt></td></tr>
102 <tr><td style="text-align: Right">Official username, lower cast</td><td>&nbsp;</td><td><tt>Username: testchallenge</tt></td></tr>
103 <tr><td style="text-align: Right">Hashed and encrypted password</td><td>&nbsp;</td><td><tt>Password: 6df7d66e8832ee52a9aba5e474ce8641a9577eff140d54b297b61443bf8d9eb1</tt></td></tr>
104 <tr><td style="text-align: Right">Allowed IP addresses, a regex pattern</td><td>&nbsp;</td><td><tt>IPaddress: 127.0.0.1</tt></td></tr>
105 <tr><td style="text-align: Right">Allowed paths in the web site, a regex pattern</td><td>&nbsp;</td><td><tt>AllowedPaths: ^/Private/index\.html$</tt></td></tr>
106 <tr><td style="text-align: Right">idem</td><td>&nbsp;</td><td><tt>AllowedPaths: ^/Private/[^/]+\.html$</tt></td></tr>
107 <tr><td style="text-align: Right">idem</td><td>&nbsp;</td><td><tt>AllowedPaths: ^/Private/?$</tt></td></tr>
108 <tr><td style="text-align: Right">Privileges, in this case allowed to hop proxies</td><td>&nbsp;</td><td><tt>Capabilities: VariableREMOTE_ADDR</tt></td></tr>
109 <tr><td style="text-align: Right">The server salt used to hash the password</td><td>&nbsp;</td><td><tt>Salt: e93cf858a1d5626bf095ea5c25df990dfa969ff5a5dc908b22c9a5229b525f65</tt></td></tr>
110 <tr><td style="text-align: Right">Allowed session type</td><td>&nbsp;</td><td><tt>Session: CHALLENGE</tt></td></tr>
111 <tr><td style="text-align: Right">A signature of important aspects of this ticket</td><td>&nbsp;</td><td><tt>Signature: eca5b95e3ff4a9628be4c6f1fca29ec2f5981cbbba0b29ce5b601055926a8720</tt></td></tr>
112 <tr><td style="text-align: Right">Maximum lifetime of a session, 45 minutes</td><td>&nbsp;</td><td><tt>MaxLifetime: +45m</tt></td></tr>
113 </table>
114 The above account contains a contradiction. Although it has <em></em>Capabilities: VariableREMOTE_ADDR</em>,
115 it is also limited to the local machine, <em>IPaddress: 127.0.0.1</em> (IPaddress is matched from the start).
116 The default account in this example has been locked down for distribution. Shipping a default account that
117 could be accessed from the outside would be a security hazard. You are adviced to change the
118 password before you change any of the default accounts.
119 </p>
121 An example <em>Create User Account</em> page is added. When logged in as any user, you can go to this
122 page and enter your own password (the one you used to log in), the user name, and password of the new
123 user. Below that, the allowed pages and IP addresses can be entered as a <em>;</em> separated list of
124 regular expression patterns. After sumitting the form, the text of the account file will be printed
125 on the page. These texts can be saved in the <em>.Passwords</em> directory.
126 However, if the <em>admin</em> account is activated, that user can create active new accounts directly.
127 With each new user, a home directory is automatically created as a copy of the
128 <em>Private/.SkeletonDir</em> directory.
129 </p>
131 <h2 style="text-align: Center">Account signatures and activation</h2>
133 <p style="text-align: Left">
134 Reading the passwords or any change in the account files by other users of the servers could
135 lead to a compromize of the system. Therefore, it is possible to encrypt passwords and sign
136 accounts (and session tickets). If the web server supports an environment variable with the
137 name <em>CGIMasterKey</em> (<em>$ENV{CGIMasterKey}</em>), the value of that variable will be used as
138 a pass phrase. <em>$ENV{CGIMasterKey}</em> will be used to encrypt the password and create
139 a signature of the account and session tickets. Any account or session ticket with an
140 invalid signature will be discarded. Both the encryption keys and the signatures will be
141 constructed from the server side salt and the user name. This means that if you change the
142 server side salt or CGIMasterKey, you will have to reset all passwords and recreate all
143 signatures.
144 </p>
145 <p style="text-align: Left">
146 Activating an account means that the password is set and a correct signature is created.
147 Setting passwords and generating signatures can be done with <em>CGIscriptor.pl</em> on the command line.
148 The following command will set a new password and signature for the testchallenge account:<br /><tt>
149 perl CGIscriptor.pl --managelogin salt=Private/.Passwords/SALT
150 masterkey='Sherlock investigates oleander curry in Bath'
151 password='testing' Private/.Password/testchallenge
152 </tt><br />
153 Note that the creation time of the account (if present) will be part
154 of the signature. This will make that every new account file will have a
155 unique signature. Even if all the other contents are the same. The password
156 is <em>not</em> part of the signature, nor are any comments.
157 </p>
159 <h2 style="text-align: Center">Creating web pages</h2>
160 <p style="text-align: Left">
161 <em>IPADDRESS</em> type sessions do not require any changes in web pages
162 after login. <em>SESSION</em> type sessions require JavaScript code in
163 the page the client lands on after login to continue. But later pages
164 can be plain. <em>CHALLENGE</em> type sessions require JavaScript code
165 on every single protected page (actually, only to get to the next page
166 after that). To add support for the login sessions to simple web pages, add the
167 following code to the HEAD section of each HTML file:
168 </p>
169 <pre>
170 &lt;script type="text/javascript"&gt;
171 &lt;SCRIPT TYPE="text/ssperl" SRC="./JavaScript/PlainPage.js"&gt;&lt;/SCRIPT&gt;
172 &lt;/script&gt;
173 </pre>
174 <p style="text-align: Left">
175 Pages that require a user to enter username or password require special
176 <em>window.onload</em> code as well as special <em>onSubmit</em> code
177 for the FORM fields, eg, <em>LoginSubmit()</em>,
178 <em>ChangePasswordSubmit ()</em>, and <em>CreateUserSubmit ()</em>.
179 For the Login page, change <em>PlainPage.js</em> into <em>LoginPage.js</em>
180 in the above code snippet.
181 For Change Password and Create User use, respectively, <em>ChangePasswordPage.js</em>
182 and <em>CreateUserPage.js</em>. The following FORM ID and CGI parameter
183 names should be used (FORM element ID):
184 <ul>
185 <li>CGIUSERNAME<br />
186 The account name of the current user (also if hidden)</li>
187 <li>NEWUSERNAME<br />
188 The new account name when creating a user</li>
189 <li>PASSWORD<br />
190 The password. Password visibility can be toggled with<br />
191 <em>onClick="this.value=togglePasswords('Hide', 'Show', this.value);true"</em></li>
192 <li>NEWPASSWORD<br />
193 The new password for Change Password or Create User</li>
194 <li>NEWPASSWORDREP<br />
195 Repetition of the new password for Change Password or Create User.
196 <em>onChange='check_password_fields()'</em> will check whether both
197 fields are identical and set the Submit button</li>
198 <li>SUBMIT<br />
199 ID of the Submit button, used to grey out the button until all fields
200 are entered
201 </li>
202 </li>
203 <li>LOGINTICKET<br />
204 Sending the login ticket when entering a password. Should not be changed by the user</li>
205 </ul>
206 FORM ID and CGI parameter names that are optional as they are set by the server
207 and also exchanged by cookies. All contain server generated hexadecimal hashes.
208 Use the FORM ID versions when you use form fields instead of cookies:
209 <ul>
210 <li>SERVERSALT</li>
211 <li>RANDOMSALT</li>
212 <li>SESSIONTICKET</li>
213 <li>CHALLENGETICKET</li>
214 </ul>
216 </p>
218 If all accounts are restricted to <em>IPADDRESS</em> and <em>SESSION</em> type login, and
219 adaptation of web pages is not feasible, it is possible to set the
220 required session cookie in the login page. Add
221 <em>setSessionParameters();true</em> after the <em>LoginSubmit()</em>
222 funtion in the Login page:
223 <pre>
224 onSubmit='LoginSubmit();setSessionParameters();true'
225 </pre>
226 Now, standard, plain, HTML web pages can be used throughout the site. However, the
227 <em>CHALLENGE</em> session type is insecure with this option, and it is disabled.
228 You might have to change the <em>admin</em> account if you want to use
229 this option.
230 </p>
231 </body>
232 </html>