-
Improvement
-
Resolution: Fixed
-
Minor
-
3.8, 3.10
-
MOODLE_310_STABLE, MOODLE_38_STABLE
-
MOODLE_311_STABLE
-
MDL-65818-master -
(This is something I have implemented locally and am offering for the community in case people want it.)
We had a requirement to store a certain password (in a plugin admin setting) more securely than Moodle normally allows. Normally, passwords are stored in the mdl_config or mdl_config_plugins tables using the admin_setting_configpasswordunmask control. This has two disadvantages:
- Any system administrator (or anyone with moodle/site:config) can access the password value from the user interface.
- Anyone with direct access to the database can access the password using a database query.
In the OU setup there are quite a few people who are server administrators, and also quite a few people (developers) who have direct access to the database for troubleshooting purposes. Worse, we then have many more people with moodle/site:config, because of stupid. Anyway, all these people are trusted staff, so for most purposes, the Moodle system, while not great, is adequate.
However the new password we are storing in our custom plugin allows quite a high level of access to student personal data that is not stored in Moodle. A few of the people I listed above do have access to this data already, but most don't - our security office required that we make sure this password is kept secret.
The change I implemented, and which I propose for standard Moodle, is a new admin setting with the following behaviour:
- In the user interface, allow admins to change the password, but not to view it.
- Store the password encrypted in the database.
- Store the encryption key in the file system - in moodledata or, optionally, in a separate configurable location.
- The encryption key can be created automatically by the server, or (e.g. if you want to use a non-shared folder in a multi-server cluster) created manually by using a CLI script and then copied to the other servers.
This means we can configure it so that:
- Our staff who can (some of them) access the Moodle admin UI, and the database, and the normal moodledata filesystem, have no way of getting the key.
- An attacker needs to steal both the database, and the protected filesystem area, to get the key. Or they have to gain command line access to the server as root or as the apache user.
Obviously the webserver does need to be able to decrypt the password so that it can use it when connecting to the remote system that requires it, so we can't make it any more secure than that.
The cryptography uses the openssl extension which is already required.
New configuration variables:
- $CFG->secretdataroot (optional, if not set defaults to $CFG->dataroot . '/secret') - keys are stored inside a 'keypair' folder inside this folder.
- $CFG->nokeypairgeneration (optional, default false) - the server will normally generate a keypair automatically the first time you encrypt something, but you can set this off if you want to prevent it, if you are planning to generate the keypair manually with the CLI script.
Issues with this code:
- I used public/private keys. This is not really necessary (it does not increase security because the same server holds and uses both keys) and is a bit of a hangover from a less-good way I was going to implement it previously. However, it does provide more flexibility, for example if we decided to make the public key public and allow external clients to set the password, pre-encrypted, using a web service or possibly even by email or something crazy.
- I wasn't previously aware of
MDL-36580, which Eloy told me about; that feature relates to encrypting data in the backup file. It is kind of similar but uses symmetric encryption and stores the key in the database. There is a question as to whether a consistent approach should be used!
- has a non-specific relationship to
-
MDL-67390 Update password hashing to SHA-512
- Closed
-
MDL-70363 Make sodium at least a recommended extension in 3.11
- Closed
- has been marked as being related by
-
MDL-69801 Introduce a new generic private / public certificate + password / token manager api / Vault API
- Open
- will be (partly) resolved by
-
MDL-66445 All admin_setting_configpassword should not show forced config items
- Closed