Role Enforcement in the _users Database
Yes, the default behavior of CouchDB prevents an authenticated non-admin user from adding the _admin role (or any other role) to their own user document or others. In a standard configuration, users are only permitted to update their own password and specific profile fields; they do not have the permission to modify the roles array within the _users database.
Likely Explanation of Constraints
CouchDB separates authentication (verifying who a user is) from authorization (what a user can do). While a user is authenticated to access their own document in the _users database, the system-level security prevents non-privileged users from escalating their own permissions. The _admin role is a global privilege; allowing a user to self-assign this role would create a critical security vulnerability.
Implementing a Custom Validation Function
If you are using a custom authentication proxy or a specific configuration where you suspect role leakage, you can implement a validate_doc_update function within a design document in the _users database. This provides a secondary layer of server-side enforcement.
Warning: Incorrectly configuring the validation function in the _users database can lock all users, including administrators, out of the system. Always test this in a staging environment first.
To strictly restrict role assignments to server administrators, use a validation function similar to this logic:
function(newDoc, oldDoc, user, couchdbThis) {
// Check if the roles field is being modified
if (newDoc.roles && (!oldDoc || JSON.stringify(newDoc.roles) !== JSON.stringify(oldDoc.roles))) {
// Only allow the update if the current requester is an admin
// Note: The 'user' object contains the current requester's credentials
if (!user || !user.roles || user.roles.indexOf('_admin') === -1) {
throw new Error("Only administrators can modify user roles.");
}
}
}
Verification Steps
- Test Escalation: Attempt to
PUT a document to /_users/username containing "roles": ["_admin"] using the credentials of a non-admin user. The request should return a 401 Unauthorized or 403 Forbidden.
- Verify Admin Access: Use a known admin account to update a user's roles and verify the change via a
GET request.
- Config Check: Attempt to access the
/_config endpoint with the non-admin user to ensure the _admin role was not successfully granted.
To provide a more tailored recommendation, please specify which version of CouchDB you are utilizing (e.g., 3.x), as security defaults for system databases have evolved between major versions.