--- /dev/null
+# Authentication
+
+## 2.1 Verify that all private pages are indeed private
+All admin pages are private. Unpublished posts are also private.
+
+However, the install submission page does not do any authentication at all,
+allowing any user to reset the database and claim an admin account.
+
+User pages can be viewed and submitted by any authenticated user.
+
+## 2.2
+## 2.3
+## 2.4
+## 2.5
+## 2.6
+## 2.7
+## 2.8
+## 2.9
+Changing a user's password does not require the original password.
+
+## 2.10
+## 2.11
+## 2.12
+
+## 2.13 Password storage security
+Password are stored in database using the PHP function `crypt`. Internally, this
+functions uses salted MD5. This is way too easy to brute-force.
+
+Instead use `argon2` or the `password_hash` function.
+
+## 2.14
+## 2.15
+
+## 2.16
+The app allows admin users to log in over HTTP. This is insecure. Force HTTPS
+for the admin_controller and for the installation script.
+
+## 2.17
+## 2.18
+## 2.19
+
+## 2.20
+No anti-automation measures are deployed.
+
+Needed for email validation, installation database check, login, comment
+submissions, etc.
+
+## 2.21
+## 2.22
+## 2.23
+## 2.24
+## 2.25
+## 2.26
+## 2.27
+## 2.28
+## 2.29
+## 2.30
+## 2.31
+## 2.32
+## 2.33
+
+## Other
+- `Users::find` is vulnerable to SQL injection.
+- The default admin password is generated using a Mersenne Twister, which is
+ not cryptographically secure.
+- Verification of hash equality in login is not done in constant time.