Page MenuHomePhabricator

(partially) expose oauth_registered_consumer table
Open, MediumPublic

Description

In T244473 I wanted to look at how big a task this was - i.e. how many existing consumers would need to be changed. I realised that we expose some information about the OAuth consumers on index.php special pages, but not via api.php and not via the database replicas.
I therefore propose we partially expose oauth_registered_consumer:

  • oarc_id
  • oarc_consumer_key - I think this is an identifier of the consumer e.g. part of the URL in https://meta.wikimedia.org/w/index.php?title=Special:OAuthListConsumers/view/fa88fc9efa0e08429863160d038f70a9 ?
  • oarc_name
  • oarc_user_id
  • oarc_version
  • oarc_callback_url
  • oarc_callback_is_prefix
  • oarc_description
  • oarc_owner_only - don't know if this is already exposed?
  • oarc_wiki - don't know if this is already exposed?
  • oarc_grants - don't know if this is already exposed?
  • oarc_registration
  • oarc_stage
  • oarc_stage_timestamp
  • oarc_deleted
  • oarc_oauth_version
  • oarc_oauth2_allowed_grants - don't know if this is already exposed?
  • oarc_oauth2_is_confidential - commented as OAuth2 flag indicating if consumer can be trusted with keeping secrets in schema/OAuth.sql - don't know if this is already exposed?

but not:

  • oarc_email
  • oarc_email_authenticated - tied to the above, possibly fine to do but probably not useful
  • oarc_developer_agreement - don't remember what this is
  • oarc_secret_key
  • oarc_rsa_key
  • oarc_restrictions - I think this contains IP addresses, and with owner-only consumers and things... if this isn't already exposed we probably should think twice before exposing it. would not be helpful for my use case anyway.

And all of this only on the basis that oarc_deleted=0.

Note it's possible some of this isn't already exposed somewhere. I have not dived deep into the OAuth extension codebase.

I made a patch for this but have been told they will require the WMF security team to sign off.

Event Timeline

Change 579800 had a related patch set uploaded (by Alex Monk; owner: Alex Monk):
[operations/puppet@production] Add public replica view for oauth_registered_consumer

https://gerrit.wikimedia.org/r/579800

bd808 edited projects, added Security-Team; removed Security.

No views were ever made for oauth_registered_consumer. In T172693: metawiki tables in labs: oauth_accepted_consumer oauth_registered_consumer it was noticed that the tables were being replicated without views and we decided to just remove the replication. That task happened at a time where maintaining the views was a bit of a dark art. We have come a long way since then. :)

