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

Restricting token_auth access #8816

Closed
Joey3000 opened this issue Sep 18, 2015 · 3 comments
Closed

Restricting token_auth access #8816

Joey3000 opened this issue Sep 18, 2015 · 3 comments
Labels
answered For when a question was asked and we referred to forum or answered it. duplicate For issues that already existed in our issue tracker and were reported previously.

Comments

@Joey3000
Copy link
Contributor

Issue

Background is here: http://forum.piwik.org/read.php?15,129194,129409

With access to a Super User token_auth, attacker can do everything.

With access to a token_auth of a "view" user, attacker can view all reports.

I assume that the reason currently, for giving token_auth access to anything beyond viewing the dashboard/widgets instead of using only regular session management for that is, e.g., bulk tracking, which requires token_auth of an administrator/super-user.

The currently unlimited access with a token_auth has a security impact, as token_auth can be compromised even with HTTPS. E.g., HTTPS, generally, has many known attack scenarios. (Requiring continuous vigilance on server side of the latest known issues, both cryptographic (e.g. TLS version used and cypher suite choices) and bugs in the library used. And implementation of the latest and greatest HTTPS extensions (e.g. HSTS and HPKP). And similar on the client side.)

The issue is made worse by the fact that token_auth, unlike a password, is continuously exchanged between the browser and the server. Neither does it expire like a session.

Solutions Discussion

There could be following solutions:

A) A "bolt-on" solution, not ideal: If the token_auth mechanism is absolutely necessary to the extent it is currently used, following could be done to limit the damage in case of a token_auth compromise:

  • Require user password confirmation on:
    • Any change of own settings by any user. (I.e. any change that could be done after a user clicks on their name in the top menu.)
    • Any administration change by an administrator or super-user. (I.e. any change that could be done under Administration in the top menu.)

That could be done, e.g., via a JS overlay to enter the password. But, for CSRF protection, it should clearly state what the password is being required for.

Requiring password confirmation on significant changes seems to be widely used (in case the user is temporarily away from the PC, to prevent changes by others, and against session hijacks). And it seems to be crucial (and that on far less important changes) with the use of such an unlimited access token as token_auth, which allows for a complete bypass of application session management.

B) Ideally, an authentication token should not be allowed unlimited access.
Example: Tokens for external tools (e.g. Git) on Github. That token, once generated, is a secret that is never sent to the client (including browser). And is not needed for website functionality, which is covered by regular session management. If a token gets lost, a new one can be generated, including a choice what can be done with it.

In Piwik, such a token could be generated (with a random value) if, e.g., bulk tracking is used. With the token limited to that. Or if widget inclusion into other websites is needed - again with access limited to that only and a specific site. So, there could be an unlimited number of token_auth, all generated for a specific purpose when needed, like on Github. One can even imagine different token_auth with exact same access, just to share them with different recipients, and later be able to revoke the access of one recipient without affecting others.

Note: On inclusion of Piwik widgets/dashboard into other websites, different tokens could be used for different access levels. I.e. it could be defined which widgets on which site can be viewed with a specific token. (Kind of like in #5703, but possibly without a need for a different token name - it could still be the token_auth.) In which case the "anonymous" user would not need to be activated. The "anonymous" user would be there only for an unauthenticated dashboard view access without a token, if needed - like on https://demo.piwik.org.

Additional Resources

#4171
#6348
#7202
#1568
#5728 (comment)
#5703
#1419

Disclaimer: I'm not a professional in any field this issue report touches, including web development. So, feel free to take it apart. Also, this could be an old and worn-out topic. I'm sorry if it is.

@mattab
Copy link
Member

mattab commented Sep 20, 2015

I assume that the reason currently, for giving token_auth access to anything beyond viewing the dashboard/widgets instead of using only regular session management for that is, e.g., bulk tracking, which requires token_auth of an administrator/super-user.

token_auth is used a lot because much of the UI of Piwik uses the API which in turns uses token_auth as auth mechanism. Having oAuth2 support would be nice alternative but it will take a while before we could implement

The issue is made worse by the fact that token_auth, unlike a password, is continuously exchanged between the browser and the server. Neither does it expire like a session.

if HTTPS is used, the token is safe.

if HTTP is used, we should never set it as GET parameter, which is covered in #7349

Requiring password confirmation on significant changes seems to be widely used (in case the user is temporarily away from the PC, to prevent changes by others, and against session hijacks). And it seems to be crucial (and that on far less important changes) with the use of such an unlimited access token as token_auth, which allows for a complete bypass of application session management.

Due to the fact that API will still allow full access with a token_auth, in case token_auth is intercepted , requiring password confirmation will not help improve security. Though this would be a good protection against session hihacking in itself, so feel free to suggest this in a new issue. note that against session hijacking should implement #7349 as it's most obvious attack vector

Note: On inclusion of Piwik widgets/dashboard into other websites, different tokens could be used for different access levels. I.e. it could be defined which widgets on which site can be viewed with a specific token. (Kind of like in #5703)

indeed, I think this issue duplicates #5703 and also maybe "oAuth2 support in Piwik" #906

Closing as duplicate, feel free to continue the discussion here or in the other issues

@mattab mattab closed this as completed Sep 20, 2015
@mattab mattab added duplicate For issues that already existed in our issue tracker and were reported previously. answered For when a question was asked and we referred to forum or answered it. labels Sep 20, 2015
@Joey3000
Copy link
Contributor Author

Thanks for looking into this, Matt!

if HTTP is used, we should never set it as GET parameter, which is covered in #7349

That would be great and would prevent token_auth hanging around log files of some proxy servers in the connection. But wouldn't help against attackers (e.g. on an open WiFi) logging the entire communication - including POST parameters, headers and content. But never mind - it's much less risky with HTTPS.

Due to the fact that API will still allow full access with a token_auth, in case token_auth is intercepted , requiring password confirmation will not help improve security.

Could you give some more details on this with respect to token_auth of non-admin users? Just hypothetically (not related to this issue report - I'm working on a separate plugin reusing the UsersManager), to make sure that I'm not running into wrong direction. As an example:

  • The UsersManager provides an additional input field for current (i.e. old, before change) password on user's "Personal Settings" page.
  • Then, on a request to change user's own settings on a POST to /index.php?date=last30&module=UsersManager&format=json&action=recordUserSettings&idSite=1&period=range it checks, inside its recordUserSettings() function, the current password value. (I.e. hashing the provided value and comparing it to password hash of currently logged in user, if there is any.) And does nothing if current password was not provided or is not correct.

Can that be circumvented with a token_auth? Again, I'm referring to token_auth of non-admin users in this question. (I.e. protecting at least non-admin users on open networks with a separate plugin.) You probably were referring to token_auth of a super-user, right? (With that one, I guess, it would be possible to just disable any bothersome plugin, before modifying any user account.)

Thanks in advance!

@Joey3000
Copy link
Contributor Author

not related to this issue report - I'm working on a separate plugin reusing the UsersManager

Just for info: The offending plugin is described here: #8781 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
answered For when a question was asked and we referred to forum or answered it. duplicate For issues that already existed in our issue tracker and were reported previously.
Projects
None yet
Development

No branches or pull requests

2 participants