[Twitter Bug Bounty] Misconfigured JSON endpoint on ads.twitter.com lead to Access control issue and Information Disclosure of role privileged users.

Twitter Ads Program enables a user/original Account administrator to grant role privileges and permissions to manage their Twitter Ads account at https://ads.twitter.com/account_management/18xxxxx/account_users

The role privileges/permissions are of types :

Account administrator : Full access to modify campaigns and view data, including ability to add/remove users and change settings.
Ad manager : Full access to modify campaigns and view data, but cannot add/remove users or change settings.
Campaign analyst : Access to view paid campaign data and pull reports, but no access to modify or create campaigns.
Organic analyst : Access to view organic analytics and audience insights, but no access to modify or view campaigns.

By default access to “App Manager” is under https://ads.twitter.com/accounts/18xxxxx/tools/manage_apps.

The above access to App Manager which discloses “Managed App name”, “Conversion Tracking” and “Deep Link scheme” data was originally restricted from access to “Organic Analyst” and “Campaign Analyst” because it didn’t came under the granted permissions and privileges of either of them

It returned a HTTP/1.1 404 STATUS CODE ‘NOT FOUND’ while accessing the link of type https://ads.twitter.com/accounts/18xxxxx/tools/manage_apps. for the given role permissions of Organic/Campaign Analyst

However a Campaign Analyst was able to access link directly of the type https://ads.twitter.com/accounts/18xxxx/campaigns/new/app_promotion which shouldn’t be accessible in the first place but we were still not able to create a campaign following through it.

But while accessing https://ads.twitter.com/accounts/18xxxx/campaigns/new/app_promotion I noticed that it would list down all the ‘Managed Apps’ and other associated data by requesting to a JSON endpoint via a HTTP GET request of the type https://ads.twitter.com/accounts/18xxxx/apps.json?account=18xxxxx&lang=en. The request was of the type.

GET /accounts/18xxxxx/apps.json?action=delete&account=18xxxx&lang=en HTTP/1.1
Host: ads.twitter.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:59.0) Gecko/20100101 Firefox/59.0
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: https://ads.twitter.com/accounts/18ce54fw885/campaigns/new/app_promotion
X-Requested-With: XMLHttpRequest
RT=xxxxx
DNT: 1
Connection: close
Cookie : xxxxxxxxx
(Removed other HTTP GET REQUEST data for clarification)

The HTTP Response was of the type

HTTP/1.1 200 OK
connection: close
content-disposition: attachment; filename=json.json
Content-Length: 8410
content-type: application/json;charset=utf-8
date: Tue, 03 Apr 2018 18:43:29 GMT
server: tsa_k
strict-transport-security: max-age=631138519
x-connection-hash: 89a2d72f5617af17b470b14e13857851
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
x-response-time: 212
x-transaction: 0032a30100b23d6b
x-xss-protection: 1; mode=block; report=https://twitter.com/i/xss_report

{"groups":[],"apps_info":{"xxxxxx":{"app_store_identifier":"com.twitter.android","description":"xxxxxx{"app_store_identifier":"com.instagram.android","description"xxxx"\u003Cdiv jsname=\"C4s9Ed\"\u003xxxxxxxxx{"app_store_identifier":"com.tumblr","description":xxxxxx"\u003Cdiv jsname=\"C4s9Ed\"\u003ETxxxxx

It listed down all the managed apps and other associated data by requesting to that endpoint. For example in the above scenario it listed down Twitter, Instagram and Tumblr under applications.

I got awarded a bounty by Twitter Security for filing this bug report on April 13th, 2018.