student numbers
[ssproject1617.git] / report / v2_authentication.tex
1
2 \begin{enumerate}[label={V2.\arabic*}]
3
4 \item
5 \fail{}
6 Verify all pages and resources by default require
7 authentication except those specifically intended to be
8 public (principle of complete mediation).
9
10 \begin{result}
11 All admin pages are private. Unpublished posts are also private.
12 However, the install submission page does not do any authentication at all,
13 allowing any user to reset the database and claim an admin account.
14 User pages can be viewed (and submitted) by any authenticated user.
15 \end{result}
16
17 \item
18 \fail{}
19 Verify that forms containing credentials are not filled in by
20 the application. Pre-filling by the application implies that
21 credentials are stored in plain-text or a reversible format,
22 which is explicitly prohibited.
23
24 \begin{result}
25 No credentials that come from the database are pre-filled by the application.
26 However, in some forms, the application pre-fills password fields from the
27 request's POST data. This is not necesarry.\footnote{This issue was actually
28 overlooked when auditing manually, and was found when running the Fortify tool.
29 In the initial audit, we only ensured that no internal information (from the
30 database) was leaked in this way.}
31 \end{result}
32
33 \setcounter{enumi}{3}
34
35 \item
36 \pass{}
37 Verify all authentication controls are enforced on the
38 server side.
39
40 \begin{result}
41 All authentication controls (login credentials and client cookies) are
42 enforced by the application. Note however item~\ref{auth:6}, about the
43 security of these controls in the implementation.
44 \end{result}
45
46 \setcounter{enumi}{5}
47
48 \item\label{auth:6}
49 \fail{}
50 Verify all authentication controls fail securely to ensure
51 attackers cannot log in.
52
53 \begin{result}
54 The input to various forms is not sanitized at all. This makes the implementation
55 in (not only) \code{Users::find} vulnerable to \SQL{} injections. Through this vulnerability,
56 an attacker can execute arbitrary \SQL{} code from the username field in the login form.
57 The following example code can submitted as username in the login form, which
58 will set the password of the \code{admin} user to \code{s3cret}:
59
60 \code{"; UPDATE users SET password='\$1\$OWgsBb90\$Lkko6aZwmp9XOVrFI09Ab0' WHERE \\username='admin' AND 'a' = "a}
61
62 After using this exploit, the attacker (of course) knows the admin password.
63 \end{result}
64
65 \item
66 \pass{}
67 Verify password entry fields allow, or encourage, the use
68 of pass-phrases, and do not prevent password managers,
69 long pass-phrases or highly complex passwords being
70 entered.
71
72 \begin{result}
73 The application allows the user to use any password (except ones that trigger
74 errors in injected \SQL{} code).
75 \end{result}
76
77 \item
78 \pass{}
79 Verify all account identity authentication functions (such
80 as update profile, forgot password, disabled / lost token,
81 help desk or IVR) that might regain access to the account
82 are at least as resistant to attack as the primary
83 authentication mechanism.
84
85 \begin{result}
86 The only alternative mechanism for authenticating (except for using
87 vulnerabilities as described in other point) is using the ``Recover
88 password'' functionality. This sends a secret token to the email
89 address owning the account.
90
91 After such a token is used, it cannot be reused, because the token is
92 derived from the password hash (and thus a random salt). Tokens do not
93 expire, however. It would be even better to require that a token be used
94 withing a day (or so) after creation.
95
96 The security of the \SMTP{} connection is at the discretion of the web server.
97 Often these connections are not very secure, but this worry is beyond the
98 scope of this audit.
99 \end{result}
100
101 \item
102 \fail{}
103 Verify that the changing password functionality includes
104 the old password, the new password, and a password
105 confirmation.
106
107 \begin{result}
108 Changing a user's password does not require the original password, nor does the
109 password Changing form request for a password confirmation. This makes it easy
110 to set a wrong password for yourself.
111 \end{result}
112
113 \setcounter{enumi}{11}
114
115 \item
116 \fail{}
117 Verify that all authentication decisions can be logged,
118 without storing sensitive session identifiers or passwords.
119 This should include requests with relevant metadata
120 needed for security investigations.
121
122 \begin{result}
123 The application does not log any notable authentication event.
124 \end{result}
125
126 \item
127 \fail{}
128 Verify that account passwords are one way hashed with a
129 salt, and there is sufficient work factor to defeat brute
130 force and password hash recovery attacks.
131
132 \begin{result}
133 Password are stored in database using the \PHP{} function \code{crypt}. Internally, this
134 function uses salted MD5 on modern UNIX systems. On legacy systems, this uses an old DES
135 based algorithm, which uses only the first eight characters of the supplied password.
136 This is way too easy to reverse with brute-force attacks using dictionary files.
137
138 Instead the \CMS{} should use the \code{argon2} password hashing algorithm
139 or the \PHP{} \code{password\_hash} function (which currently uses BCRYPT) which are
140 (at this moment) considered safe to use.
141 \end{result}
142
143 \setcounter{enumi}{15}
144
145 \item
146 \fail{}
147 Verify that credentials are transported using a suitable
148 encrypted link and that all pages/functions that require a
149 user to enter credentials are done so using an encrypted
150 link.
151
152 \begin{result}
153 The app allows admin users to log in over \HTTP{}. This is insecure, as it allows
154 eavesdroppers to intercept any password.
155 The app should force \HTTPS{} for at least the login form, the \code{admin\_controller} and
156 for the installation script (because the users posts secrets like the database
157 password to this page and the \CMS{} supplies the user with the credentials of the \code{admin}
158 account).
159 \end{result}
160
161 \item
162 \pass{}
163 Verify that the forgotten password function and other
164 recovery paths do not reveal the current password and
165 that the new password is not sent in clear text to the user.
166
167 \begin{result}
168 No password is stored in plain text. The password recovery path works with
169 a secret token, which is used to reset the password. Although this token
170 is derived from the password hash, it does not reveal any secret
171 information.
172 \end{result}
173
174 \item
175 \fail{}
176 Verify that information enumeration is not possible via
177 login, password reset, or forgot account functionality.
178
179 \begin{result}
180 All these forms are vulnerable to \SQL{} injection attacks. So any information
181 can leak any information from the database.
182 \end{result}
183
184 \item
185 \pass{}
186 Verify there are no default passwords in use for the
187 application framework or any components used by the
188 application (such as “admin/password”).
189
190 \begin{result}
191 No secrets are initialized by predefined values. The admin user will have
192 username \code{admin} by default. This is no secret and therefore not
193 considered unsafe.
194 \end{result}
195
196 \item
197 \fail{}
198 Verify that anti-automation is in place to prevent breached
199 credential testing, brute forcing, and account lockout
200 attacks.
201
202 \begin{result}
203 No anti-automation measures are deployed.
204
205 This is needed for:
206 \begin{itemize}
207 \item Email validation, to harden brute force email address discovery
208 \item Installation database check, to prevent guessing attacks for the database password
209 \item Login, to prevent login guessing
210 \item And comment submission, to prevent spam, phishing et cetera (by
211 using some CAPTCHA software.
212 \end{itemize}
213 \end{result}
214
215 \item
216 \fail{}
217 Verify that all authentication credentials for accessing
218 services external to the application are encrypted and
219 stored in a protected location.
220
221 \begin{result}
222 The database credentials are hard-coded in \code{config.php}. While it
223 would be better to pass secrets as environment variables, this is not
224 really bad practice.
225
226 However, the installation instructions state the following:
227 \begin{verbatim}
228 Change the file permissions to allow all users write access to the
229 folder you extracted TestCMS to.
230 \end{verbatim}
231 This implies making the configuration file readable for all users on the
232 system. This information should not be accessible for any user other than
233 running the \PHP{} script.
234 \end{result}
235
236 \item
237 \pass{}
238 Verify that forgotten password and other recovery paths
239 use a \TOTP{} or other soft token, mobile push, or other
240 offline recovery mechanism. Use of a random value in an
241 e-mail or SMS should be a last resort and is known weak.
242
243 \begin{result}
244 The password recovery path uses a random looking token. It is sent over
245 e-mail, which is considered weak (but not unsafe).
246 \end{result}
247
248 \item
249 \fail{}
250 Verify that account lockout is divided into soft and hard
251 lock status, and these are not mutually exclusive. If an
252 account is temporarily soft locked out due to a brute force
253 attack, this should not reset the hard lock status.
254
255 \begin{result}
256 The application has not implemented any lockout mechanisms.
257 \end{result}
258
259 \item
260 \pass{}
261 Verify that if shared knowledge based questions (also
262 known as ``secret questions'') are required, the questions
263 do not violate privacy laws and are sufficiently strong to
264 protect accounts from malicious recovery.
265
266 \begin{result}
267 The application uses no shared knowledge based questions, and thus not
268 violate any privacy laws.
269 \end{result}
270
271 \item
272 \fail{}
273 Verify that the system can be configured to disallow the
274 use of a configurable number of previous passwords.
275
276 \begin{result}
277 The system does not remember any previously used passwords and does not
278 require variation in the use of different passwords.
279 \end{result}
280
281 \item
282 \pass{}
283 Verify that risk based re-authentication, two factor or
284 transaction signing is in place for high value transactions.
285
286 \begin{result}
287 There are no (really) risk based action for which re-authentication would be
288 fit.
289 \end{result}
290
291 \item
292 \fail{}
293 Verify that measures are in place to block the use of
294 commonly chosen passwords and weak pass-phrases.
295
296 \begin{result}
297 No password strengthening measures are implemented. The app should
298 use some password strength estimator like \texttt{zxcvbn}\footnote{\url{https://github.com/dropbox/zxcvbn}}.
299 \end{result}
300
301 \notapplicable{
302 \item
303 % \fail{}
304 Verify that all authentication challenges, whether
305 successful or failed, should respond in the same average
306 response time.
307
308 % \begin{result}
309 % String comparisation for checking password hashes and password reset
310 % tokens are not in constant time.
311 % \end{result}
312 }
313
314 \notapplicable{
315 \item
316 % \fail{}
317 Verify that secrets, \API{} keys, and passwords are not
318 included in the source code, or online source code
319 repositories.
320
321 % \begin{result}
322 % The database credentials are hard coded in \code{config.php}. These
323 % credentials should ideally be passed using environment variables.
324 % \end{result}
325 }
326
327 \setcounter{enumi}{30}
328
329 \item
330 \fail{}
331 Verify that if an application allows users to authenticate,
332 they can authenticate using two-factor authentication or
333 other strong authentication, or any similar scheme that
334 provides protection against username + password
335 disclosure.
336
337 \begin{result}
338 No such features are implemented.
339 \end{result}
340
341 \item
342 \fail{}
343 Verify that administrative interfaces are not accessible to
344 untrusted parties.
345
346 \begin{result}
347 Any authenticated user is allowed to view and use the administrative
348 interface. A separation should be made between administrators and normal
349 users.
350 \end{result}
351
352 \item
353 \pass{}
354 Browser auto-complete, and integration with password
355 managers are permitted unless prohibited by risk based
356 policy.
357
358 \begin{result}
359 Browser auto-complete functionality is not restricted in any way.
360 \end{result}
361
362 \end{enumerate}