# Unauthorized Tweeting on behalf of Account Owners

Ad Manager with promoted-tweet-only rights could post real tweets to the account owner's timeline by dropping the nullcast_flag=1 parameter from the create_tweet request.

- Payout: $420
- Severity: medium
- Program: X / xAI
- Credited: anshuman_bh
- Disclosed: 2015-05-07
- Write-up quality: 6/10
- Original: https://hackerone.com/reports/31082
- Library page: https://bugbountylibrary.com/r/h1%3A31082
- Tags: domain:web impact:integrity kind:bounty platform:hackerone sev:medium technique:param-pollution vuln:access-control vuln:business-logic

**Target:** ads.twitter.com tweet_box/create_tweet endpoint
**Root cause:** Server trusted the client-supplied nullcast_flag parameter to decide whether a tweet was promoted-only vs. a real timeline tweet, without re-checking the user's role permissions for non-promoted tweets.
**Steps:**
1. Owner adds user as Ad Manager with 'create promoted-only tweets' checkbox enabled
2. As that user, switch to owner's ads dashboard and compose a promoted tweet
3. Intercept `POST /accounts/<id>/tweet_box/create_tweet?format=json` with body `account=<id>&form_location=objective_creative_composer&nullcast_flag=1&tweet_text=test`
4. Remove `nullcast_flag=1` and resend
5. Tweet appears on owner's public timeline
**How found:** Researcher noticed the promoted-tweet composer sent a nullcast_flag=1 parameter and hypothesized it was the only thing distinguishing promoted from real tweets; removed it in Burp Repeater to test.
**Exploitation:** A low-privileged Ad Manager removes the nullcast_flag parameter from the create_tweet request, causing the backend to publish a normal tweet on the account owner's timeline, impersonating them.
**Insight:** When a UI restricts an action, look for a client-controlled flag (nullcast_flag, draft, preview, internal) in the request that the server uses to gate the action; strip or flip it to test whether authorization is enforced server-side.