Comparing the public output on https://meta.wikimedia.org/wiki/Special:OAuthListConsumers and it's drill down pages to the list of columns that @Krenair is suggesting I think he picked most of the right things:

  • oarc_id - Not exposed, but not scary to expose. Just an autoincrement numeric value.
  • oarc_consumer_key - This is public in the URL (for example https://meta.wikimedia.org/w/index.php?title=Special:OAuthListConsumers/view/aea31746a1e5d5b3e7514952f70e7035)
  • oarc_name - "Application name"
  • oarc_user_id - "Publisher". Special page shows the user_name rather than the user_id (for example "BDavis (WMF)")
  • oarc_version - "Consumer version"
  • oarc_callback_url - 'OAuth "callback URL"'
  • oarc_callback_is_prefix - 'Allow consumer to specify a callback in requests and use "callback" URL above as a required prefix.'
  • oarc_description - "Description"
  • oarc_email - Private. user_email associated with oarc_user_id at the time of proposal
  • oarc_email_authenticated - Private. user_email_authenticated associated with oarc_user_id at the time of proposal
  • oarc_developer_agreement - Not shown, but implied as this is a required 1 for the proposal to even be in the queue for review.
  • oarc_owner_only - Shown in associated log messages (for example https://meta.wikimedia.org/wiki/Special:OAuthListConsumers/view/3f3a99d8c3f8da1c7bf997f808f88daa says 'BDavis (WMF) created an owner-only OAuth consumer (consumer key 3f3a99d8c3f8da1c7bf997f808f88daa) (Self access for api testing)')
  • oarc_wiki - "Applicable project" (note a * in this column means "All projects on this site")
  • oarc_grants - "Applicable grants"
  • oarc_registration - Exposed as timestamp of "proposed" log message
  • oarc_secret_key - Private. This is functionally the password for using this consumer.
  • oarc_rsa_key - Technically not private, but not displayed on any current screens. This is an RSA public key used for verifying request signatures originating from the consumer. It is almost always empty because few consumers implement signed requests.
  • oarc_restrictions - Private. This is an optional list of allowed IPv{4,6} addresses or CIDR ranges that the consumer requests are expected to originate from.
  • oarc_stage - "Status"
  • oarc_stage_timestamp - Exposed as timestamp of some log message (proposed, approved, denied)
  • oarc_deleted - Suppression flag. Must equal 0 in all rows we expose
  • oarc_oauth_version - "OAuth protocol version"
  • oarc_oauth2_allowed_grants - Not displayed, but possibly only because the OAuth2 integration did not update Special:OAuthListConsumers at all. Value will be NULL if oarc_oauth_version==1, some subset of ["authorization_code","refresh_token","client_credentials"] if oarc_oauth_version==2.
  • oarc_oauth2_is_confidential - Not displayed, but possibly only because the OAuth2 integration did not update Special:OAuthListConsumers at all. Value will be 1 if oarc_oauth_version==1 (column default), and either 0 or 1 if oarc_oauth_version==2.

The MWOAuthConsumer::getFieldPermissionChecks function handily provides a key to what is expected to private/public by the PHP code. MWOAuthDAO::userCanAccess is used to check contextual access against that list. Any column not listed is allowed for all contexts. Any field listed as a key has a method name in MWOAuthConsumer as its value and that function determines what is allowed to be displayed in the given context. "userCanSee" columns are public unless oarc_deleted=1 or the user has the 'mwoauthviewsuppressed' right. "userCanSeePrivate" columns are only shown to users with the 'mwoauthviewprivate' right + "userCanSee" logic. "userCanSeeEmail" columns are only shown to users with the 'mwoauthmanageconsumer' right + "userCanSee" logic.


Having done all this, I will wait for someone from Security-Team to check my work and sign off on exposing these columns.

  • oarc_id - Not exposed, but not scary to expose. Just an autoincrement numeric value.

oarc_id is exposed in change tag names, and will be exposed elsewhere soon (T224749: OAuth consumer id should be exposed).

  • oarc_user_id - "Publisher". Special page shows the user_name rather than the user_id (for example "BDavis (WMF)")

I guess if we are paranoid we could check if the user has been suppressed.

  • oarc_developer_agreement - Not shown, but implied as this is a required 1 for the proposal to even be in the queue for review.

Maybe 0 for very old consumers, before that developer agreement checkbox was introduced? Anyway, this is harmless to expose, but worthless, too.

  • oarc_rsa_key - Technically not private, but not displayed on any current screens. This is an RSA public key used for verifying request signatures originating from the consumer. It is almost always empty because few consumers implement signed requests.

I'd say there's an expectation of privacy for this, even though the security of the OAuth protocol would not be compromised by it becoming public.

  • oarc_oauth2_allowed_grants - Not displayed, but possibly only because the OAuth2 integration did not update Special:OAuthListConsumers at all. Value will be NULL if oarc_oauth_version==1, some subset of ["authorization_code","refresh_token","client_credentials"] if oarc_oauth_version==2.

Yeah, this should probably be displayed. It just tells which type of authentication flow the app uses.

  • oarc_oauth2_is_confidential - Not displayed, but possibly only because the OAuth2 integration did not update Special:OAuthListConsumers at all. Value will be 1 if oarc_oauth_version==1 (column default), and either 0 or 1 if oarc_oauth_version==2.

Yeah, probably should also be displayed. This basically says "the client is able to keep the consumer secret secret" (ie. this will be false for mobile apps and client-side web apps, and true for server-side web apps).

"userCanSeePrivate" columns are only shown to users with the 'mwoauthviewprivate' right + "userCanSee" logic.

Which is no one, in the Wikimedia setup. The permission check is circumvented for the owner in the appropriate places. (This is only used for restrictions.)

Reedy triaged this task as Medium priority.Mar 18 2020, 4:15 PM
Reedy moved this task from Incoming to Back Orders on the Security-Team board.
  • oarc_oauth2_is_confidential - Not displayed, but possibly only because the OAuth2 integration did not update Special:OAuthListConsumers at all. Value will be 1 if oarc_oauth_version==1 (column default), and either 0 or 1 if oarc_oauth_version==2.

Yeah, probably should also be displayed. This basically says "the client is able to keep the consumer secret secret" (ie. this will be false for mobile apps and client-side web apps, and true for server-side web apps).

Now displayed (T323866), btw.