Page MenuHomePhabricator

Privacy issue: ResourceLoader lets you request other user's preferences
Closed, ResolvedPublic

Description

With load.php?modules=user.options&user=OtherUser you can easily retrieve someone else's preferences including the watchlist token.

Needs a check against $wgUser I think.


Version: 1.17.x
Severity: major

Details

Reference
bz25281

Event Timeline

bzimport raised the priority of this task from to Medium.Nov 21 2014, 11:15 PM
bzimport set Reference to bz25281.

Well, the point is actually to make this resource cachable at the squid level.

I'm not doubting that it could be, but perhaps someone could help me to understand how is this type of information being available a problem.

(In reply to comment #1)

I'm not doubting that it could be, but perhaps someone could help me to
understand how is this type of information being available a problem.

I don't know the extent to which user preferences are available, but I would say that the most (and probably only) problematic user preference is user e-mail address. In addition to privacy and expectation of privacy concerns, something like this could theoretically be used for e-mail address harvesting or revealing that multiple accounts belong to the same individual.

The personal settings of a user are usually considered to be private. I don't know if it's worth arguing about whether it's a problem or not that e.g. your personal watchlist is made publicly available.

I'd guess there's a reason that the API blocks these kind of requests, rsp. requires a special token from the user.

User preferences are not intended to be public. The most obvious problem is the watchlist token.

(In reply to comment #2)

(In reply to comment #1)

I'm not doubting that it could be, but perhaps someone could help me to
understand how is this type of information being available a problem.

I don't know the extent to which user preferences are available, but I would
say that the most (and probably only) problematic user preference is user
e-mail address. In addition to privacy and expectation of privacy concerns,
something like this could theoretically be used for e-mail address harvesting
or revealing that multiple accounts belong to the same individual.

This wouldn't be revealed.

The watchlist thing sounds important, and the general idea of exposing something that's been considered private before seem like great reasons to change course here.

Are there any objections to including the user.options module as an inline script? Logged in users would naturally get their own versions while anons would get the defaults. This would solve the issue without having to give up the functionality.

The other possibility is using a user-specific token in the URL, or using something else and not caching in squid.

Why are all user preferences outputted unconditionally?

Access to user preferences on the client has been a want of front-end developers for some time, and has been being done in part for a while by in-lining them. However, it is completely reasonable to make a white/black list for these things, rather than just output them, as you say, unconditionally.

Assuming we never send the preferences of one user to another, the only advantage I can see to conditionally exporting user options to the client is a reduction of the size of the data being added to the page - which I am a fan of.

I think user preferences should not be loaded through the resource loader at all, but just inlined like mediaWiki.config.set() is. I'll poke at this.

I spoke with Tim about this approach last night. It seems to add about 1-2k of data to the page, but it uses fewer requests. He recommended we make it configurable so that it will either embed in the page or be available as a request (but will check against $wgUser) so that we can do some performance analysis between them and also so 3rd party users can choose different settings that make sense for us/them.

This has been solved in r73686, which supports both embedding the user options into the page using an inline script, or accessing them through ResourceLoader, in which case server caching is bypassed. In both cases the user parameter in the resource request is checked against $wgUser, and default user options are used in case of mismatch.