@Joey3000 opened this Issue on January 2nd 2016 Contributor

Authentication tokens have a similar level of confidentiality to passwords. Actually, currently, due to the coupling of the token_auth to passwords and their equal power in Piwik, its token_auth have exactly the same level of confidentiality as passwords. Yet they are stored in plain text.

The token_auth should be stored with the same rigorous hashing and salting as passwords. For the same reasons.

Notes:

@Joey3000 commented on January 3rd 2016 Contributor

An alternative option, without a need for an API change, could be using of a part of the transmitted token_auth as a "token ID", stored in plain text in a separate DB table column and used for the table look-up:

[received token_auth] = ["token ID"] + [token_auth content]
         |                   |                  |
      received             stored            stored
      from user              in              hashed
                          plaintext

The verification procedure would be:

  • First use the received "token ID" to look up the corresponding hashed token_auth content
  • Then use password_verify() to securely compare the received token_auth content to the one looked up
  • Then use the corresponding user name ("login") if verification successful
@Joey3000 commented on January 3rd 2016 Contributor

Implementation of token_auth hashing would require following additional actions:

  • On the part of the user: Update of the transmitted token_auth after Piwik has been updated for this. (See next point.)
  • On the part of Piwik:

    • When displaying the token_auth (in the UsersManager plugin, etc.), show it including the "token ID" in the same string. (Reusing a part of the previously sent token_auth will not be possible, due to probable clashes in the ID part. Which needs to be unique among all tokens.)
    • For performance reasons[1]: Instead of the requirement to check token_auth (see https://developer.piwik.org/guides/security-in-piwik#check-for-the-token_auth), the check would need to be for a different, a temporary plain text token.
      [1] Because password/token hashing with bcrypt used internally by the PHP's password_*() functions takes time and resources, which is on purpose - to make bruteforcing of leaked hashes slower; as opposed to MD/SHA hash functions, which are used for different purposes and need to be fast.

    Namely: The token_auth would be used for authentication on initial request only (before an active session exists), and the temporary plain text token used afterwards. (Handling of the temporary token in plain text is not a problem due to its limited validity period, similarly to a PHP session ID. Unlike token_auth, which has a long validity period and in that is similar to a password.) Or should that temporary token be the PHP session ID itself - to automate its expiration, etc.?

    • Because token_auth is no longer stored in plain text:
    • If the performance impact is acceptable, and as long as token_auth has not been de-coupled from the user password (see https://github.com/piwik/piwik/issues/5703), the displayed (in the UsersManager, etc.) token_auth would need to be re-calculated from user password on each display.
    • Otherwise: As is currently the case with, e.g., Github tokens (and Github warns one about that on token creation), a token_auth can be shown to the user only once, and never again - namely at the time of its creation. Because it cannot be retrieved from its hash. If a token_auth gets lost/forgotten, then a new one needs to be created. (Well, currently it would be re-created from the user password (in which case it will be equal to the old one). But once token_auth has been de-coupled from the password, it will be a completely new one.)

I'm not an expert in any way, so I may have mixed things up.

@tsteur commented on January 8th 2020 Member

Closing this as a duplicate of https://github.com/matomo-org/matomo/issues/6559

This Issue was closed on January 8th 2020
Powered by GitHub Issue Mirror