Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Put User doesn't always overwrite custom metadata #70295

Open
tvernum opened this issue Mar 11, 2021 · 1 comment
Open

Put User doesn't always overwrite custom metadata #70295

tvernum opened this issue Mar 11, 2021 · 1 comment
Labels
>bug :Security/Authentication Logging in, Usernames/passwords, Realms (Native/LDAP/AD/SAML/PKI/etc) Team:Security Meta label for security team

Comments

@tvernum
Copy link
Contributor

tvernum commented Mar 11, 2021

https://discuss.elastic.co/t/how-to-remove-custom-metadata-fields-from-users-and-roles/266646/2

By design, a PUT on a user does not overwrite their password unless the password (or hash) is in the request body.
That means, that within the NativeUsersStore, the Put will actually perform an update on the underlying document.

Because metadata is stored as a nested object, the semantics of that update means that metadata fields are not always removed from the document, even though they are supposed to be (and are for other object types like roles).

To be extra confusing putting a user with metadata: {} will preserve all existing metadata, but not specifying metadata at all will remove all metadata (and metadata: null is not allowed by the rest parser).

We will need to think carefully about how to fix this without breaking existing workflows that rely on the bug.

Examples below:

GET /.security/_doc/user-test {}
=== 
{
  "_index": ".security-7",
  "_type": "_doc",
  "_id": "user-test",
  "found": false
}
=== 

PUT /_security/user/test {}
{"roles":[],"password":"this is a password","metadata":{"test 1":1}}
=== 
{  "created": true  }
=== 

GET /.security/_doc/user-test {}
=== 
{
  "_index": ".security-7",
  "_type": "_doc",
  "_id": "user-test",
  "_version": 8,
  "_seq_no": 23,
  "_primary_term": 2,
  "found": true,
  "_source": {
    "username": "test",
    "password": "$2a$10$wDDS11yWheRfK2ypdYnlkOvX5Mbh/h38i9Ig9hE.1QHpUY0RlFeLq",
    "roles": [],
    "full_name": null,
    "email": null,
    "metadata": {  "test 1": 1  },
    "enabled": true,
    "type": "user"
  }
}
=== 

GET /_security/user/test {}
=== 
{
  "test": {
    "username": "test",
    "roles": [],
    "full_name": null,
    "email": null,
    "metadata": { "test 1": 1  },
    "enabled": true
  }
}
=== 

PUT /_security/user/test {}
{"roles":[],"metadata":{"test 2":2}}
=== 
{  "created": false }
=== 

GET /.security/_doc/user-test {}
=== 
{
  "_index": ".security-7",
  "_type": "_doc",
  "_id": "user-test",
  "_version": 9,
  "_seq_no": 24,
  "_primary_term": 2,
  "found": true,
  "_source": {
    "username": "test",
    "password": "$2a$10$wDDS11yWheRfK2ypdYnlkOvX5Mbh/h38i9Ig9hE.1QHpUY0RlFeLq",
    "roles": [],
    "full_name": null,
    "email": null,
    "metadata": {
      "test 1": 1,
      "test 2": 2
    },
    "enabled": true,
    "type": "user"
  }
}
=== 

GET /_security/user/test {}
=== 
{
  "test": {
    "username": "test",
    "roles": [],
    "full_name": null,
    "email": null,
    "metadata": {
      "test 2": 2,
      "test 1": 1
    },
    "enabled": true
  }
}
=== 

PUT /_security/user/test {}
{"roles":[],"metadata":{}}
=== 
{  "created": false }
=== 

GET /.security/_doc/user-test {}
=== 
{
  "_index": ".security-7",
  "_type": "_doc",
  "_id": "user-test",
  "_version": 9,
  "_seq_no": 24,
  "_primary_term": 2,
  "found": true,
  "_source": {
    "username": "test",
    "password": "$2a$10$wDDS11yWheRfK2ypdYnlkOvX5Mbh/h38i9Ig9hE.1QHpUY0RlFeLq",
    "roles": [],
    "full_name": null,
    "email": null,
    "metadata": {
      "test 1": 1,
      "test 2": 2
    },
    "enabled": true,
    "type": "user"
  }
}
=== 

GET /_security/user/test {}
=== 
{
  "test": {
    "username": "test",
    "roles": [],
    "full_name": null,
    "email": null,
    "metadata": {
      "test 2": 2,
      "test 1": 1
    },
    "enabled": true
  }
}
=== 

PUT /_security/user/test {}
{"roles":[]}
=== 
{  "created": false }
=== 

GET /.security/_doc/user-test {}
=== 
{
  "_index": ".security-7",
  "_type": "_doc",
  "_id": "user-test",
  "_version": 10,
  "_seq_no": 25,
  "_primary_term": 2,
  "found": true,
  "_source": {
    "username": "test",
    "password": "$2a$10$wDDS11yWheRfK2ypdYnlkOvX5Mbh/h38i9Ig9hE.1QHpUY0RlFeLq",
    "roles": [],
    "full_name": null,
    "email": null,
    "metadata": null,
    "enabled": true,
    "type": "user"
  }
}

=== 
GET /_security/user/test {}
=== 
{
  "test": {
    "username": "test",
    "roles": [],
    "full_name": null,
    "email": null,
    "metadata": {},
    "enabled": true
  }
}
@tvernum tvernum added >bug :Security/Authentication Logging in, Usernames/passwords, Realms (Native/LDAP/AD/SAML/PKI/etc) labels Mar 11, 2021
@elasticmachine elasticmachine added the Team:Security Meta label for security team label Mar 11, 2021
@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-security (Team:Security)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
>bug :Security/Authentication Logging in, Usernames/passwords, Realms (Native/LDAP/AD/SAML/PKI/etc) Team:Security Meta label for security team
Projects
None yet
Development

No branches or pull requests

2 participants